From c5046ca5b33d8f245fe805b92ce8c4e61c5ba065 Mon Sep 17 00:00:00 2001
From: Brian Burkhalter
Date: Tue, 1 Dec 2020 20:07:53 +0000
Subject: [PATCH 001/504] 8246739: InputStream.skipNBytes could be implemented
more efficiently
Reviewed-by: rriggs, lancea, naoto
---
.../share/classes/java/io/InputStream.java | 33 ++++++++++---------
1 file changed, 17 insertions(+), 16 deletions(-)
diff --git a/src/java.base/share/classes/java/io/InputStream.java b/src/java.base/share/classes/java/io/InputStream.java
index 9b5b0b09c5192..ec530ad0a853a 100644
--- a/src/java.base/share/classes/java/io/InputStream.java
+++ b/src/java.base/share/classes/java/io/InputStream.java
@@ -577,13 +577,15 @@ public long skip(long n) throws IOException {
* @implSpec
* If {@code n} is zero or negative, then no bytes are skipped.
* If {@code n} is positive, the default implementation of this method
- * invokes {@link #skip(long) skip()} with parameter {@code n}. If the
- * return value of {@code skip(n)} is non-negative and less than {@code n},
- * then {@link #read()} is invoked repeatedly until the stream is {@code n}
- * bytes beyond its position when this method was invoked or end of stream
- * is reached. If the return value of {@code skip(n)} is negative or
- * greater than {@code n}, then an {@code IOException} is thrown. Any
- * exception thrown by {@code skip()} or {@code read()} will be propagated.
+ * invokes {@link #skip(long) skip()} repeatedly with its parameter equal
+ * to the remaining number of bytes to skip until the requested number
+ * of bytes has been skipped or an error condition occurs. If at any
+ * point the return value of {@code skip()} is negative or greater than the
+ * remaining number of bytes to be skipped, then an {@code IOException} is
+ * thrown. If {@code skip()} ever returns zero, then {@link #read()} is
+ * invoked to read a single byte, and if it returns {@code -1}, then an
+ * {@code EOFException} is thrown. Any exception thrown by {@code skip()}
+ * or {@code read()} will be propagated.
*
* @param n the number of bytes to be skipped.
* @throws EOFException if end of stream is encountered before the
@@ -596,20 +598,19 @@ public long skip(long n) throws IOException {
* @since 12
*/
public void skipNBytes(long n) throws IOException {
- if (n > 0) {
+ while (n > 0) {
long ns = skip(n);
- if (ns >= 0 && ns < n) { // skipped too few bytes
+ if (ns > 0 && ns <= n) {
// adjust number to skip
n -= ns;
- // read until requested number skipped or EOS reached
- while (n > 0 && read() != -1) {
- n--;
- }
- // if not enough skipped, then EOFE
- if (n != 0) {
+ } else if (ns == 0) { // no bytes skipped
+ // read one byte to check for EOS
+ if (read() == -1) {
throw new EOFException();
}
- } else if (ns != n) { // skipped negative or too many bytes
+ // one byte read so decrement number to skip
+ n--;
+ } else { // skipped negative or too many bytes
throw new IOException("Unable to skip exactly");
}
}
From 29d90b952cfdfb05903fa6932a7930852aaaab5c Mon Sep 17 00:00:00 2001
From: Guoxiong Li
Date: Tue, 1 Dec 2020 21:06:06 +0000
Subject: [PATCH 002/504] 8255968: Confusing error message for inaccessible
constructor
Reviewed-by: mcimadamore
---
.../com/sun/tools/javac/comp/Resolve.java | 42 +++++++++++++++--
.../tools/javac/T8255968/T8255968_1.java | 37 +++++++++++++++
.../tools/javac/T8255968/T8255968_1.out | 2 +
.../tools/javac/T8255968/T8255968_10.java | 41 +++++++++++++++++
.../tools/javac/T8255968/T8255968_10.out | 2 +
.../tools/javac/T8255968/T8255968_11.java | 41 +++++++++++++++++
.../tools/javac/T8255968/T8255968_11.out | 2 +
.../tools/javac/T8255968/T8255968_12.java | 42 +++++++++++++++++
.../tools/javac/T8255968/T8255968_12.out | 2 +
.../tools/javac/T8255968/T8255968_13.java | 42 +++++++++++++++++
.../tools/javac/T8255968/T8255968_13.out | 2 +
.../tools/javac/T8255968/T8255968_14.java | 43 ++++++++++++++++++
.../tools/javac/T8255968/T8255968_14.out | 2 +
.../tools/javac/T8255968/T8255968_15.java | 43 ++++++++++++++++++
.../tools/javac/T8255968/T8255968_15.out | 2 +
.../tools/javac/T8255968/T8255968_16.java | 43 ++++++++++++++++++
.../tools/javac/T8255968/T8255968_16.out | 2 +
.../tools/javac/T8255968/T8255968_2.java | 37 +++++++++++++++
.../tools/javac/T8255968/T8255968_2.out | 2 +
.../tools/javac/T8255968/T8255968_3.java | 38 ++++++++++++++++
.../tools/javac/T8255968/T8255968_3.out | 2 +
.../tools/javac/T8255968/T8255968_4.java | 38 ++++++++++++++++
.../tools/javac/T8255968/T8255968_4.out | 2 +
.../tools/javac/T8255968/T8255968_5.java | 39 ++++++++++++++++
.../tools/javac/T8255968/T8255968_5.out | 2 +
.../tools/javac/T8255968/T8255968_6.java | 39 ++++++++++++++++
.../tools/javac/T8255968/T8255968_6.out | 2 +
.../tools/javac/T8255968/T8255968_7.java | 39 ++++++++++++++++
.../tools/javac/T8255968/T8255968_7.out | 2 +
.../tools/javac/T8255968/T8255968_8.java | 45 +++++++++++++++++++
.../tools/javac/T8255968/T8255968_9.java | 41 +++++++++++++++++
31 files changed, 715 insertions(+), 3 deletions(-)
create mode 100644 test/langtools/tools/javac/T8255968/T8255968_1.java
create mode 100644 test/langtools/tools/javac/T8255968/T8255968_1.out
create mode 100644 test/langtools/tools/javac/T8255968/T8255968_10.java
create mode 100644 test/langtools/tools/javac/T8255968/T8255968_10.out
create mode 100644 test/langtools/tools/javac/T8255968/T8255968_11.java
create mode 100644 test/langtools/tools/javac/T8255968/T8255968_11.out
create mode 100644 test/langtools/tools/javac/T8255968/T8255968_12.java
create mode 100644 test/langtools/tools/javac/T8255968/T8255968_12.out
create mode 100644 test/langtools/tools/javac/T8255968/T8255968_13.java
create mode 100644 test/langtools/tools/javac/T8255968/T8255968_13.out
create mode 100644 test/langtools/tools/javac/T8255968/T8255968_14.java
create mode 100644 test/langtools/tools/javac/T8255968/T8255968_14.out
create mode 100644 test/langtools/tools/javac/T8255968/T8255968_15.java
create mode 100644 test/langtools/tools/javac/T8255968/T8255968_15.out
create mode 100644 test/langtools/tools/javac/T8255968/T8255968_16.java
create mode 100644 test/langtools/tools/javac/T8255968/T8255968_16.out
create mode 100644 test/langtools/tools/javac/T8255968/T8255968_2.java
create mode 100644 test/langtools/tools/javac/T8255968/T8255968_2.out
create mode 100644 test/langtools/tools/javac/T8255968/T8255968_3.java
create mode 100644 test/langtools/tools/javac/T8255968/T8255968_3.out
create mode 100644 test/langtools/tools/javac/T8255968/T8255968_4.java
create mode 100644 test/langtools/tools/javac/T8255968/T8255968_4.out
create mode 100644 test/langtools/tools/javac/T8255968/T8255968_5.java
create mode 100644 test/langtools/tools/javac/T8255968/T8255968_5.out
create mode 100644 test/langtools/tools/javac/T8255968/T8255968_6.java
create mode 100644 test/langtools/tools/javac/T8255968/T8255968_6.out
create mode 100644 test/langtools/tools/javac/T8255968/T8255968_7.java
create mode 100644 test/langtools/tools/javac/T8255968/T8255968_7.out
create mode 100644 test/langtools/tools/javac/T8255968/T8255968_8.java
create mode 100644 test/langtools/tools/javac/T8255968/T8255968_9.java
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java
index 727d2989adf4b..abf883d71062c 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java
@@ -1583,9 +1583,23 @@ Symbol selectBest(Env env,
currentResolutionContext.addApplicableCandidate(sym, mt);
} catch (InapplicableMethodException ex) {
currentResolutionContext.addInapplicableCandidate(sym, ex.getDiagnostic());
+ // Currently, an InapplicableMethodException occurs.
+ // If bestSoFar.kind was ABSENT_MTH, return an InapplicableSymbolError(kind is WRONG_MTH).
+ // If bestSoFar.kind was HIDDEN(AccessError)/WRONG_MTH/WRONG_MTHS, return an InapplicableSymbolsError(kind is WRONG_MTHS).
+ // See JDK-8255968 for more information.
switch (bestSoFar.kind) {
case ABSENT_MTH:
return new InapplicableSymbolError(currentResolutionContext);
+ case HIDDEN:
+ if (bestSoFar instanceof AccessError) {
+ // Add the JCDiagnostic of previous AccessError to the currentResolutionContext
+ // and construct InapplicableSymbolsError.
+ // Intentionally fallthrough.
+ currentResolutionContext.addInapplicableCandidate(((AccessError) bestSoFar).sym,
+ ((AccessError) bestSoFar).getDiagnostic(JCDiagnostic.DiagnosticType.FRAGMENT, null, null, site, null, argtypes, typeargtypes));
+ } else {
+ return bestSoFar;
+ }
case WRONG_MTH:
bestSoFar = new InapplicableSymbolsError(currentResolutionContext);
default:
@@ -1593,9 +1607,31 @@ Symbol selectBest(Env env,
}
}
if (!isAccessible(env, site, sym)) {
- return (bestSoFar.kind == ABSENT_MTH)
- ? new AccessError(env, site, sym)
- : bestSoFar;
+ AccessError curAccessError = new AccessError(env, site, sym);
+ JCDiagnostic curDiagnostic = curAccessError.getDiagnostic(JCDiagnostic.DiagnosticType.FRAGMENT, null, null, site, null, argtypes, typeargtypes);
+ // Currently, an AccessError occurs.
+ // If bestSoFar.kind was ABSENT_MTH, return an AccessError(kind is HIDDEN).
+ // If bestSoFar.kind was HIDDEN(AccessError), WRONG_MTH, WRONG_MTHS, return an InapplicableSymbolsError(kind is WRONG_MTHS).
+ // See JDK-8255968 for more information.
+ if (bestSoFar.kind == ABSENT_MTH) {
+ bestSoFar = curAccessError;
+ } else if (bestSoFar.kind == WRONG_MTH) {
+ // Add the JCDiagnostic of current AccessError to the currentResolutionContext
+ // and construct InapplicableSymbolsError.
+ currentResolutionContext.addInapplicableCandidate(sym, curDiagnostic);
+ bestSoFar = new InapplicableSymbolsError(currentResolutionContext);
+ } else if (bestSoFar.kind == WRONG_MTHS) {
+ // Add the JCDiagnostic of current AccessError to the currentResolutionContext
+ currentResolutionContext.addInapplicableCandidate(sym, curDiagnostic);
+ } else if (bestSoFar.kind == HIDDEN && bestSoFar instanceof AccessError) {
+ // Add the JCDiagnostics of previous and current AccessError to the currentResolutionContext
+ // and construct InapplicableSymbolsError.
+ currentResolutionContext.addInapplicableCandidate(((AccessError) bestSoFar).sym,
+ ((AccessError) bestSoFar).getDiagnostic(JCDiagnostic.DiagnosticType.FRAGMENT, null, null, site, null, argtypes, typeargtypes));
+ currentResolutionContext.addInapplicableCandidate(sym, curDiagnostic);
+ bestSoFar = new InapplicableSymbolsError(currentResolutionContext);
+ }
+ return bestSoFar;
}
return (bestSoFar.kind.isResolutionError() && bestSoFar.kind != AMBIGUOUS)
? sym
diff --git a/test/langtools/tools/javac/T8255968/T8255968_1.java b/test/langtools/tools/javac/T8255968/T8255968_1.java
new file mode 100644
index 0000000000000..4c19225c35e25
--- /dev/null
+++ b/test/langtools/tools/javac/T8255968/T8255968_1.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 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
+ * @bug 8255968
+ * @summary Confusing error message for inaccessible constructor
+ * @run compile/fail/ref=T8255968_1.out -XDrawDiagnostics T8255968_1.java
+ */
+
+class T8255968_1 {
+ T8255968_1_Test c = new T8255968_1_Test(0);
+}
+
+class T8255968_1_Test {
+ private T8255968_1_Test(int x) {}
+}
diff --git a/test/langtools/tools/javac/T8255968/T8255968_1.out b/test/langtools/tools/javac/T8255968/T8255968_1.out
new file mode 100644
index 0000000000000..710b9f3562a68
--- /dev/null
+++ b/test/langtools/tools/javac/T8255968/T8255968_1.out
@@ -0,0 +1,2 @@
+T8255968_1.java:32:25: compiler.err.report.access: T8255968_1_Test(int), private, T8255968_1_Test
+1 error
diff --git a/test/langtools/tools/javac/T8255968/T8255968_10.java b/test/langtools/tools/javac/T8255968/T8255968_10.java
new file mode 100644
index 0000000000000..ea67b9a2bafc2
--- /dev/null
+++ b/test/langtools/tools/javac/T8255968/T8255968_10.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 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
+ * @bug 8255968
+ * @summary Confusing error message for inaccessible constructor
+ * @run compile/fail/ref=T8255968_10.out -XDrawDiagnostics T8255968_10.java
+ */
+
+class T8255968_10 {
+ T8255968_10_TestMethodReference c = T8255968_10_Test::new;
+}
+
+interface T8255968_10_TestMethodReference {
+ T8255968_10_Test create(int x);
+}
+
+class T8255968_10_Test {
+ private T8255968_10_Test(int x) {}
+}
diff --git a/test/langtools/tools/javac/T8255968/T8255968_10.out b/test/langtools/tools/javac/T8255968/T8255968_10.out
new file mode 100644
index 0000000000000..45485766e4426
--- /dev/null
+++ b/test/langtools/tools/javac/T8255968/T8255968_10.out
@@ -0,0 +1,2 @@
+T8255968_10.java:32:41: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.report.access: T8255968_10_Test(int), private, T8255968_10_Test))
+1 error
diff --git a/test/langtools/tools/javac/T8255968/T8255968_11.java b/test/langtools/tools/javac/T8255968/T8255968_11.java
new file mode 100644
index 0000000000000..bec6e6e7a7f84
--- /dev/null
+++ b/test/langtools/tools/javac/T8255968/T8255968_11.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 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
+ * @bug 8255968
+ * @summary Confusing error message for inaccessible constructor
+ * @run compile/fail/ref=T8255968_11.out -XDrawDiagnostics T8255968_11.java
+ */
+
+class T8255968_11 {
+ T8255968_11_TestMethodReference c = T8255968_11_Test::new;
+}
+
+interface T8255968_11_TestMethodReference {
+ T8255968_11_Test create(int x);
+}
+
+class T8255968_11_Test {
+ T8255968_11_Test(String x) {} // If this method is private, compiler will output the same error message.
+}
diff --git a/test/langtools/tools/javac/T8255968/T8255968_11.out b/test/langtools/tools/javac/T8255968/T8255968_11.out
new file mode 100644
index 0000000000000..63b1546402aeb
--- /dev/null
+++ b/test/langtools/tools/javac/T8255968/T8255968_11.out
@@ -0,0 +1,2 @@
+T8255968_11.java:32:41: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, T8255968_11_Test, java.lang.String, int, kindname.class, T8255968_11_Test, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: int, java.lang.String))))
+1 error
diff --git a/test/langtools/tools/javac/T8255968/T8255968_12.java b/test/langtools/tools/javac/T8255968/T8255968_12.java
new file mode 100644
index 0000000000000..f58181617c72d
--- /dev/null
+++ b/test/langtools/tools/javac/T8255968/T8255968_12.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 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
+ * @bug 8255968
+ * @summary Confusing error message for inaccessible constructor
+ * @run compile/fail/ref=T8255968_12.out -XDrawDiagnostics T8255968_12.java
+ */
+
+class T8255968_12 {
+ T8255968_12_TestMethodReference c = T8255968_12_Test::new;
+}
+
+interface T8255968_12_TestMethodReference {
+ T8255968_12_Test create(int x);
+}
+
+class T8255968_12_Test {
+ private T8255968_12_Test(int x) {} // This method is not at the end.
+ T8255968_12_Test(String x) {} // If this method is private, compiler will output the same error message.
+}
diff --git a/test/langtools/tools/javac/T8255968/T8255968_12.out b/test/langtools/tools/javac/T8255968/T8255968_12.out
new file mode 100644
index 0000000000000..5d9205c15ce0f
--- /dev/null
+++ b/test/langtools/tools/javac/T8255968/T8255968_12.out
@@ -0,0 +1,2 @@
+T8255968_12.java:32:41: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbols: kindname.constructor, T8255968_12_Test, int,{(compiler.misc.inapplicable.method: kindname.constructor, T8255968_12_Test, T8255968_12_Test(int), (compiler.misc.report.access: T8255968_12_Test(int), private, T8255968_12_Test)),(compiler.misc.inapplicable.method: kindname.constructor, T8255968_12_Test, T8255968_12_Test(java.lang.String), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: int, java.lang.String)))}))
+1 error
diff --git a/test/langtools/tools/javac/T8255968/T8255968_13.java b/test/langtools/tools/javac/T8255968/T8255968_13.java
new file mode 100644
index 0000000000000..a1a0005f3e754
--- /dev/null
+++ b/test/langtools/tools/javac/T8255968/T8255968_13.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 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
+ * @bug 8255968
+ * @summary Confusing error message for inaccessible constructor
+ * @run compile/fail/ref=T8255968_13.out -XDrawDiagnostics T8255968_13.java
+ */
+
+class T8255968_13 {
+ T8255968_13_TestMethodReference c = T8255968_13_Test::new;
+}
+
+interface T8255968_13_TestMethodReference {
+ T8255968_13_Test create(int x);
+}
+
+class T8255968_13_Test {
+ T8255968_13_Test(String x) {} // If this method is private, compiler will output the same error message.
+ private T8255968_13_Test(int x) {} // This method is at the end.
+}
diff --git a/test/langtools/tools/javac/T8255968/T8255968_13.out b/test/langtools/tools/javac/T8255968/T8255968_13.out
new file mode 100644
index 0000000000000..316c5a9a981e8
--- /dev/null
+++ b/test/langtools/tools/javac/T8255968/T8255968_13.out
@@ -0,0 +1,2 @@
+T8255968_13.java:32:41: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbols: kindname.constructor, T8255968_13_Test, int,{(compiler.misc.inapplicable.method: kindname.constructor, T8255968_13_Test, T8255968_13_Test(int), (compiler.misc.report.access: T8255968_13_Test(int), private, T8255968_13_Test)),(compiler.misc.inapplicable.method: kindname.constructor, T8255968_13_Test, T8255968_13_Test(java.lang.String), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: int, java.lang.String)))}))
+1 error
diff --git a/test/langtools/tools/javac/T8255968/T8255968_14.java b/test/langtools/tools/javac/T8255968/T8255968_14.java
new file mode 100644
index 0000000000000..f80c84cb8cb94
--- /dev/null
+++ b/test/langtools/tools/javac/T8255968/T8255968_14.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 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
+ * @bug 8255968
+ * @summary Confusing error message for inaccessible constructor
+ * @run compile/fail/ref=T8255968_14.out -XDrawDiagnostics T8255968_14.java
+ */
+
+class T8255968_14 {
+ T8255968_14_TestMethodReference c = T8255968_14_Test::new;
+}
+
+interface T8255968_14_TestMethodReference {
+ T8255968_14_Test create(int x);
+}
+
+class T8255968_14_Test {
+ private T8255968_14_Test(int x) {} // This method is not at the end.
+ T8255968_14_Test(String x) {} // If this method is private, compiler will output the same error message.
+ private T8255968_14_Test(int[] x) {}
+}
diff --git a/test/langtools/tools/javac/T8255968/T8255968_14.out b/test/langtools/tools/javac/T8255968/T8255968_14.out
new file mode 100644
index 0000000000000..8df0f90875d8c
--- /dev/null
+++ b/test/langtools/tools/javac/T8255968/T8255968_14.out
@@ -0,0 +1,2 @@
+T8255968_14.java:32:41: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbols: kindname.constructor, T8255968_14_Test, int,{(compiler.misc.inapplicable.method: kindname.constructor, T8255968_14_Test, T8255968_14_Test(int), (compiler.misc.report.access: T8255968_14_Test(int), private, T8255968_14_Test)),(compiler.misc.inapplicable.method: kindname.constructor, T8255968_14_Test, T8255968_14_Test(java.lang.String), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: int, java.lang.String))),(compiler.misc.inapplicable.method: kindname.constructor, T8255968_14_Test, T8255968_14_Test(int[]), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: int, int[])))}))
+1 error
diff --git a/test/langtools/tools/javac/T8255968/T8255968_15.java b/test/langtools/tools/javac/T8255968/T8255968_15.java
new file mode 100644
index 0000000000000..49f900381ef39
--- /dev/null
+++ b/test/langtools/tools/javac/T8255968/T8255968_15.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 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
+ * @bug 8255968
+ * @summary Confusing error message for inaccessible constructor
+ * @run compile/fail/ref=T8255968_15.out -XDrawDiagnostics T8255968_15.java
+ */
+
+class T8255968_15 {
+ T8255968_15_TestMethodReference c = T8255968_15_Test::new;
+}
+
+interface T8255968_15_TestMethodReference {
+ T8255968_15_Test create(int x);
+}
+
+class T8255968_15_Test {
+ T8255968_15_Test(String x) {} // If this method is private, compiler will output the same error message.
+ private T8255968_15_Test(int x) {} // This method is not at the end.
+ private T8255968_15_Test(int[] x) {}
+}
diff --git a/test/langtools/tools/javac/T8255968/T8255968_15.out b/test/langtools/tools/javac/T8255968/T8255968_15.out
new file mode 100644
index 0000000000000..cf9e7cd8af7f8
--- /dev/null
+++ b/test/langtools/tools/javac/T8255968/T8255968_15.out
@@ -0,0 +1,2 @@
+T8255968_15.java:32:41: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbols: kindname.constructor, T8255968_15_Test, int,{(compiler.misc.inapplicable.method: kindname.constructor, T8255968_15_Test, T8255968_15_Test(java.lang.String), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: int, java.lang.String))),(compiler.misc.inapplicable.method: kindname.constructor, T8255968_15_Test, T8255968_15_Test(int), (compiler.misc.report.access: T8255968_15_Test(int), private, T8255968_15_Test)),(compiler.misc.inapplicable.method: kindname.constructor, T8255968_15_Test, T8255968_15_Test(int[]), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: int, int[])))}))
+1 error
diff --git a/test/langtools/tools/javac/T8255968/T8255968_16.java b/test/langtools/tools/javac/T8255968/T8255968_16.java
new file mode 100644
index 0000000000000..9638338897052
--- /dev/null
+++ b/test/langtools/tools/javac/T8255968/T8255968_16.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 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
+ * @bug 8255968
+ * @summary Confusing error message for inaccessible constructor
+ * @run compile/fail/ref=T8255968_16.out -XDrawDiagnostics T8255968_16.java
+ */
+
+class T8255968_16 {
+ T8255968_16_TestMethodReference c = T8255968_16_Test::new;
+}
+
+interface T8255968_16_TestMethodReference {
+ T8255968_16_Test create(int x);
+}
+
+class T8255968_16_Test {
+ T8255968_16_Test(String x) {} // If this method is private, compiler will output the same error message.
+ private T8255968_16_Test(int[] x) {}
+ private T8255968_16_Test(int x) {} // This method is at the end.
+}
diff --git a/test/langtools/tools/javac/T8255968/T8255968_16.out b/test/langtools/tools/javac/T8255968/T8255968_16.out
new file mode 100644
index 0000000000000..790dac8e8a3dd
--- /dev/null
+++ b/test/langtools/tools/javac/T8255968/T8255968_16.out
@@ -0,0 +1,2 @@
+T8255968_16.java:32:41: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbols: kindname.constructor, T8255968_16_Test, int,{(compiler.misc.inapplicable.method: kindname.constructor, T8255968_16_Test, T8255968_16_Test(java.lang.String), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: int, java.lang.String))),(compiler.misc.inapplicable.method: kindname.constructor, T8255968_16_Test, T8255968_16_Test(int), (compiler.misc.report.access: T8255968_16_Test(int), private, T8255968_16_Test)),(compiler.misc.inapplicable.method: kindname.constructor, T8255968_16_Test, T8255968_16_Test(int[]), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: int, int[])))}))
+1 error
diff --git a/test/langtools/tools/javac/T8255968/T8255968_2.java b/test/langtools/tools/javac/T8255968/T8255968_2.java
new file mode 100644
index 0000000000000..01fe34801134a
--- /dev/null
+++ b/test/langtools/tools/javac/T8255968/T8255968_2.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 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
+ * @bug 8255968
+ * @summary Confusing error message for inaccessible constructor
+ * @run compile/fail/ref=T8255968_2.out -XDrawDiagnostics T8255968_2.java
+ */
+
+class T8255968_2 {
+ T8255968_2_Test c = new T8255968_2_Test(0);
+}
+
+class T8255968_2_Test {
+ T8255968_2_Test(String x) {} // If this method is private, compiler will output the same error message.
+}
diff --git a/test/langtools/tools/javac/T8255968/T8255968_2.out b/test/langtools/tools/javac/T8255968/T8255968_2.out
new file mode 100644
index 0000000000000..41b878a781173
--- /dev/null
+++ b/test/langtools/tools/javac/T8255968/T8255968_2.out
@@ -0,0 +1,2 @@
+T8255968_2.java:32:25: compiler.err.cant.apply.symbol: kindname.constructor, T8255968_2_Test, java.lang.String, int, kindname.class, T8255968_2_Test, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: int, java.lang.String))
+1 error
diff --git a/test/langtools/tools/javac/T8255968/T8255968_3.java b/test/langtools/tools/javac/T8255968/T8255968_3.java
new file mode 100644
index 0000000000000..0125995a5f1ff
--- /dev/null
+++ b/test/langtools/tools/javac/T8255968/T8255968_3.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 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
+ * @bug 8255968
+ * @summary Confusing error message for inaccessible constructor
+ * @run compile/fail/ref=T8255968_3.out -XDrawDiagnostics T8255968_3.java
+ */
+
+class T8255968_3 {
+ T8255968_3_Test c = new T8255968_3_Test(0);
+}
+
+class T8255968_3_Test {
+ private T8255968_3_Test(int x) {} // This method is not at the end.
+ T8255968_3_Test(String x) {} // If this method is private, compiler will output the same error message.
+}
diff --git a/test/langtools/tools/javac/T8255968/T8255968_3.out b/test/langtools/tools/javac/T8255968/T8255968_3.out
new file mode 100644
index 0000000000000..55d6efad3a4f1
--- /dev/null
+++ b/test/langtools/tools/javac/T8255968/T8255968_3.out
@@ -0,0 +1,2 @@
+T8255968_3.java:32:25: compiler.err.cant.apply.symbols: kindname.constructor, T8255968_3_Test, int,{(compiler.misc.inapplicable.method: kindname.constructor, T8255968_3_Test, T8255968_3_Test(int), (compiler.misc.report.access: T8255968_3_Test(int), private, T8255968_3_Test)),(compiler.misc.inapplicable.method: kindname.constructor, T8255968_3_Test, T8255968_3_Test(java.lang.String), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: int, java.lang.String)))}
+1 error
diff --git a/test/langtools/tools/javac/T8255968/T8255968_4.java b/test/langtools/tools/javac/T8255968/T8255968_4.java
new file mode 100644
index 0000000000000..57e4f5110605c
--- /dev/null
+++ b/test/langtools/tools/javac/T8255968/T8255968_4.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 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
+ * @bug 8255968
+ * @summary Confusing error message for inaccessible constructor
+ * @run compile/fail/ref=T8255968_4.out -XDrawDiagnostics T8255968_4.java
+ */
+
+class T8255968_4 {
+ T8255968_4_Test c = new T8255968_4_Test(0);
+}
+
+class T8255968_4_Test {
+ T8255968_4_Test(String x) {} // If this method is private, compiler will output the same error message.
+ private T8255968_4_Test(int x) {} // This method is at the end.
+}
diff --git a/test/langtools/tools/javac/T8255968/T8255968_4.out b/test/langtools/tools/javac/T8255968/T8255968_4.out
new file mode 100644
index 0000000000000..d038fbfbae808
--- /dev/null
+++ b/test/langtools/tools/javac/T8255968/T8255968_4.out
@@ -0,0 +1,2 @@
+T8255968_4.java:32:25: compiler.err.cant.apply.symbols: kindname.constructor, T8255968_4_Test, int,{(compiler.misc.inapplicable.method: kindname.constructor, T8255968_4_Test, T8255968_4_Test(int), (compiler.misc.report.access: T8255968_4_Test(int), private, T8255968_4_Test)),(compiler.misc.inapplicable.method: kindname.constructor, T8255968_4_Test, T8255968_4_Test(java.lang.String), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: int, java.lang.String)))}
+1 error
diff --git a/test/langtools/tools/javac/T8255968/T8255968_5.java b/test/langtools/tools/javac/T8255968/T8255968_5.java
new file mode 100644
index 0000000000000..1b42ac840803a
--- /dev/null
+++ b/test/langtools/tools/javac/T8255968/T8255968_5.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 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
+ * @bug 8255968
+ * @summary Confusing error message for inaccessible constructor
+ * @run compile/fail/ref=T8255968_5.out -XDrawDiagnostics T8255968_5.java
+ */
+
+class T8255968_5 {
+ T8255968_5_Test c = new T8255968_5_Test(0);
+}
+
+class T8255968_5_Test {
+ private T8255968_5_Test(int x) {} // This method is not at the end.
+ T8255968_5_Test(String x) {} // If this method is private, compiler will output the same error message.
+ private T8255968_5_Test(int[] x) {}
+}
diff --git a/test/langtools/tools/javac/T8255968/T8255968_5.out b/test/langtools/tools/javac/T8255968/T8255968_5.out
new file mode 100644
index 0000000000000..a74a2d0629d98
--- /dev/null
+++ b/test/langtools/tools/javac/T8255968/T8255968_5.out
@@ -0,0 +1,2 @@
+T8255968_5.java:32:25: compiler.err.cant.apply.symbols: kindname.constructor, T8255968_5_Test, int,{(compiler.misc.inapplicable.method: kindname.constructor, T8255968_5_Test, T8255968_5_Test(int), (compiler.misc.report.access: T8255968_5_Test(int), private, T8255968_5_Test)),(compiler.misc.inapplicable.method: kindname.constructor, T8255968_5_Test, T8255968_5_Test(java.lang.String), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: int, java.lang.String))),(compiler.misc.inapplicable.method: kindname.constructor, T8255968_5_Test, T8255968_5_Test(int[]), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: int, int[])))}
+1 error
diff --git a/test/langtools/tools/javac/T8255968/T8255968_6.java b/test/langtools/tools/javac/T8255968/T8255968_6.java
new file mode 100644
index 0000000000000..fda79dc969388
--- /dev/null
+++ b/test/langtools/tools/javac/T8255968/T8255968_6.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 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
+ * @bug 8255968
+ * @summary Confusing error message for inaccessible constructor
+ * @run compile/fail/ref=T8255968_6.out -XDrawDiagnostics T8255968_6.java
+ */
+
+class T8255968_6 {
+ T8255968_6_Test c = new T8255968_6_Test(0);
+}
+
+class T8255968_6_Test {
+ T8255968_6_Test(String x) {} // If this method is private, compiler will output the same error message.
+ private T8255968_6_Test(int x) {} // This method is not at the end.
+ private T8255968_6_Test(int[] x) {}
+}
diff --git a/test/langtools/tools/javac/T8255968/T8255968_6.out b/test/langtools/tools/javac/T8255968/T8255968_6.out
new file mode 100644
index 0000000000000..c10d2807aa256
--- /dev/null
+++ b/test/langtools/tools/javac/T8255968/T8255968_6.out
@@ -0,0 +1,2 @@
+T8255968_6.java:32:25: compiler.err.cant.apply.symbols: kindname.constructor, T8255968_6_Test, int,{(compiler.misc.inapplicable.method: kindname.constructor, T8255968_6_Test, T8255968_6_Test(java.lang.String), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: int, java.lang.String))),(compiler.misc.inapplicable.method: kindname.constructor, T8255968_6_Test, T8255968_6_Test(int), (compiler.misc.report.access: T8255968_6_Test(int), private, T8255968_6_Test)),(compiler.misc.inapplicable.method: kindname.constructor, T8255968_6_Test, T8255968_6_Test(int[]), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: int, int[])))}
+1 error
diff --git a/test/langtools/tools/javac/T8255968/T8255968_7.java b/test/langtools/tools/javac/T8255968/T8255968_7.java
new file mode 100644
index 0000000000000..be8802fb749c2
--- /dev/null
+++ b/test/langtools/tools/javac/T8255968/T8255968_7.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 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
+ * @bug 8255968
+ * @summary Confusing error message for inaccessible constructor
+ * @run compile/fail/ref=T8255968_7.out -XDrawDiagnostics T8255968_7.java
+ */
+
+class T8255968_7 {
+ T8255968_7_Test c = new T8255968_7_Test(0);
+}
+
+class T8255968_7_Test {
+ T8255968_7_Test(String x) {} // If this method is private, compiler will output the same error message.
+ private T8255968_7_Test(int[] x) {}
+ private T8255968_7_Test(int x) {} // This method is at the end.
+}
diff --git a/test/langtools/tools/javac/T8255968/T8255968_7.out b/test/langtools/tools/javac/T8255968/T8255968_7.out
new file mode 100644
index 0000000000000..41c9873c5927e
--- /dev/null
+++ b/test/langtools/tools/javac/T8255968/T8255968_7.out
@@ -0,0 +1,2 @@
+T8255968_7.java:32:25: compiler.err.cant.apply.symbols: kindname.constructor, T8255968_7_Test, int,{(compiler.misc.inapplicable.method: kindname.constructor, T8255968_7_Test, T8255968_7_Test(java.lang.String), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: int, java.lang.String))),(compiler.misc.inapplicable.method: kindname.constructor, T8255968_7_Test, T8255968_7_Test(int), (compiler.misc.report.access: T8255968_7_Test(int), private, T8255968_7_Test)),(compiler.misc.inapplicable.method: kindname.constructor, T8255968_7_Test, T8255968_7_Test(int[]), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: int, int[])))}
+1 error
diff --git a/test/langtools/tools/javac/T8255968/T8255968_8.java b/test/langtools/tools/javac/T8255968/T8255968_8.java
new file mode 100644
index 0000000000000..9471ae8285923
--- /dev/null
+++ b/test/langtools/tools/javac/T8255968/T8255968_8.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 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
+ * @bug 8255968
+ * @summary Confusing error message for inaccessible constructor
+ * @run compile -XDrawDiagnostics T8255968_8.java
+ */
+
+class T8255968_8_Outer {
+ void m() {}
+ void m(String s) {}
+
+ class T8255968_8_Inner extends T8255968_8_Sup {
+ void test() {
+ m();
+ }
+ }
+}
+
+class T8255968_8_Sup {
+ private void m(String s) {}
+ private void m() {}
+}
diff --git a/test/langtools/tools/javac/T8255968/T8255968_9.java b/test/langtools/tools/javac/T8255968/T8255968_9.java
new file mode 100644
index 0000000000000..7fe1eccf6d02c
--- /dev/null
+++ b/test/langtools/tools/javac/T8255968/T8255968_9.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 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
+ * @bug 8255968
+ * @summary Confusing error message for inaccessible constructor
+ * @run compile -XDrawDiagnostics T8255968_9.java
+ */
+
+class T8255968_9 {
+ T8255968_9_TestMethodReference c = T8255968_9_Test::new;
+}
+
+interface T8255968_9_TestMethodReference {
+ T8255968_9_Test create(int x);
+}
+
+class T8255968_9_Test {
+ T8255968_9_Test(int x) {}
+}
From 015e6e58c51e489b3ba0221abe2de966bf05e0de Mon Sep 17 00:00:00 2001
From: Nils Eliasson
Date: Tue, 1 Dec 2020 21:08:45 +0000
Subject: [PATCH 003/504] 8257460: Further CompilerOracle cleanup
Reviewed-by: kvn, redestad, thartmann
---
.../share/compiler/compilerDirectives.cpp | 2 +-
src/hotspot/share/compiler/compilerOracle.cpp | 80 +++++++++----------
src/hotspot/share/compiler/compilerOracle.hpp | 6 +-
src/hotspot/share/prims/whitebox.cpp | 5 +-
4 files changed, 49 insertions(+), 44 deletions(-)
diff --git a/src/hotspot/share/compiler/compilerDirectives.cpp b/src/hotspot/share/compiler/compilerDirectives.cpp
index ddef13ac6c541..830d63a94b501 100644
--- a/src/hotspot/share/compiler/compilerDirectives.cpp
+++ b/src/hotspot/share/compiler/compilerDirectives.cpp
@@ -359,7 +359,7 @@ DirectiveSet* DirectiveSet::compilecommand_compatibility_init(const methodHandle
}
// inline and dontinline (including exclude) are implemented in the directiveset accessors
-#define init_default_cc(name, type, dvalue, cc_flag) { type v; if (!_modified[name##Index] && CompilerOracle::has_option_value(method, CompileCommand::cc_flag, v) && v != this->name##Option) { set.cloned()->name##Option = v; } }
+#define init_default_cc(name, type, dvalue, cc_flag) { type v; if (!_modified[name##Index] && CompileCommand::cc_flag != CompileCommand::Unknown && CompilerOracle::has_option_value(method, CompileCommand::cc_flag, v) && v != this->name##Option) { set.cloned()->name##Option = v; } }
compilerdirectives_common_flags(init_default_cc)
compilerdirectives_c2_flags(init_default_cc)
compilerdirectives_c1_flags(init_default_cc)
diff --git a/src/hotspot/share/compiler/compilerOracle.cpp b/src/hotspot/share/compiler/compilerOracle.cpp
index 878b65921709d..193c791df7457 100644
--- a/src/hotspot/share/compiler/compilerOracle.cpp
+++ b/src/hotspot/share/compiler/compilerOracle.cpp
@@ -104,7 +104,6 @@ class TypedMethodOptionMatcher : public MethodMatcher {
private:
TypedMethodOptionMatcher* _next;
enum CompileCommand _option;
- OptionType _type;
public:
union {
@@ -117,18 +116,16 @@ class TypedMethodOptionMatcher : public MethodMatcher {
TypedMethodOptionMatcher() : MethodMatcher(),
_next(NULL),
- _option(CompileCommand::Unknown),
- _type(OptionType::Unknown) {
+ _option(CompileCommand::Unknown) {
memset(&_u, 0, sizeof(_u));
}
~TypedMethodOptionMatcher();
static TypedMethodOptionMatcher* parse_method_pattern(char*& line, char* errorbuf, const int buf_size);
- TypedMethodOptionMatcher* match(const methodHandle &method, enum CompileCommand option, OptionType type);
+ TypedMethodOptionMatcher* match(const methodHandle &method, enum CompileCommand option);
- void init(enum CompileCommand option, OptionType type, TypedMethodOptionMatcher* next) {
+ void init(enum CompileCommand option, TypedMethodOptionMatcher* next) {
_next = next;
- _type = type;
_option = option;
}
@@ -140,7 +137,6 @@ class TypedMethodOptionMatcher : public MethodMatcher {
void set_next(TypedMethodOptionMatcher* next) {_next = next; }
TypedMethodOptionMatcher* next() { return _next; }
- OptionType type() { return _type; }
enum CompileCommand option() { return _option; }
template T value();
template void set_value(T value);
@@ -194,8 +190,9 @@ void TypedMethodOptionMatcher::print() {
ttyLocker ttyl;
print_base(tty);
const char* name = option2name(_option);
- switch (_type) {
- case OptionType::Intx:
+ enum OptionType type = option2type(_option);
+ switch (type) {
+ case OptionType::Intx:
tty->print_cr(" intx %s = " INTX_FORMAT, name, value());
break;
case OptionType::Uintx:
@@ -208,6 +205,7 @@ void TypedMethodOptionMatcher::print() {
tty->print_cr(" double %s = %f", name, value());
break;
case OptionType::Ccstr:
+ case OptionType::Ccstrlist:
tty->print_cr(" const char* %s = '%s'", name, value());
break;
default:
@@ -244,7 +242,8 @@ TypedMethodOptionMatcher* TypedMethodOptionMatcher::clone() {
}
TypedMethodOptionMatcher::~TypedMethodOptionMatcher() {
- if (type() == OptionType::Ccstr) {
+ enum OptionType type = option2type(_option);
+ if (type == OptionType::Ccstr || type == OptionType::Ccstrlist) {
ccstr v = value();
os::free((void*)v);
}
@@ -263,7 +262,7 @@ TypedMethodOptionMatcher* TypedMethodOptionMatcher::parse_method_pattern(char*&
return tom;
}
-TypedMethodOptionMatcher* TypedMethodOptionMatcher::match(const methodHandle& method, enum CompileCommand option, OptionType type) {
+TypedMethodOptionMatcher* TypedMethodOptionMatcher::match(const methodHandle& method, enum CompileCommand option) {
TypedMethodOptionMatcher* current = this;
while (current != NULL) {
if (current->_option == option) {
@@ -285,12 +284,9 @@ static void register_command(TypedMethodOptionMatcher* matcher,
tty->print_cr("Warning: +LogCompilation must be enabled in order for individual methods to be logged with ");
tty->print_cr(" CompileCommand=log,");
}
- enum OptionType type = option2type(option);
- if (type == OptionType::Ccstrlist) {
- type = OptionType::Ccstr; // ccstrlists are stores as ccstr
- }
- assert(type == get_type_for(), "sanity");
- matcher->init(option, type, option_list);
+ assert(CompilerOracle::option_matches_type(option, value), "Value must match option type");
+
+ matcher->init(option, option_list);
matcher->set_value(value);
option_list = matcher;
if ((option != CompileCommand::DontInline) &&
@@ -308,26 +304,10 @@ static void register_command(TypedMethodOptionMatcher* matcher,
}
template
-bool CompilerOracle::has_option_value(const methodHandle& method, enum CompileCommand option, T& value, bool verify_type) {
- enum OptionType type = option2type(option);
- if (type == OptionType::Unknown) {
- return false; // Can't query options with type Unknown.
- }
- if (type == OptionType::Ccstrlist) {
- type = OptionType::Ccstr; // CCstrList type options are stored as Ccstr
- }
- if (verify_type) {
- if (type != get_type_for()) {
- // Whitebox API expects false if option and type doesn't match
- return false;
- }
- } else {
- assert(type == get_type_for(), "Value type (%s) must match option %s (%s)",
- optiontype2name(get_type_for()),
- option2name(option), optiontype2name(option2type(option)));
- }
+bool CompilerOracle::has_option_value(const methodHandle& method, enum CompileCommand option, T& value) {
+ assert(option_matches_type(option, value), "Value must match option type");
if (option_list != NULL) {
- TypedMethodOptionMatcher* m = option_list->match(method, option, type);
+ TypedMethodOptionMatcher* m = option_list->match(method, option);
if (m != NULL) {
value = m->value();
return true;
@@ -361,11 +341,29 @@ bool CompilerOracle::has_any_command_set() {
}
// Explicit instantiation for all OptionTypes supported.
-template bool CompilerOracle::has_option_value(const methodHandle& method, enum CompileCommand option, intx& value, bool verify_type);
-template bool CompilerOracle::has_option_value(const methodHandle& method, enum CompileCommand option, uintx& value, bool verify_type);
-template bool CompilerOracle::has_option_value(const methodHandle& method, enum CompileCommand option, bool& value, bool verify_type);
-template bool CompilerOracle::has_option_value(const methodHandle& method, enum CompileCommand option, ccstr& value, bool verify_type);
-template bool CompilerOracle::has_option_value(const methodHandle& method, enum CompileCommand option, double& value, bool verify_type);
+template bool CompilerOracle::has_option_value(const methodHandle& method, enum CompileCommand option, intx& value);
+template bool CompilerOracle::has_option_value(const methodHandle& method, enum CompileCommand option, uintx& value);
+template bool CompilerOracle::has_option_value(const methodHandle& method, enum CompileCommand option, bool& value);
+template bool CompilerOracle::has_option_value(const methodHandle& method, enum CompileCommand option, ccstr& value);
+template bool CompilerOracle::has_option_value(const methodHandle& method, enum CompileCommand option, double& value);
+
+template
+bool CompilerOracle::option_matches_type(enum CompileCommand option, T& value) {
+ enum OptionType option_type = option2type(option);
+ if (option_type == OptionType::Unknown) {
+ return false; // Can't query options with type Unknown.
+ }
+ if (option_type == OptionType::Ccstrlist) {
+ option_type = OptionType::Ccstr; // CCstrList type options are stored as Ccstr
+ }
+ return (get_type_for() == option_type);
+}
+
+template bool CompilerOracle::option_matches_type(enum CompileCommand option, intx& value);
+template bool CompilerOracle::option_matches_type(enum CompileCommand option, uintx& value);
+template bool CompilerOracle::option_matches_type(enum CompileCommand option, bool& value);
+template bool CompilerOracle::option_matches_type(enum CompileCommand option, ccstr& value);
+template bool CompilerOracle::option_matches_type(enum CompileCommand option, double& value);
bool CompilerOracle::has_option(const methodHandle& method, enum CompileCommand option) {
bool value = false;
diff --git a/src/hotspot/share/compiler/compilerOracle.hpp b/src/hotspot/share/compiler/compilerOracle.hpp
index e834254f50686..e8f7c2097a420 100644
--- a/src/hotspot/share/compiler/compilerOracle.hpp
+++ b/src/hotspot/share/compiler/compilerOracle.hpp
@@ -149,7 +149,11 @@ class CompilerOracle : AllStatic {
// Check if method has option and value set. If yes, overwrite value and return true,
// otherwise leave value unchanged and return false.
template
- static bool has_option_value(const methodHandle& method, enum CompileCommand option, T& value, bool verfiy_type = false);
+ static bool has_option_value(const methodHandle& method, enum CompileCommand option, T& value);
+
+ // This check is currently only needed by whitebox API
+ template
+ static bool option_matches_type(enum CompileCommand option, T& value);
// Reads from string instead of file
static void parse_from_string(const char* option_string, void (*parser)(char*));
diff --git a/src/hotspot/share/prims/whitebox.cpp b/src/hotspot/share/prims/whitebox.cpp
index 7e780990401df..28a5162abd0ac 100644
--- a/src/hotspot/share/prims/whitebox.cpp
+++ b/src/hotspot/share/prims/whitebox.cpp
@@ -1814,7 +1814,10 @@ static bool GetMethodOption(JavaThread* thread, JNIEnv* env, jobject method, jst
if (option == CompileCommand::Unknown) {
return false;
}
- return CompilerOracle::has_option_value(mh, option, *value, true /* verify type*/);
+ if (!CompilerOracle::option_matches_type(option, *value)) {
+ return false;
+ }
+ return CompilerOracle::has_option_value(mh, option, *value);
}
WB_ENTRY(jobject, WB_GetMethodBooleaneOption(JNIEnv* env, jobject wb, jobject method, jstring name))
From 00e79db89e10fac71a8ae4b60b2ef23c0deff032 Mon Sep 17 00:00:00 2001
From: Claes Redestad
Date: Tue, 1 Dec 2020 22:50:05 +0000
Subject: [PATCH 004/504] 8257511: JDK-8254082 brings regression to
AbstractStringBuilder.insert(int dstOffset, CharSequence s, int start, int
end)
Reviewed-by: alanb, rriggs, bpb
---
.../java/lang/AbstractStringBuilder.java | 2 +-
test/jdk/java/lang/StringBuilder/Insert.java | 32 ++++++++++++++-----
2 files changed, 25 insertions(+), 9 deletions(-)
diff --git a/src/java.base/share/classes/java/lang/AbstractStringBuilder.java b/src/java.base/share/classes/java/lang/AbstractStringBuilder.java
index 49bf751c2e854..dc1afeaa10a79 100644
--- a/src/java.base/share/classes/java/lang/AbstractStringBuilder.java
+++ b/src/java.base/share/classes/java/lang/AbstractStringBuilder.java
@@ -1717,7 +1717,7 @@ private void putStringAt(int index, String str, int off, int end) {
if (getCoder() != str.coder()) {
inflate();
}
- str.getBytes(value, off, index, coder, end);
+ str.getBytes(value, off, index, coder, end - off);
}
private void putStringAt(int index, String str) {
diff --git a/test/jdk/java/lang/StringBuilder/Insert.java b/test/jdk/java/lang/StringBuilder/Insert.java
index 2922c803f6463..d4b1ef28d866f 100644
--- a/test/jdk/java/lang/StringBuilder/Insert.java
+++ b/test/jdk/java/lang/StringBuilder/Insert.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -21,15 +21,31 @@
* questions.
*/
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
/**
* @test
- * @bug 4914802
- * @summary Test Insert method for infinite loop
+ * @run testng Insert
+ * @bug 4914802 8257511
+ * @summary Test StringBuilder.insert sanity tests
*/
-
+@Test
public class Insert {
- public static void main (String argv[]) throws Exception {
- StringBuilder sb = new StringBuilder();
- sb.insert(0, false);
- }
+
+ public void insertFalse() {
+ // Caused an infinite loop before 4914802
+ StringBuilder sb = new StringBuilder();
+ assertEquals("false", sb.insert(0, false).toString());
+ }
+
+ public void insertOffset() {
+ // 8254082 made the String variant cause an AIOOBE, fixed in 8257511
+ assertEquals("efabc", new StringBuilder("abc").insert(0, "def", 1, 3).toString());
+ assertEquals("efabc", new StringBuilder("abc").insert(0, new StringBuilder("def"), 1, 3).toString());
+ // insert(I[CII) and insert(ILjava/lang/CharSequence;II) are inconsistently specified
+ assertEquals("efabc", new StringBuilder("abc").insert(0, new char[] {'d', 'e', 'f'}, 1, 2).toString());
+ }
+
}
From 927504e8270b4ea44c10d7faf0959b107281ddfe Mon Sep 17 00:00:00 2001
From: David Holmes
Date: Tue, 1 Dec 2020 23:10:39 +0000
Subject: [PATCH 005/504] 8256474: Migrate Mutex _owner accesses to use Atomic
operations
Reviewed-by: coleenp, kbarrett
---
src/hotspot/share/runtime/mutex.cpp | 24 ++++++++++++------------
src/hotspot/share/runtime/mutex.hpp | 17 ++++++++++++-----
2 files changed, 24 insertions(+), 17 deletions(-)
diff --git a/src/hotspot/share/runtime/mutex.cpp b/src/hotspot/share/runtime/mutex.cpp
index 220b0b58ce9d5..fa969bb20e85c 100644
--- a/src/hotspot/share/runtime/mutex.cpp
+++ b/src/hotspot/share/runtime/mutex.cpp
@@ -100,7 +100,7 @@ void Mutex::lock_contended(Thread* self) {
}
void Mutex::lock(Thread* self) {
- assert(_owner != self, "invariant");
+ assert(owner() != self, "invariant");
check_safepoint_state(self);
check_rank(self);
@@ -125,7 +125,7 @@ void Mutex::lock() {
// in the wrong way this can lead to a deadlock with the safepoint code.
void Mutex::lock_without_safepoint_check(Thread * self) {
- assert(_owner != self, "invariant");
+ assert(owner() != self, "invariant");
check_no_safepoint_state(self);
check_rank(self);
@@ -145,7 +145,7 @@ bool Mutex::try_lock_inner(bool do_rank_checks) {
Thread * const self = Thread::current();
// Checking the owner hides the potential difference in recursive locking behaviour
// on some platforms.
- if (_owner == self) {
+ if (owner() == self) {
return false;
}
@@ -308,13 +308,13 @@ Monitor::Monitor(int Rank, const char * name, bool allow_vm_block,
Mutex(Rank, name, allow_vm_block, safepoint_check_required) {}
bool Mutex::owned_by_self() const {
- return _owner == Thread::current();
+ return owner() == Thread::current();
}
void Mutex::print_on_error(outputStream* st) const {
st->print("[" PTR_FORMAT, p2i(this));
st->print("] %s", _name);
- st->print(" - owner thread: " PTR_FORMAT, p2i(_owner));
+ st->print(" - owner thread: " PTR_FORMAT, p2i(owner()));
}
// ----------------------------------------------------------------------------------
@@ -332,7 +332,7 @@ const char* print_safepoint_check(Mutex::SafepointCheckRequired safepoint_check)
void Mutex::print_on(outputStream* st) const {
st->print("Mutex: [" PTR_FORMAT "] %s - owner: " PTR_FORMAT,
- p2i(this), _name, p2i(_owner));
+ p2i(this), _name, p2i(owner()));
if (_allow_vm_block) {
st->print("%s", " allow_vm_block");
}
@@ -350,9 +350,9 @@ void Mutex::assert_owner(Thread * expected) {
else if (expected == Thread::current()) {
msg = "should be owned by current thread";
}
- assert(_owner == expected,
+ assert(owner() == expected,
"%s: owner=" INTPTR_FORMAT ", should be=" INTPTR_FORMAT,
- msg, p2i(_owner), p2i(expected));
+ msg, p2i(owner()), p2i(expected));
}
Mutex* Mutex::get_least_ranked_lock(Mutex* locks) {
@@ -469,8 +469,8 @@ void Mutex::set_owner_implementation(Thread *new_owner) {
// the thread is acquiring this lock
assert(new_owner == Thread::current(), "Should I be doing this?");
- assert(_owner == NULL, "setting the owner thread of an already owned mutex");
- _owner = new_owner; // set the owner
+ assert(owner() == NULL, "setting the owner thread of an already owned mutex");
+ raw_set_owner(new_owner); // set the owner
// link "this" into the owned locks list
this->_next = new_owner->_owned_locks;
@@ -482,14 +482,14 @@ void Mutex::set_owner_implementation(Thread *new_owner) {
} else {
// the thread is releasing this lock
- Thread* old_owner = _owner;
+ Thread* old_owner = owner();
_last_owner = old_owner;
_skip_rank_check = false;
assert(old_owner != NULL, "removing the owner thread of an unowned mutex");
assert(old_owner == Thread::current(), "removing the owner thread of an unowned mutex");
- _owner = NULL; // set the owner
+ raw_set_owner(NULL); // set the owner
Mutex* locks = old_owner->owned_locks();
diff --git a/src/hotspot/share/runtime/mutex.hpp b/src/hotspot/share/runtime/mutex.hpp
index fea8c8ecda6b0..06bf999be3462 100644
--- a/src/hotspot/share/runtime/mutex.hpp
+++ b/src/hotspot/share/runtime/mutex.hpp
@@ -26,6 +26,7 @@
#define SHARE_RUNTIME_MUTEX_HPP
#include "memory/allocation.hpp"
+#include "runtime/atomic.hpp"
#include "runtime/os.hpp"
// A Mutex/Monitor is a simple wrapper around a native lock plus condition
@@ -81,8 +82,14 @@ class Mutex : public CHeapObj {
native = max_nonleaf + 1
};
+ private:
+ // The _owner field is only set by the current thread, either to itself after it has acquired
+ // the low-level _lock, or to NULL before it has released the _lock. Accesses by any thread other
+ // than the lock owner are inherently racy.
+ Thread* volatile _owner;
+ void raw_set_owner(Thread* new_owner) { Atomic::store(&_owner, new_owner); }
+
protected: // Monitor-Mutex metadata
- Thread * volatile _owner; // The owner of the lock
os::PlatformMonitor _lock; // Native monitor implementation
char _name[MUTEX_NAME_LEN]; // Name of mutex/monitor
@@ -111,7 +118,7 @@ class Mutex : public CHeapObj {
#endif // ASSERT
protected:
- void set_owner_implementation(Thread* owner) NOT_DEBUG({ _owner = owner;});
+ void set_owner_implementation(Thread* owner) NOT_DEBUG({ raw_set_owner(owner);});
void check_block_state (Thread* thread) NOT_DEBUG_RETURN;
void check_safepoint_state (Thread* thread) NOT_DEBUG_RETURN;
void check_no_safepoint_state(Thread* thread) NOT_DEBUG_RETURN;
@@ -180,7 +187,7 @@ class Mutex : public CHeapObj {
void lock(); // prints out warning if VM thread blocks
void lock(Thread *thread); // overloaded with current thread
void unlock();
- bool is_locked() const { return _owner != NULL; }
+ bool is_locked() const { return owner() != NULL; }
bool try_lock(); // Like lock(), but unblocking. It returns false instead
private:
@@ -197,9 +204,9 @@ class Mutex : public CHeapObj {
// A thread should not call this if failure to acquire ownership will blocks its progress
bool try_lock_without_rank_check();
- // Current owner - not not MT-safe. Can only be used to guarantee that
+ // Current owner - note not MT-safe. Can only be used to guarantee that
// the current running thread owns the lock
- Thread* owner() const { return _owner; }
+ Thread* owner() const { return Atomic::load(&_owner); }
void set_owner(Thread* owner) { set_owner_implementation(owner); }
bool owned_by_self() const;
From ce496cbda508bc648741d7da9785dce93a7a5f26 Mon Sep 17 00:00:00 2001
From: Xin Liu
Date: Tue, 1 Dec 2020 23:50:53 +0000
Subject: [PATCH 006/504] 8257190: simplify PhaseIdealLoop constructors
Currently, C2 has 3 private constructors of PhaseIdealLoop as follows. a-b are for verification. only c is for real loop optimizations.
a. PhaseIdealLoop( PhaseIterGVN &igvn)
b. PhaseIdealLoop(PhaseIterGVN &igvn, const PhaseIdealLoop *verify_me)
c. PhaseIdealLoop(PhaseIterGVN &igvn, LoopOptsMode mode)
I propose 3 changes to simplify them.
1. add assertion in the constructor c. C2 shouldn't use mode = LoopOptsVerify for it.
2. merge a and b into one constructor.
3. make the merged verification ctor only for debug builds.
Reviewed-by: thartmann, kvn
---
src/hotspot/share/opto/loopnode.hpp | 25 +++++++++----------------
1 file changed, 9 insertions(+), 16 deletions(-)
diff --git a/src/hotspot/share/opto/loopnode.hpp b/src/hotspot/share/opto/loopnode.hpp
index 59160a0927c80..075073add2ef0 100644
--- a/src/hotspot/share/opto/loopnode.hpp
+++ b/src/hotspot/share/opto/loopnode.hpp
@@ -1045,17 +1045,6 @@ class PhaseIdealLoop : public PhaseTransform {
uint *_dom_depth; // Used for fast LCA test
GrowableArray* _dom_stk; // For recomputation of dom depth
- // Perform verification that the graph is valid.
- PhaseIdealLoop( PhaseIterGVN &igvn) :
- PhaseTransform(Ideal_Loop),
- _igvn(igvn),
- _verify_me(NULL),
- _verify_only(true),
- _dom_lca_tags(arena()), // Thread::resource_area
- _nodes_required(UINT_MAX) {
- build_and_optimize(LoopOptsVerify);
- }
-
// build the loop tree and perform any requested optimizations
void build_and_optimize(LoopOptsMode mode);
@@ -1063,26 +1052,30 @@ class PhaseIdealLoop : public PhaseTransform {
void Dominators();
// Compute the Ideal Node to Loop mapping
- PhaseIdealLoop(PhaseIterGVN &igvn, LoopOptsMode mode) :
+ PhaseIdealLoop(PhaseIterGVN& igvn, LoopOptsMode mode) :
PhaseTransform(Ideal_Loop),
_igvn(igvn),
- _verify_me(NULL),
+ _verify_me(nullptr),
_verify_only(false),
_dom_lca_tags(arena()), // Thread::resource_area
_nodes_required(UINT_MAX) {
+ assert(mode != LoopOptsVerify, "wrong constructor to verify IdealLoop");
build_and_optimize(mode);
}
- // Verify that verify_me made the same decisions as a fresh run.
- PhaseIdealLoop(PhaseIterGVN &igvn, const PhaseIdealLoop *verify_me) :
+#ifndef PRODUCT
+ // Verify that verify_me made the same decisions as a fresh run
+ // or only verify that the graph is valid if verify_me is null.
+ PhaseIdealLoop(PhaseIterGVN& igvn, const PhaseIdealLoop* verify_me = nullptr) :
PhaseTransform(Ideal_Loop),
_igvn(igvn),
_verify_me(verify_me),
- _verify_only(false),
+ _verify_only(verify_me == nullptr),
_dom_lca_tags(arena()), // Thread::resource_area
_nodes_required(UINT_MAX) {
build_and_optimize(LoopOptsVerify);
}
+#endif
public:
Node* idom_no_update(Node* d) const {
From 03f3b8eadd89f33a027b59c68c4af5f40b0b65ff Mon Sep 17 00:00:00 2001
From: Sergey Bylokhov
Date: Wed, 2 Dec 2020 00:04:20 +0000
Subject: [PATCH 007/504] 8210253: Clipped UI rendering with X11 pipeline and
HiDPI
Reviewed-by: aivanov, kizune
---
.../sun/java2d/x11/X11SurfaceData.java | 77 ++++++++++++-------
.../sun/java2d/x11/X11SurfaceDataProxy.java | 12 ++-
.../java2d/x11/X11VolatileSurfaceManager.java | 6 +-
3 files changed, 60 insertions(+), 35 deletions(-)
diff --git a/src/java.desktop/unix/classes/sun/java2d/x11/X11SurfaceData.java b/src/java.desktop/unix/classes/sun/java2d/x11/X11SurfaceData.java
index a4b995fae4a68..f96297b1019d6 100644
--- a/src/java.desktop/unix/classes/sun/java2d/x11/X11SurfaceData.java
+++ b/src/java.desktop/unix/classes/sun/java2d/x11/X11SurfaceData.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -25,28 +25,24 @@
package sun.java2d.x11;
-import java.awt.GraphicsDevice;
-import java.awt.GraphicsEnvironment;
-import java.awt.Color;
import java.awt.Composite;
-import java.awt.Rectangle;
import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
import java.awt.Image;
-import java.awt.color.ColorSpace;
+import java.awt.Rectangle;
import java.awt.Transparency;
-import java.awt.image.BufferedImage;
+import java.awt.color.ColorSpace;
import java.awt.image.ColorModel;
import java.awt.image.ComponentColorModel;
import java.awt.image.DirectColorModel;
import java.awt.image.IndexColorModel;
import java.awt.image.Raster;
-import java.awt.peer.ComponentPeer;
import sun.awt.SunHints;
import sun.awt.SunToolkit;
import sun.awt.X11ComponentPeer;
import sun.awt.X11GraphicsConfig;
-import sun.awt.X11GraphicsEnvironment;
import sun.awt.image.PixelConverter;
import sun.font.X11TextRenderer;
import sun.java2d.InvalidPipeException;
@@ -54,16 +50,15 @@
import sun.java2d.SunGraphicsEnvironment;
import sun.java2d.SurfaceData;
import sun.java2d.SurfaceDataProxy;
-import sun.java2d.loops.SurfaceType;
import sun.java2d.loops.CompositeType;
-import sun.java2d.loops.RenderLoops;
import sun.java2d.loops.GraphicsPrimitive;
+import sun.java2d.loops.RenderLoops;
+import sun.java2d.loops.SurfaceType;
import sun.java2d.loops.XORComposite;
-import sun.java2d.loops.Blit;
-import sun.java2d.pipe.ValidatePipe;
import sun.java2d.pipe.PixelToShapeConverter;
-import sun.java2d.pipe.TextPipe;
import sun.java2d.pipe.Region;
+import sun.java2d.pipe.TextPipe;
+import sun.java2d.pipe.ValidatePipe;
public abstract class X11SurfaceData extends XSurfaceData {
X11ComponentPeer peer;
@@ -411,11 +406,12 @@ public static X11PixmapSurfaceData createData(X11GraphicsConfig gc,
int width, int height,
ColorModel cm, Image image,
long drawable,
- int transparency)
+ int transparency,
+ boolean isTexture)
{
return new X11PixmapSurfaceData(gc, width, height, image,
getSurfaceType(gc, transparency, true),
- cm, drawable, transparency);
+ cm, drawable, transparency, isTexture);
}
// /**
@@ -699,11 +695,15 @@ public synchronized void makePipes() {
}
}
- public static class X11WindowSurfaceData extends X11SurfaceData {
+ private final static class X11WindowSurfaceData extends X11SurfaceData {
+
+ private final int scale;
+
public X11WindowSurfaceData(X11ComponentPeer peer,
X11GraphicsConfig gc,
SurfaceType sType) {
super(peer, gc, sType, peer.getColorModel());
+ this.scale = gc.getDevice().getScaleFactor();
if (isDrawableValid()) {
makePipes();
}
@@ -716,6 +716,8 @@ public SurfaceData getReplacement() {
public Rectangle getBounds() {
Rectangle r = peer.getBounds();
r.x = r.y = 0;
+ r.width *= scale;
+ r.height *= scale;
return r;
}
@@ -730,27 +732,40 @@ public boolean canSourceSendExposures(int x, int y, int w, int h) {
public Object getDestination() {
return peer.getTarget();
}
+
+ @Override
+ public double getDefaultScaleX() {
+ return scale;
+ }
+
+ @Override
+ public double getDefaultScaleY() {
+ return scale;
+ }
}
- public static class X11PixmapSurfaceData extends X11SurfaceData {
+ private final static class X11PixmapSurfaceData extends X11SurfaceData {
- Image offscreenImage;
- int width;
- int height;
- int transparency;
+ private final Image offscreenImage;
+ private final int width;
+ private final int height;
+ private final int transparency;
+ private final int scale;
public X11PixmapSurfaceData(X11GraphicsConfig gc,
int width, int height,
Image image,
SurfaceType sType, ColorModel cm,
- long drawable, int transparency)
+ long drawable, int transparency,
+ boolean isTexture)
{
super(null, gc, sType, cm);
- this.width = width;
- this.height = height;
+ this.scale = isTexture ? 1 : gc.getDevice().getScaleFactor();
+ this.width = width * scale;
+ this.height = height * scale;
offscreenImage = image;
this.transparency = transparency;
- initSurface(depth, width, height, drawable);
+ initSurface(depth, this.width, this.height, drawable);
makePipes();
}
@@ -798,6 +813,16 @@ public void flush() {
public Object getDestination() {
return offscreenImage;
}
+
+ @Override
+ public double getDefaultScaleX() {
+ return scale;
+ }
+
+ @Override
+ public double getDefaultScaleY() {
+ return scale;
+ }
}
private static LazyPipe lazypipe = new LazyPipe();
diff --git a/src/java.desktop/unix/classes/sun/java2d/x11/X11SurfaceDataProxy.java b/src/java.desktop/unix/classes/sun/java2d/x11/X11SurfaceDataProxy.java
index 6f21c01daeb82..e55c663181f08 100644
--- a/src/java.desktop/unix/classes/sun/java2d/x11/X11SurfaceDataProxy.java
+++ b/src/java.desktop/unix/classes/sun/java2d/x11/X11SurfaceDataProxy.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -26,18 +26,15 @@
package sun.java2d.x11;
import java.awt.Color;
-import java.awt.AlphaComposite;
-import java.awt.GraphicsConfiguration;
import java.awt.Transparency;
import java.awt.image.ColorModel;
-import java.awt.image.IndexColorModel;
import java.awt.image.DirectColorModel;
+import java.awt.image.IndexColorModel;
import sun.awt.X11GraphicsConfig;
+import sun.java2d.SunGraphics2D;
import sun.java2d.SurfaceData;
import sun.java2d.SurfaceDataProxy;
-import sun.java2d.SunGraphics2D;
-import sun.java2d.loops.SurfaceType;
import sun.java2d.loops.CompositeType;
/**
@@ -106,7 +103,8 @@ public SurfaceData validateSurfaceData(SurfaceData srcData,
// Bitmask will be created lazily during the blit phase
cachedData = X11SurfaceData.createData(x11gc, w, h,
x11gc.getColorModel(),
- null, 0, getTransparency());
+ null, 0,
+ getTransparency(), true);
} catch (OutOfMemoryError oome) {
}
}
diff --git a/src/java.desktop/unix/classes/sun/java2d/x11/X11VolatileSurfaceManager.java b/src/java.desktop/unix/classes/sun/java2d/x11/X11VolatileSurfaceManager.java
index 7adad31e19f22..2b06d471de883 100644
--- a/src/java.desktop/unix/classes/sun/java2d/x11/X11VolatileSurfaceManager.java
+++ b/src/java.desktop/unix/classes/sun/java2d/x11/X11VolatileSurfaceManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -29,6 +29,7 @@
import java.awt.ImageCapabilities;
import java.awt.Transparency;
import java.awt.image.ColorModel;
+
import sun.awt.X11GraphicsConfig;
import sun.awt.image.SunVolatileImage;
import sun.awt.image.VolatileSurfaceManager;
@@ -93,7 +94,8 @@ protected SurfaceData initAcceleratedSurface() {
vImg.getWidth(),
vImg.getHeight(),
cm, vImg, drawable,
- Transparency.OPAQUE);
+ Transparency.OPAQUE,
+ false);
} catch (NullPointerException ex) {
sData = null;
} catch (OutOfMemoryError er) {
From cfd070ece64fc4c4248caaf0803d02ba0600fe38 Mon Sep 17 00:00:00 2001
From: Paul Sandoz
Date: Wed, 2 Dec 2020 02:01:19 +0000
Subject: [PATCH 008/504] 8257537: [vector] Cleanup redundant bitwise cases on
floating point vectors
Reviewed-by: vlivanov
---
.../classes/jdk/incubator/vector/DoubleVector.java | 8 --------
.../classes/jdk/incubator/vector/FloatVector.java | 8 --------
.../jdk/incubator/vector/X-Vector.java.template | 12 ++++--------
3 files changed, 4 insertions(+), 24 deletions(-)
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 0e73f291ac454..4b4e3ac0a7923 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
@@ -665,8 +665,6 @@ opc, getClass(), double.class, length(),
v0.bOp(v1, (i, a, b) -> (double)Math.max(a, b));
case VECTOR_OP_MIN: return (v0, v1) ->
v0.bOp(v1, (i, a, b) -> (double)Math.min(a, b));
- case VECTOR_OP_OR: return (v0, v1) ->
- v0.bOp(v1, (i, a, b) -> fromBits(toBits(a) | toBits(b)));
default: return null;
}}));
}
@@ -2319,8 +2317,6 @@ opc, getClass(), double.class, length(),
toBits(v.rOp(MAX_OR_INF, (i, a, b) -> (double) Math.min(a, b)));
case VECTOR_OP_MAX: return v ->
toBits(v.rOp(MIN_OR_INF, (i, a, b) -> (double) Math.max(a, b)));
- case VECTOR_OP_OR: return v ->
- toBits(v.rOp((double)0, (i, a, b) -> fromBits(toBits(a) | toBits(b))));
default: return null;
}})));
}
@@ -2336,13 +2332,9 @@ DoubleVector reduceIdentityVector(VectorOperators.Associative op) {
= 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:
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 f43ef9e96fbd4..4c9cb3388013f 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
@@ -665,8 +665,6 @@ opc, getClass(), float.class, length(),
v0.bOp(v1, (i, a, b) -> (float)Math.max(a, b));
case VECTOR_OP_MIN: return (v0, v1) ->
v0.bOp(v1, (i, a, b) -> (float)Math.min(a, b));
- case VECTOR_OP_OR: return (v0, v1) ->
- v0.bOp(v1, (i, a, b) -> fromBits(toBits(a) | toBits(b)));
default: return null;
}}));
}
@@ -2339,8 +2337,6 @@ opc, getClass(), float.class, length(),
toBits(v.rOp(MAX_OR_INF, (i, a, b) -> (float) Math.min(a, b)));
case VECTOR_OP_MAX: return v ->
toBits(v.rOp(MIN_OR_INF, (i, a, b) -> (float) Math.max(a, b)));
- case VECTOR_OP_OR: return v ->
- toBits(v.rOp((float)0, (i, a, b) -> fromBits(toBits(a) | toBits(b))));
default: return null;
}})));
}
@@ -2356,13 +2352,9 @@ FloatVector reduceIdentityVector(VectorOperators.Associative op) {
= 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:
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 54399c82cfd76..e49e987265fda 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
@@ -731,10 +731,6 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> {
case VECTOR_OP_URSHIFT: return (v0, v1) ->
v0.bOp(v1, (i, a, n) -> ($type$)((a & LSHR_SETUP_MASK) >>> n));
#end[BITWISE]
-#if[FP]
- case VECTOR_OP_OR: return (v0, v1) ->
- v0.bOp(v1, (i, a, b) -> fromBits(toBits(a) | toBits(b)));
-#end[FP]
default: return null;
}}));
}
@@ -2836,10 +2832,6 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> {
case VECTOR_OP_XOR: return v ->
toBits(v.rOp(($type$)0, (i, a, b) -> ($type$)(a ^ b)));
#end[BITWISE]
-#if[FP]
- case VECTOR_OP_OR: return v ->
- toBits(v.rOp(($type$)0, (i, a, b) -> fromBits(toBits(a) | toBits(b))));
-#end[FP]
default: return null;
}})));
}
@@ -2855,13 +2847,17 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> {
= 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:
From 8f4fa3f8d5f34ebc80fb70f1b36aa67a8bd35211 Mon Sep 17 00:00:00 2001
From: Jie Fu
Date: Wed, 2 Dec 2020 02:31:08 +0000
Subject: [PATCH 009/504] 8257232: CompileThresholdScaling fails to work on
32-bit platforms
Reviewed-by: kvn, redestad
---
src/hotspot/share/compiler/compilerDefinitions.cpp | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/src/hotspot/share/compiler/compilerDefinitions.cpp b/src/hotspot/share/compiler/compilerDefinitions.cpp
index 2fcb359aa5ee2..dc8c726ce3605 100644
--- a/src/hotspot/share/compiler/compilerDefinitions.cpp
+++ b/src/hotspot/share/compiler/compilerDefinitions.cpp
@@ -119,13 +119,17 @@ intx CompilerConfig::scaled_freq_log(intx freq_log, double scale) {
// max_freq_bits accordingly.
intx max_freq_bits = InvocationCounter::number_of_count_bits + 1;
intx scaled_freq = scaled_compile_threshold((intx)1 << freq_log, scale);
+
if (scaled_freq == 0) {
// Return 0 right away to avoid calculating log2 of 0.
return 0;
- } else if (scaled_freq > nth_bit(max_freq_bits)) {
- return max_freq_bits;
} else {
- return log2_intptr(scaled_freq);
+ intx res = log2_intptr(scaled_freq);
+ if (res > max_freq_bits) {
+ return max_freq_bits;
+ } else {
+ return res;
+ }
}
}
From 541c7f74bbe0ffbacfa802e9e0d6cb6c63d81b10 Mon Sep 17 00:00:00 2001
From: Alexey Semenyuk
Date: Wed, 2 Dec 2020 02:50:33 +0000
Subject: [PATCH 010/504] 8257434: jpackage fails to create rpm on Fedora Linux
Reviewed-by: almatvee, herrick
---
.../jdk/jpackage/internal/resources/template.spec | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/template.spec b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/template.spec
index a1885ff949a6c..017761babb941 100644
--- a/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/template.spec
+++ b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/template.spec
@@ -5,19 +5,19 @@ Release: APPLICATION_RELEASE
License: APPLICATION_LICENSE_TYPE
Vendor: APPLICATION_VENDOR
-%if "xAPPLICATION_PREFIX" != x
+%if "xAPPLICATION_PREFIX" != "x"
Prefix: APPLICATION_PREFIX
%endif
Provides: APPLICATION_PACKAGE
-%if "xAPPLICATION_GROUP" != x
+%if "xAPPLICATION_GROUP" != "x"
Group: APPLICATION_GROUP
%endif
Autoprov: 0
Autoreq: 0
-%if "xPACKAGE_DEFAULT_DEPENDENCIES" != x || "xPACKAGE_CUSTOM_DEPENDENCIES" != x
+%if "xPACKAGE_DEFAULT_DEPENDENCIES" != "x" || "xPACKAGE_CUSTOM_DEPENDENCIES" != "x"
Requires: PACKAGE_DEFAULT_DEPENDENCIES PACKAGE_CUSTOM_DEPENDENCIES
%endif
@@ -43,7 +43,7 @@ APPLICATION_DESCRIPTION
rm -rf %{buildroot}
install -d -m 755 %{buildroot}APPLICATION_DIRECTORY
cp -r %{_sourcedir}APPLICATION_DIRECTORY/* %{buildroot}APPLICATION_DIRECTORY
-%if "xAPPLICATION_LICENSE_FILE" != x
+%if "xAPPLICATION_LICENSE_FILE" != "x"
%define license_install_file %{_defaultlicensedir}/%{name}-%{version}/%{basename:APPLICATION_LICENSE_FILE}
install -d -m 755 "%{buildroot}%{dirname:%{license_install_file}}"
install -m 644 "APPLICATION_LICENSE_FILE" "%{buildroot}%{license_install_file}"
@@ -53,12 +53,12 @@ cp -r %{_sourcedir}APPLICATION_DIRECTORY/* %{buildroot}APPLICATION_DIRECTORY
comm -23 %{app_filelist} %{filesystem_filelist} > %{package_filelist}
sed -i -e 's/.*/%dir "&"/' %{package_filelist}
(cd %{buildroot} && find . -not -type d) | sed -e 's/^\.//' -e 's/.*/"&"/' >> %{package_filelist}
-%if "xAPPLICATION_LICENSE_FILE" != x
+%if "xAPPLICATION_LICENSE_FILE" != "x"
sed -i -e 's|"%{license_install_file}"||' -e '/^$/d' %{package_filelist}
%endif
%files -f %{package_filelist}
-%if "xAPPLICATION_LICENSE_FILE" != x
+%if "xAPPLICATION_LICENSE_FILE" != "x"
%license "%{license_install_file}"
%endif
From fe5cccc1ec76a5c29b1f55af311823f84483395b Mon Sep 17 00:00:00 2001
From: Bradford Wetmore
Date: Wed, 2 Dec 2020 04:14:28 +0000
Subject: [PATCH 011/504] 8254631: Better support ALPN byte wire values in
SunJSSE
Reviewed-by: xuelei, dfuchs
---
.../classes/javax/net/ssl/SSLEngine.java | 42 +++
.../classes/javax/net/ssl/SSLParameters.java | 23 +-
.../classes/javax/net/ssl/SSLSocket.java | 43 ++-
.../sun/security/ssl/AlpnExtension.java | 37 ++-
.../share/conf/security/java.security | 10 +
.../sun/security/ssl/ALPN/AlpnGreaseTest.java | 306 ++++++++++++++++++
6 files changed, 450 insertions(+), 11 deletions(-)
create mode 100644 test/jdk/sun/security/ssl/ALPN/AlpnGreaseTest.java
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 c81e033dcefb7..812cecf867213 100644
--- a/src/java.base/share/classes/javax/net/ssl/SSLEngine.java
+++ b/src/java.base/share/classes/javax/net/ssl/SSLEngine.java
@@ -336,6 +336,48 @@
* started, an {@code SSLEngine} can not switch between client and server
* modes, even when performing renegotiations.
*
+ * The ApplicationProtocol {@code String} values returned by the methods
+ * in this class are in the network byte representation sent by the peer.
+ * The bytes could be directly compared, or converted to its Unicode
+ * {code String} format for comparison.
+ *
+ *
+ * String networkString = sslEngine.getHandshakeApplicationProtocol();
+ * byte[] bytes = networkString.getBytes(StandardCharsets.ISO_8859_1);
+ *
+ * //
+ * // Match using bytes:
+ * //
+ * // "http/1.1" (7-bit ASCII values same in UTF-8)
+ * // MEETEI MAYEK LETTERS "HUK UN I" (Unicode 0xabcd->0xabcf)
+ * //
+ * String HTTP1_1 = "http/1.1";
+ * byte[] HTTP1_1_BYTES = HTTP1_1.getBytes(StandardCharsets.UTF_8);
+ *
+ * byte[] HUK_UN_I_BYTES = new byte[] {
+ * (byte) 0xab, (byte) 0xcd,
+ * (byte) 0xab, (byte) 0xce,
+ * (byte) 0xab, (byte) 0xcf};
+ *
+ * if ((Arrays.compare(bytes, HTTP1_1_BYTES) == 0 )
+ * || Arrays.compare(bytes, HUK_UN_I_BYTES) == 0) {
+ * ...
+ * }
+ *
+ * //
+ * // Alternatively match using string.equals() if we know the ALPN value
+ * // was encoded from a {@code String} using a certain character set,
+ * // for example {@code UTF-8}. The ALPN value must first be properly
+ * // decoded to a Unicode {@code String} before use.
+ * //
+ * String unicodeString = new String(bytes, StandardCharsets.UTF_8);
+ * if (unicodeString.equals(HTTP1_1)
+ * || unicodeString.equals("\u005cuabcd\u005cuabce\u005cuabcf")) {
+ * ...
+ * }
+ *
+ *
+ *
* Applications might choose to process delegated tasks in different
* threads. When an {@code SSLEngine}
* is created, the current {@link java.security.AccessControlContext}
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 5df0d7becdd9c..04a50686064a1 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, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -646,6 +646,27 @@ public String[] getApplicationProtocols() {
* requested by the peer, the underlying protocol will determine what
* action to take. (For example, ALPN will send a
* {@code "no_application_protocol"} alert and terminate the connection.)
+ *
+ * The {@code String} values must be presented using the network
+ * byte representation expected by the peer. For example, if an ALPN
+ * {@code String} should be exchanged using {@code UTF-8}, the
+ * {@code String} should be converted to its {@code byte[]} representation
+ * and stored as a byte-oriented {@code String} before calling this method.
+ *
+ *
+ * // MEETEI MAYEK LETTERS HUK UN I (Unicode 0xabcd->0xabcf): 2 bytes
+ * byte[] bytes = "\u005cuabcd\u005cuabce\u005cuabcf"
+ * .getBytes(StandardCharsets.UTF_8);
+ * String HUK_UN_I = new String(bytes, StandardCharsets.ISO_8859_1);
+ *
+ * // 0x00-0xFF: 1 byte
+ * String rfc7301Grease8F = "\u005c008F\u005c008F";
+ *
+ * SSLParameters p = sslSocket.getSSLParameters();
+ * p.setApplicationProtocols(new String[] {
+ * "h2", "http/1.1", rfc7301Grease8F, HUK_UN_I});
+ * sslSocket.setSSLParameters(p);
+ *
*
* @implSpec
* This method will make a copy of the {@code protocols} array.
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 7271f3434b0b7..7f44a4fe6c530 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, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -130,6 +130,47 @@
* socket can not switch between client and server modes, even when
* performing renegotiations.
*
+ * The ApplicationProtocol {@code String} values returned by the methods
+ * in this class are in the network byte representation sent by the peer.
+ * The bytes could be directly compared, or converted to its Unicode
+ * {code String} format for comparison.
+ *
+ *
+ * String networkString = sslSocket.getHandshakeApplicationProtocol();
+ * byte[] bytes = networkString.getBytes(StandardCharsets.ISO_8859_1);
+ *
+ * //
+ * // Match using bytes:
+ * //
+ * // "http/1.1" (7-bit ASCII values same in UTF-8)
+ * // MEETEI MAYEK LETTERS "HUK UN I" (Unicode 0xabcd->0xabcf)
+ * //
+ * String HTTP1_1 = "http/1.1";
+ * byte[] HTTP1_1_BYTES = HTTP1_1.getBytes(StandardCharsets.UTF_8);
+ *
+ * byte[] HUK_UN_I_BYTES = new byte[] {
+ * (byte) 0xab, (byte) 0xcd,
+ * (byte) 0xab, (byte) 0xce,
+ * (byte) 0xab, (byte) 0xcf};
+ *
+ * if ((Arrays.compare(bytes, HTTP1_1_BYTES) == 0 )
+ * || Arrays.compare(bytes, HUK_UN_I_BYTES) == 0) {
+ * ...
+ * }
+ *
+ * //
+ * // Alternatively match using string.equals() if we know the ALPN value
+ * // was encoded from a {@code String} using a certain character set,
+ * // for example {@code UTF-8}. The ALPN value must first be properly
+ * // decoded to a Unicode {@code String} before use.
+ * //
+ * String unicodeString = new String(bytes, StandardCharsets.UTF_8);
+ * if (unicodeString.equals(HTTP1_1)
+ * || unicodeString.equals("\u005cuabcd\u005cuabce\u005cuabcf")) {
+ * ...
+ * }
+ *
+ *
* @apiNote
* When the connection is no longer needed, the client and server
* applications should each close both sides of their respective connection.
diff --git a/src/java.base/share/classes/sun/security/ssl/AlpnExtension.java b/src/java.base/share/classes/sun/security/ssl/AlpnExtension.java
index fae54d5b6532d..b2448b023f468 100644
--- a/src/java.base/share/classes/sun/security/ssl/AlpnExtension.java
+++ b/src/java.base/share/classes/sun/security/ssl/AlpnExtension.java
@@ -27,7 +27,10 @@
import java.io.IOException;
import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
+import java.nio.charset.Charset;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.Security;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
@@ -59,6 +62,20 @@ final class AlpnExtension {
static final SSLStringizer alpnStringizer = new AlpnStringizer();
+ // Encoding Charset to convert between String and byte[]
+ static final Charset alpnCharset;
+
+ static {
+ String alpnCharsetString = AccessController.doPrivileged(
+ (PrivilegedAction) ()
+ -> Security.getProperty("jdk.tls.alpnCharset"));
+ if ((alpnCharsetString == null)
+ || (alpnCharsetString.length() == 0)) {
+ alpnCharsetString = "ISO_8859_1";
+ }
+ alpnCharset = Charset.forName(alpnCharsetString);
+ }
+
/**
* The "application_layer_protocol_negotiation" extension.
*
@@ -101,7 +118,7 @@ private AlpnSpec(HandshakeContext hc,
"extension: empty application protocol name"));
}
- String appProtocol = new String(bytes, StandardCharsets.UTF_8);
+ String appProtocol = new String(bytes, alpnCharset);
protocolNames.add(appProtocol);
}
@@ -168,10 +185,10 @@ public byte[] produce(ConnectionContext context,
return null;
}
- // Produce the extension.
+ // Produce the extension: first find the overall length
int listLength = 0; // ProtocolNameList length
for (String ap : laps) {
- int length = ap.getBytes(StandardCharsets.UTF_8).length;
+ int length = ap.getBytes(alpnCharset).length;
if (length == 0) {
// log the configuration problem
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
@@ -223,8 +240,10 @@ public byte[] produce(ConnectionContext context,
byte[] extData = new byte[listLength + 2];
ByteBuffer m = ByteBuffer.wrap(extData);
Record.putInt16(m, listLength);
+
+ // opaque ProtocolName<1..2^8-1>;
for (String ap : laps) {
- Record.putBytes8(m, ap.getBytes(StandardCharsets.UTF_8));
+ Record.putBytes8(m, ap.getBytes(alpnCharset));
}
// Update the context.
@@ -414,14 +433,14 @@ public byte[] produce(ConnectionContext context,
}
// opaque ProtocolName<1..2^8-1>, RFC 7301.
- int listLen = shc.applicationProtocol.length() + 1;
- // 1: length byte
+ byte[] bytes = shc.applicationProtocol.getBytes(alpnCharset);
+ int listLen = bytes.length + 1; // 1: length byte
+
// ProtocolName protocol_name_list<2..2^16-1>, RFC 7301.
byte[] extData = new byte[listLen + 2]; // 2: list length
ByteBuffer m = ByteBuffer.wrap(extData);
Record.putInt16(m, listLen);
- Record.putBytes8(m,
- shc.applicationProtocol.getBytes(StandardCharsets.UTF_8));
+ Record.putBytes8(m, bytes);
// Update the context.
shc.conContext.applicationProtocol = shc.applicationProtocol;
diff --git a/src/java.base/share/conf/security/java.security b/src/java.base/share/conf/security/java.security
index 63a621be9c89c..844178231912f 100644
--- a/src/java.base/share/conf/security/java.security
+++ b/src/java.base/share/conf/security/java.security
@@ -1309,3 +1309,13 @@ jdk.io.permissionsUseCanonicalPath=false
# System value prevails. The default value of the property is "false".
#
#jdk.security.allowNonCaAnchor=true
+
+#
+# The default Character set name (java.nio.charset.Charset.forName())
+# for converting TLS ALPN values between byte arrays and Strings.
+# Prior versions of the JDK may use UTF-8 as the default charset. If
+# you experience interoperability issues, setting this property to UTF-8
+# may help.
+#
+# jdk.tls.alpnCharset=UTF-8
+jdk.tls.alpnCharset=ISO_8859_1
diff --git a/test/jdk/sun/security/ssl/ALPN/AlpnGreaseTest.java b/test/jdk/sun/security/ssl/ALPN/AlpnGreaseTest.java
new file mode 100644
index 0000000000000..d3c656043a266
--- /dev/null
+++ b/test/jdk/sun/security/ssl/ALPN/AlpnGreaseTest.java
@@ -0,0 +1,306 @@
+/*
+ * Copyright (c) 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.
+ */
+
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+
+/*
+ * @test
+ * @bug 8254631
+ * @summary Better support ALPN byte wire values in SunJSSE
+ * @library /javax/net/ssl/templates
+ * @run main/othervm AlpnGreaseTest
+ */
+import javax.net.ssl.*;
+import javax.net.ssl.SSLEngineResult.HandshakeStatus;
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+
+/**
+ * A SSLEngine usage example which simplifies the presentation
+ * by removing the I/O and multi-threading concerns.
+ *
+ * The test creates two SSLEngines, simulating a client and server.
+ * The "transport" layer consists two byte buffers: think of them
+ * as directly connected pipes.
+ *
+ * Note, this is a *very* simple example: real code will be much more
+ * involved. For example, different threading and I/O models could be
+ * used, transport mechanisms could close unexpectedly, and so on.
+ *
+ * When this application runs, notice that several messages
+ * (wrap/unwrap) pass before any application data is consumed or
+ * produced.
+ */
+public class AlpnGreaseTest implements SSLContextTemplate {
+
+ private final SSLEngine clientEngine; // client Engine
+ private final ByteBuffer clientOut; // write side of clientEngine
+ private final ByteBuffer clientIn; // read side of clientEngine
+
+ private final SSLEngine serverEngine; // server Engine
+ private final ByteBuffer serverOut; // write side of serverEngine
+ private final ByteBuffer serverIn; // read side of serverEngine
+
+ // For data transport, this example uses local ByteBuffers. This
+ // isn't really useful, but the purpose of this example is to show
+ // SSLEngine concepts, not how to do network transport.
+ private final ByteBuffer cTOs; // "reliable" transport client->server
+ private final ByteBuffer sTOc; // "reliable" transport server->client
+
+ // These are the various 8-bit char values that could be sent as GREASE
+ // values. We'll just make one big String here to make it easy to check
+ // that the right values are being output.
+ private static final byte[] greaseBytes = new byte[] {
+ (byte) 0x0A, (byte) 0x1A, (byte) 0x2A, (byte) 0x3A,
+ (byte) 0x4A, (byte) 0x5A, (byte) 0x6A, (byte) 0x7A,
+ (byte) 0x8A, (byte) 0x9A, (byte) 0xAA, (byte) 0xBA,
+ (byte) 0xCA, (byte) 0xDA, (byte) 0xEA, (byte) 0xFA
+ };
+
+ private static final String greaseString =
+ new String(greaseBytes, StandardCharsets.ISO_8859_1);
+
+ private static void findGreaseInClientHello(byte[] bytes) throws Exception {
+ for (int i = 0; i < bytes.length - greaseBytes.length; i++) {
+ if (Arrays.equals(bytes, i, i + greaseBytes.length,
+ greaseBytes, 0, greaseBytes.length)) {
+ System.out.println("Found greaseBytes in ClientHello at: " + i);
+ return;
+ }
+ }
+ throw new Exception("Couldn't find greaseBytes");
+ }
+
+ private AlpnGreaseTest() throws Exception {
+ serverEngine = configureServerEngine(
+ createServerSSLContext().createSSLEngine());
+
+ clientEngine = configureClientEngine(
+ createClientSSLContext().createSSLEngine());
+
+ // We'll assume the buffer sizes are the same
+ // between client and server.
+ SSLSession session = clientEngine.getSession();
+ int appBufferMax = session.getApplicationBufferSize();
+ int netBufferMax = session.getPacketBufferSize();
+
+ // We'll make the input buffers a bit bigger than the max needed
+ // size, so that unwrap()s following a successful data transfer
+ // won't generate BUFFER_OVERFLOWS.
+ //
+ // We'll use a mix of direct and indirect ByteBuffers for
+ // tutorial purposes only. In reality, only use direct
+ // ByteBuffers when they give a clear performance enhancement.
+ clientIn = ByteBuffer.allocate(appBufferMax + 50);
+ serverIn = ByteBuffer.allocate(appBufferMax + 50);
+
+ cTOs = ByteBuffer.allocateDirect(netBufferMax);
+ sTOc = ByteBuffer.allocateDirect(netBufferMax);
+
+ clientOut = ByteBuffer.wrap("Hi Server, I'm Client".getBytes());
+ serverOut = ByteBuffer.wrap("Hello Client, I'm Server".getBytes());
+ }
+
+ //
+ // Protected methods could be used to customize the test case.
+ //
+
+ /*
+ * Configure the client side engine.
+ */
+ protected SSLEngine configureClientEngine(SSLEngine clientEngine) {
+ clientEngine.setUseClientMode(true);
+
+ // Get/set parameters if needed
+ SSLParameters paramsClient = clientEngine.getSSLParameters();
+ paramsClient.setApplicationProtocols(new String[] { greaseString });
+
+ clientEngine.setSSLParameters(paramsClient);
+
+ return clientEngine;
+ }
+
+ /*
+ * Configure the server side engine.
+ */
+ protected SSLEngine configureServerEngine(SSLEngine serverEngine) {
+ serverEngine.setUseClientMode(false);
+ serverEngine.setNeedClientAuth(true);
+
+ // Get/set parameters if needed
+ //
+ SSLParameters paramsServer = serverEngine.getSSLParameters();
+ paramsServer.setApplicationProtocols(new String[] { greaseString });
+ serverEngine.setSSLParameters(paramsServer);
+
+ return serverEngine;
+ }
+
+ public static void main(String[] args) throws Exception {
+ new AlpnGreaseTest().runTest();
+ }
+
+ //
+ // Private methods that used to build the common part of the test.
+ //
+
+ private void runTest() throws Exception {
+ SSLEngineResult clientResult;
+ SSLEngineResult serverResult;
+
+ boolean dataDone = false;
+ boolean firstClientWrap = true;
+ while (isOpen(clientEngine) || isOpen(serverEngine)) {
+ log("=================");
+
+ // client wrap
+ log("---Client Wrap---");
+ clientResult = clientEngine.wrap(clientOut, cTOs);
+ logEngineStatus(clientEngine, clientResult);
+ runDelegatedTasks(clientEngine);
+
+ if (firstClientWrap) {
+ firstClientWrap = false;
+ byte[] bytes = new byte[cTOs.position()];
+ cTOs.duplicate().flip().get(bytes);
+ findGreaseInClientHello(bytes);
+ }
+
+ // server wrap
+ log("---Server Wrap---");
+ serverResult = serverEngine.wrap(serverOut, sTOc);
+ logEngineStatus(serverEngine, serverResult);
+ runDelegatedTasks(serverEngine);
+
+ cTOs.flip();
+ sTOc.flip();
+
+ // client unwrap
+ log("---Client Unwrap---");
+ clientResult = clientEngine.unwrap(sTOc, clientIn);
+ logEngineStatus(clientEngine, clientResult);
+ runDelegatedTasks(clientEngine);
+
+ // server unwrap
+ log("---Server Unwrap---");
+ serverResult = serverEngine.unwrap(cTOs, serverIn);
+ logEngineStatus(serverEngine, serverResult);
+ runDelegatedTasks(serverEngine);
+
+ cTOs.compact();
+ sTOc.compact();
+
+ // After we've transferred all application data between the client
+ // and server, we close the clientEngine's outbound stream.
+ // This generates a close_notify handshake message, which the
+ // server engine receives and responds by closing itself.
+ if (!dataDone && (clientOut.limit() == serverIn.position()) &&
+ (serverOut.limit() == clientIn.position())) {
+
+ // Check ALPN Value
+ String alpnServerValue = serverEngine.getApplicationProtocol();
+ String alpnClientValue = clientEngine.getApplicationProtocol();
+
+ if (!alpnServerValue.equals(greaseString)
+ || !alpnClientValue.equals(greaseString)) {
+ throw new Exception("greaseString didn't match");
+ }
+
+ // A sanity check to ensure we got what was sent.
+ checkTransfer(serverOut, clientIn);
+ checkTransfer(clientOut, serverIn);
+
+ log("\tClosing clientEngine's *OUTBOUND*...");
+ clientEngine.closeOutbound();
+ logEngineStatus(clientEngine);
+
+ dataDone = true;
+ log("\tClosing serverEngine's *OUTBOUND*...");
+ serverEngine.closeOutbound();
+ logEngineStatus(serverEngine);
+ }
+ }
+ }
+
+ private static boolean isOpen(SSLEngine engine) {
+ return (!engine.isOutboundDone() || !engine.isInboundDone());
+ }
+
+ private static void logEngineStatus(SSLEngine engine) {
+ log("\tCurrent HS State: " + engine.getHandshakeStatus());
+ log("\tisInboundDone() : " + engine.isInboundDone());
+ log("\tisOutboundDone(): " + engine.isOutboundDone());
+ }
+
+ private static void logEngineStatus(
+ SSLEngine engine, SSLEngineResult result) {
+ log("\tResult Status : " + result.getStatus());
+ log("\tResult HS Status : " + result.getHandshakeStatus());
+ log("\tEngine HS Status : " + engine.getHandshakeStatus());
+ log("\tisInboundDone() : " + engine.isInboundDone());
+ log("\tisOutboundDone() : " + engine.isOutboundDone());
+ log("\tMore Result : " + result);
+ }
+
+ private static void log(String message) {
+ System.err.println(message);
+ }
+
+ // If the result indicates that we have outstanding tasks to do,
+ // go ahead and run them in this thread.
+ private static void runDelegatedTasks(SSLEngine engine) throws Exception {
+ if (engine.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
+ Runnable runnable;
+ while ((runnable = engine.getDelegatedTask()) != null) {
+ log(" running delegated task...");
+ runnable.run();
+ }
+ HandshakeStatus hsStatus = engine.getHandshakeStatus();
+ if (hsStatus == HandshakeStatus.NEED_TASK) {
+ throw new Exception(
+ "handshake shouldn't need additional tasks");
+ }
+ logEngineStatus(engine);
+ }
+ }
+
+ // Simple check to make sure everything came across as expected.
+ private static void checkTransfer(ByteBuffer a, ByteBuffer b)
+ throws Exception {
+ a.flip();
+ b.flip();
+
+ if (!a.equals(b)) {
+ throw new Exception("Data didn't transfer cleanly");
+ } else {
+ log("\tData transferred cleanly");
+ }
+
+ a.position(a.limit());
+ b.position(b.limit());
+ a.limit(a.capacity());
+ b.limit(b.capacity());
+ }
+}
From f2a0988a4aa1270f49280eb465e468bc002b3a1f Mon Sep 17 00:00:00 2001
From: Jie Fu
Date: Wed, 2 Dec 2020 06:49:57 +0000
Subject: [PATCH 012/504] 8257228: G1: SIGFPE in
G1ConcurrentRefine::create(int*) due to buffers_to_cards overflow
Reviewed-by: kbarrett, tschatzl
---
.../share/gc/g1/g1ConcurrentRefine.cpp | 25 +++++++---
.../gc/g1/TestBuffersToCardsOverflow.java | 46 +++++++++++++++++++
2 files changed, 64 insertions(+), 7 deletions(-)
create mode 100644 test/hotspot/jtreg/gc/g1/TestBuffersToCardsOverflow.java
diff --git a/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp b/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp
index bb9731f8b4162..7d8076f3cf3c6 100644
--- a/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp
+++ b/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp
@@ -34,6 +34,7 @@
#include "runtime/java.hpp"
#include "runtime/thread.hpp"
#include "utilities/debug.hpp"
+#include "utilities/formatBuffer.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/pair.hpp"
#include
@@ -183,8 +184,16 @@ STATIC_ASSERT(max_yellow_zone <= max_red_zone);
// For logging zone values, ensuring consistency of level and tags.
#define LOG_ZONES(...) log_debug( CTRL_TAGS )(__VA_ARGS__)
-static size_t buffers_to_cards(size_t value) {
- return value * G1UpdateBufferSize;
+// Convert configuration values in units of buffers to number of cards.
+static size_t configuration_buffers_to_cards(size_t value, const char* value_name) {
+ if (value == 0) return 0;
+ size_t res = value * G1UpdateBufferSize;
+
+ if (res / value != G1UpdateBufferSize) { // Check overflow
+ vm_exit_during_initialization(err_msg("configuration_buffers_to_cards: "
+ "(%s = " SIZE_FORMAT ") * (G1UpdateBufferSize = " SIZE_FORMAT ") overflow!", value_name, value, G1UpdateBufferSize));
+ }
+ return res;
}
// Package for pair of refinement thread activation and deactivation
@@ -206,7 +215,7 @@ static Thresholds calc_thresholds(size_t green_zone,
// doing any processing, as that might lead to significantly more
// than green_zone buffers to be processed during pause. So limit
// to an extra half buffer per pause-time processing thread.
- step = MIN2(step, buffers_to_cards(ParallelGCThreads) / 2.0);
+ step = MIN2(step, configuration_buffers_to_cards(ParallelGCThreads, "ParallelGCThreads") / 2.0);
}
size_t activate_offset = static_cast(ceil(step * (worker_id + 1)));
size_t deactivate_offset = static_cast(floor(step * worker_id));
@@ -232,7 +241,7 @@ jint G1ConcurrentRefine::initialize() {
}
static size_t calc_min_yellow_zone_size() {
- size_t step = buffers_to_cards(G1ConcRefinementThresholdStep);
+ size_t step = configuration_buffers_to_cards(G1ConcRefinementThresholdStep, "G1ConcRefinementThresholdStep");
uint n_workers = G1ConcurrentRefine::max_num_threads();
if ((max_yellow_zone / step) < n_workers) {
return max_yellow_zone;
@@ -243,15 +252,17 @@ static size_t calc_min_yellow_zone_size() {
static size_t calc_init_green_zone() {
size_t green = G1ConcRefinementGreenZone;
+ const char* name = "G1ConcRefinementGreenZone";
if (FLAG_IS_DEFAULT(G1ConcRefinementGreenZone)) {
green = ParallelGCThreads;
+ name = "ParallelGCThreads";
}
- green = buffers_to_cards(green);
+ green = configuration_buffers_to_cards(green, name);
return MIN2(green, max_green_zone);
}
static size_t calc_init_yellow_zone(size_t green, size_t min_size) {
- size_t config = buffers_to_cards(G1ConcRefinementYellowZone);
+ size_t config = configuration_buffers_to_cards(G1ConcRefinementYellowZone, "G1ConcRefinementYellowZone");
size_t size = 0;
if (FLAG_IS_DEFAULT(G1ConcRefinementYellowZone)) {
size = green * 2;
@@ -266,7 +277,7 @@ static size_t calc_init_yellow_zone(size_t green, size_t min_size) {
static size_t calc_init_red_zone(size_t green, size_t yellow) {
size_t size = yellow - green;
if (!FLAG_IS_DEFAULT(G1ConcRefinementRedZone)) {
- size_t config = buffers_to_cards(G1ConcRefinementRedZone);
+ size_t config = configuration_buffers_to_cards(G1ConcRefinementRedZone, "G1ConcRefinementRedZone");
if (yellow < config) {
size = MAX2(size, config - yellow);
}
diff --git a/test/hotspot/jtreg/gc/g1/TestBuffersToCardsOverflow.java b/test/hotspot/jtreg/gc/g1/TestBuffersToCardsOverflow.java
new file mode 100644
index 0000000000000..dd8a1aade20d3
--- /dev/null
+++ b/test/hotspot/jtreg/gc/g1/TestBuffersToCardsOverflow.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2020 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 8257228
+ * @library /test/lib
+ * @requires vm.bits == 64
+ * @build gc.g1.TestBuffersToCardsOverflow jdk.test.lib.process.*
+ * @run main gc.g1.TestBuffersToCardsOverflow
+ */
+
+package gc.g1;
+
+import jdk.test.lib.process.ProcessTools;
+
+public class TestBuffersToCardsOverflow {
+ public static void main(String... args) throws Exception {
+ ProcessTools.executeTestJava("-XX:G1ConcRefinementThresholdStep=16G",
+ "-XX:G1UpdateBufferSize=1G")
+ .outputTo(System.out)
+ .errorTo(System.out)
+ .stdoutShouldNotContain("SIGFPE")
+ .stdoutShouldNotContain("hs_err");
+ }
+}
From 282cb325b19ebc0cc1ef8d40f768c49de8033388 Mon Sep 17 00:00:00 2001
From: Sergey Bylokhov
Date: Wed, 2 Dec 2020 06:51:53 +0000
Subject: [PATCH 013/504] 8005970: Mouse cursor is default cursor over
TextArea's scrollbar
Reviewed-by: kizune
---
test/jdk/ProblemList.txt | 1 -
.../MouseOverScrollbarWhenTyping/Test.java | 4 +-
.../MouseOverScrollbarWhenTyping/Test1.java | 409 ------------------
3 files changed, 2 insertions(+), 412 deletions(-)
delete mode 100644 test/jdk/java/awt/TextArea/MouseOverScrollbarWhenTyping/Test1.java
diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt
index 96f90907d28eb..9dc6a663dd882 100644
--- a/test/jdk/ProblemList.txt
+++ b/test/jdk/ProblemList.txt
@@ -864,7 +864,6 @@ java/awt/event/MouseEvent/SpuriousExitEnter/SpuriousExitEnter_2.java 7131438,802
java/awt/Modal/WsDisabledStyle/CloseBlocker/CloseBlocker.java 7187741 linux-all,macosx-all
java/awt/Component/UpdatingBootTime/UpdatingBootTime.html 7194219 linux-all
java/awt/xembed/server/TestXEmbedServerJava.java 8001150,8004031 generic-all
-java/awt/TextArea/MouseOverScrollbarWhenTyping/Test1.java 8005970 macosx-all,windows-all
javax/swing/JFileChooser/6698013/bug6698013.java 8024419 macosx-all
javax/swing/JColorChooser/8065098/bug8065098.java 8065647 macosx-all
java/awt/Modal/PrintDialogsTest/PrintDialogsTest.java 8068378 generic-all
diff --git a/test/jdk/java/awt/TextArea/MouseOverScrollbarWhenTyping/Test.java b/test/jdk/java/awt/TextArea/MouseOverScrollbarWhenTyping/Test.java
index c785370d5a9e4..947d02d8a1254 100644
--- a/test/jdk/java/awt/TextArea/MouseOverScrollbarWhenTyping/Test.java
+++ b/test/jdk/java/awt/TextArea/MouseOverScrollbarWhenTyping/Test.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -51,7 +51,7 @@ private static void init() {
f.setLayout( new BorderLayout () );
f.add( new TextArea( text ) );
f.setSize(400, 300);
-
+ f.setLocationRelativeTo(null);
f.setVisible(true);
String[] instructions = {
diff --git a/test/jdk/java/awt/TextArea/MouseOverScrollbarWhenTyping/Test1.java b/test/jdk/java/awt/TextArea/MouseOverScrollbarWhenTyping/Test1.java
deleted file mode 100644
index 898b865d50d79..0000000000000
--- a/test/jdk/java/awt/TextArea/MouseOverScrollbarWhenTyping/Test1.java
+++ /dev/null
@@ -1,409 +0,0 @@
-/*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
- * 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 6431076
- @summary Mouse cursor must remain DEFAULT over scrollbar when text is typed
- @author Andrei Dmitriev: area=TextArea
- @run main/manual Test1
-*/
-
-import java.awt.*;
-import java.awt.event.*;
-
-public class Test1 {
- private static void init() {
- Frame f = new Frame("Test1 for cursor");
- final int dim = 100;
- String line = "";
- for( int i=0; i 0 )
- {
- //if longer than max then chop off first max chars to print
- if( remainingStr.length() >= maxStringLength )
- {
- //Try to chop on a word boundary
- int posOfSpace = remainingStr.
- lastIndexOf( ' ', maxStringLength - 1 );
-
- if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
-
- printStr = remainingStr.substring( 0, posOfSpace + 1 );
- remainingStr = remainingStr.substring( posOfSpace + 1 );
- }
- //else just print
- else
- {
- printStr = remainingStr;
- remainingStr = "";
- }
-
- instructionsText.append( printStr + "\n" );
-
- }// while
-
- }// for
-
- }//printInstructions()
-
- //DO NOT call this directly, go through Sysout
- public void displayMessage( String messageIn )
- {
- messageText.append( messageIn + "\n" );
- System.out.println(messageIn);
- }
-
- //catch presses of the passed and failed buttons.
- //simply call the standard pass() or fail() static methods of
- //ManualMainTest
- public void actionPerformed( ActionEvent e )
- {
- if( e.getActionCommand() == "pass" )
- {
- Test1.pass();
- }
- else
- {
- Test1.fail();
- }
- }
-
-}// TestDialog class
From 9de283b891d48326e957d7448c5de96fab3c8b9a Mon Sep 17 00:00:00 2001
From: Stefan Johansson
Date: Wed, 2 Dec 2020 08:53:54 +0000
Subject: [PATCH 014/504] 8257505: nsk/share/test/StressOptions stressTime is
scaled in getter but not when printed
Reviewed-by: kbarrett, dholmes
---
.../jtreg/vmTestbase/nsk/share/test/StressOptions.java | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/share/test/StressOptions.java b/test/hotspot/jtreg/vmTestbase/nsk/share/test/StressOptions.java
index fab4e07ed7744..c2ca9b5142914 100644
--- a/test/hotspot/jtreg/vmTestbase/nsk/share/test/StressOptions.java
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/test/StressOptions.java
@@ -200,10 +200,10 @@ public void parseCommandLine(String[] args) {
* @param out output stream
*/
public void printInfo(PrintStream out) {
- out.println("Stress time: " + time + " seconds");
- out.println("Stress iterations factor: " + iterationsFactor);
- out.println("Stress threads factor: " + threadsFactor);
- out.println("Stress runs factor: " + runsFactor);
+ out.println("Stress time: " + getTime() + " seconds");
+ out.println("Stress iterations factor: " + getIterationsFactor());
+ out.println("Stress threads factor: " + getThreadsFactor());
+ out.println("Stress runs factor: " + getRunsFactor());
}
private void error(String msg) {
From fb139cff1a6ddf7659908053d5a0a6ae7563e725 Mon Sep 17 00:00:00 2001
From: Yasumasa Suenaga
Date: Wed, 2 Dec 2020 09:06:02 +0000
Subject: [PATCH 015/504] 8257467: [TESTBUG] -Wdeprecated-declarations is
reported at sigset() in exesigtest.c
Reviewed-by: dholmes, stuefe
---
test/hotspot/jtreg/runtime/signal/exesigtest.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/test/hotspot/jtreg/runtime/signal/exesigtest.c b/test/hotspot/jtreg/runtime/signal/exesigtest.c
index 02dd76255992e..7a27f1f6c8004 100644
--- a/test/hotspot/jtreg/runtime/signal/exesigtest.c
+++ b/test/hotspot/jtreg/runtime/signal/exesigtest.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -242,7 +242,14 @@ void setSignalHandler()
} // end - dealing with sigaction
else if (!strcmp(mode, "sigset"))
{
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#endif
sigset(signal_num, handler);
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
} // end dealing with sigset
printf("%s: signal handler using function '%s' has been set\n", signal_name, mode);
}
From 3e3745c2dabf3e9d5f326362a6688a701b7dcf21 Mon Sep 17 00:00:00 2001
From: Yasumasa Suenaga
Date: Wed, 2 Dec 2020 09:19:24 +0000
Subject: [PATCH 016/504] 8256008: UL does not report anything if disk writing
fails
Reviewed-by: stuefe
---
src/hotspot/share/logging/logFileOutput.cpp | 18 ++++---
.../share/logging/logFileStreamOutput.cpp | 48 +++++++++++++++----
.../share/logging/logFileStreamOutput.hpp | 7 ++-
3 files changed, 54 insertions(+), 19 deletions(-)
diff --git a/src/hotspot/share/logging/logFileOutput.cpp b/src/hotspot/share/logging/logFileOutput.cpp
index 81a42822b45fe..40a499c57b921 100644
--- a/src/hotspot/share/logging/logFileOutput.cpp
+++ b/src/hotspot/share/logging/logFileOutput.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -292,10 +292,12 @@ int LogFileOutput::write(const LogDecorations& decorations, const char* msg) {
_rotation_semaphore.wait();
int written = LogFileStreamOutput::write(decorations, msg);
- _current_size += written;
+ if (written > 0) {
+ _current_size += written;
- if (should_rotate()) {
- rotate();
+ if (should_rotate()) {
+ rotate();
+ }
}
_rotation_semaphore.signal();
@@ -310,10 +312,12 @@ int LogFileOutput::write(LogMessageBuffer::Iterator msg_iterator) {
_rotation_semaphore.wait();
int written = LogFileStreamOutput::write(msg_iterator);
- _current_size += written;
+ if (written > 0) {
+ _current_size += written;
- if (should_rotate()) {
- rotate();
+ if (should_rotate()) {
+ rotate();
+ }
}
_rotation_semaphore.signal();
diff --git a/src/hotspot/share/logging/logFileStreamOutput.cpp b/src/hotspot/share/logging/logFileStreamOutput.cpp
index 78f5befbf55b0..c331c7c9c6de7 100644
--- a/src/hotspot/share/logging/logFileStreamOutput.cpp
+++ b/src/hotspot/share/logging/logFileStreamOutput.cpp
@@ -28,6 +28,7 @@
#include "logging/logFileStreamOutput.hpp"
#include "logging/logMessageBuffer.hpp"
#include "memory/allocation.inline.hpp"
+#include "utilities/defaultStream.hpp"
static bool initialized;
static union {
@@ -86,19 +87,47 @@ class FileLocker : public StackObj {
}
};
+bool LogFileStreamOutput::flush() {
+ bool result = true;
+ if (fflush(_stream) != 0) {
+ if (!_write_error_is_shown) {
+ jio_fprintf(defaultStream::error_stream(),
+ "Could not flush log: %s (%s (%d))\n", name(), os::strerror(errno), errno);
+ jio_fprintf(_stream, "\nERROR: Could not flush log (%d)\n", errno);
+ _write_error_is_shown = true;
+ }
+ result = false;
+ }
+ return result;
+}
+
+#define WRITE_LOG_WITH_RESULT_CHECK(op, total) \
+{ \
+ int result = op; \
+ if (result < 0) { \
+ if (!_write_error_is_shown) { \
+ jio_fprintf(defaultStream::error_stream(), \
+ "Could not write log: %s\n", name()); \
+ jio_fprintf(_stream, "\nERROR: Could not write log\n"); \
+ _write_error_is_shown = true; \
+ return -1; \
+ } \
+ } \
+ total += result; \
+}
+
int LogFileStreamOutput::write(const LogDecorations& decorations, const char* msg) {
const bool use_decorations = !_decorators.is_empty();
int written = 0;
FileLocker flocker(_stream);
if (use_decorations) {
- written += write_decorations(decorations);
- written += jio_fprintf(_stream, " ");
+ WRITE_LOG_WITH_RESULT_CHECK(write_decorations(decorations), written);
+ WRITE_LOG_WITH_RESULT_CHECK(jio_fprintf(_stream, " "), written);
}
- written += jio_fprintf(_stream, "%s\n", msg);
- fflush(_stream);
+ WRITE_LOG_WITH_RESULT_CHECK(jio_fprintf(_stream, "%s\n", msg), written);
- return written;
+ return flush() ? written : -1;
}
int LogFileStreamOutput::write(LogMessageBuffer::Iterator msg_iterator) {
@@ -108,12 +137,11 @@ int LogFileStreamOutput::write(LogMessageBuffer::Iterator msg_iterator) {
FileLocker flocker(_stream);
for (; !msg_iterator.is_at_end(); msg_iterator++) {
if (use_decorations) {
- written += write_decorations(msg_iterator.decorations());
- written += jio_fprintf(_stream, " ");
+ WRITE_LOG_WITH_RESULT_CHECK(write_decorations(msg_iterator.decorations()), written);
+ WRITE_LOG_WITH_RESULT_CHECK(jio_fprintf(_stream, " "), written);
}
- written += jio_fprintf(_stream, "%s\n", msg_iterator.message());
+ WRITE_LOG_WITH_RESULT_CHECK(jio_fprintf(_stream, "%s\n", msg_iterator.message()), written);
}
- fflush(_stream);
- return written;
+ return flush() ? written : -1;
}
diff --git a/src/hotspot/share/logging/logFileStreamOutput.hpp b/src/hotspot/share/logging/logFileStreamOutput.hpp
index a02c56f6d184c..c4a0db7355d2c 100644
--- a/src/hotspot/share/logging/logFileStreamOutput.hpp
+++ b/src/hotspot/share/logging/logFileStreamOutput.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -40,17 +40,20 @@ static LogFileStreamInitializer log_stream_initializer;
// Base class for all FileStream-based log outputs.
class LogFileStreamOutput : public LogOutput {
+ private:
+ bool _write_error_is_shown;
protected:
FILE* _stream;
size_t _decorator_padding[LogDecorators::Count];
- LogFileStreamOutput(FILE *stream) : _stream(stream) {
+ LogFileStreamOutput(FILE *stream) : _write_error_is_shown(false), _stream(stream) {
for (size_t i = 0; i < LogDecorators::Count; i++) {
_decorator_padding[i] = 0;
}
}
int write_decorations(const LogDecorations& decorations);
+ bool flush();
public:
virtual int write(const LogDecorations& decorations, const char* msg);
From 7e37c7c5441b9aceac31a7b8996f1d607877e0fa Mon Sep 17 00:00:00 2001
From: Doug Simon
Date: Wed, 2 Dec 2020 10:14:46 +0000
Subject: [PATCH 017/504] 8257471: fatal error: Fatal exception in JVMCI:
Exception during JVMCI compiler initialization
Reviewed-by: kvn, never
---
.../hotspot/HotSpotJVMCICompilerConfig.java | 29 ++++++++++--------
.../vm/ci/hotspot/HotSpotJVMCIRuntime.java | 30 ++++++++++++-------
.../jvmci/TestEnableJVMCIProduct.java | 6 +++-
3 files changed, 40 insertions(+), 25 deletions(-)
diff --git a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCICompilerConfig.java b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCICompilerConfig.java
index 245239443c9c3..9bfb3050b6b99 100644
--- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCICompilerConfig.java
+++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCICompilerConfig.java
@@ -48,14 +48,16 @@ final class HotSpotJVMCICompilerConfig {
private static class DummyCompilerFactory implements JVMCICompilerFactory, JVMCICompiler {
private final String reason;
+ private final HotSpotJVMCIRuntime runtime;
- DummyCompilerFactory(String reason) {
+ DummyCompilerFactory(String reason, HotSpotJVMCIRuntime runtime) {
this.reason = reason;
+ this.runtime = runtime;
}
@Override
public HotSpotCompilationRequestResult compileMethod(CompilationRequest request) {
- throw new JVMCIError("no JVMCI compiler selected: " + reason);
+ throw runtime.exitHotSpotWithMessage(1, "Cannot use JVMCI compiler: %s%n", reason);
}
@Override
@@ -64,7 +66,7 @@ public String getCompilerName() {
}
@Override
- public JVMCICompiler createCompiler(JVMCIRuntime runtime) {
+ public JVMCICompiler createCompiler(JVMCIRuntime rt) {
return this;
}
}
@@ -81,15 +83,16 @@ public JVMCICompiler createCompiler(JVMCIRuntime runtime) {
* @throws SecurityException if a security manager is present and it denies
* {@link JVMCIPermission} for any {@link JVMCIServiceLocator} loaded by this method
*/
- static JVMCICompilerFactory getCompilerFactory() {
+ static JVMCICompilerFactory getCompilerFactory(HotSpotJVMCIRuntime runtime) {
if (compilerFactory == null) {
JVMCICompilerFactory factory = null;
String compilerName = Option.Compiler.getString();
if (compilerName != null) {
+ String compPropertyName = Option.Compiler.getPropertyName();
if (compilerName.isEmpty()) {
- factory = new DummyCompilerFactory(" empty \"\" is specified");
+ factory = new DummyCompilerFactory("Value of " + compPropertyName + " is empty", runtime);
} else if (compilerName.equals("null")) {
- factory = new DummyCompilerFactory("\"null\" is specified");
+ factory = new DummyCompilerFactory("Value of " + compPropertyName + " is \"null\"", runtime);
} else {
for (JVMCICompilerFactory f : getJVMCICompilerFactories()) {
if (f.getCompilerName().equals(compilerName)) {
@@ -98,29 +101,29 @@ static JVMCICompilerFactory getCompilerFactory() {
}
if (factory == null) {
if (Services.IS_IN_NATIVE_IMAGE) {
- throw new JVMCIError("JVMCI compiler '%s' not found in JVMCI native library.%n" +
- "Use -XX:-UseJVMCINativeLibrary when specifying a JVMCI compiler available on a class path with %s.",
- compilerName, Option.Compiler.getPropertyName());
+ throw runtime.exitHotSpotWithMessage(1, "JVMCI compiler '%s' not found in JVMCI native library.%n" +
+ "Use -XX:-UseJVMCINativeLibrary when specifying a JVMCI compiler available on a class path with %s.%n",
+ compilerName, compPropertyName);
}
- throw new JVMCIError("JVMCI compiler '%s' not found", compilerName);
+ throw runtime.exitHotSpotWithMessage(1, "JVMCI compiler '%s' specified by %s not found%n", compilerName, compPropertyName);
}
}
} else {
// Auto select a single available compiler
- String reason = "default compiler is not found";
+ String reason = "No JVMCI compiler found";
for (JVMCICompilerFactory f : getJVMCICompilerFactories()) {
if (factory == null) {
openJVMCITo(f.getClass().getModule());
factory = f;
} else {
// Multiple factories seen - cancel auto selection
- reason = "multiple factories seen: \"" + factory.getCompilerName() + "\" and \"" + f.getCompilerName() + "\"";
+ reason = "Multiple JVMCI compilers found: \"" + factory.getCompilerName() + "\" and \"" + f.getCompilerName() + "\"";
factory = null;
break;
}
}
if (factory == null) {
- factory = new DummyCompilerFactory(reason);
+ factory = new DummyCompilerFactory(reason, runtime);
}
}
factory.onSelection();
diff --git a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java
index 530706f75b94f..23ec67eb89ec2 100644
--- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java
+++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java
@@ -63,7 +63,6 @@
import jdk.vm.ci.runtime.JVMCICompilerFactory;
import jdk.vm.ci.runtime.JVMCIRuntime;
import jdk.vm.ci.services.JVMCIServiceLocator;
-import jdk.vm.ci.services.Services;
/**
* HotSpot implementation of a JVMCI runtime.
@@ -380,9 +379,9 @@ static float stringSimiliarity(String str1, String str2) {
* Parses all system properties starting with {@value #JVMCI_OPTION_PROPERTY_PREFIX} and
* initializes the options based on their values.
*
- * @param compilerToVm
+ * @param runtime
*/
- static void parse(CompilerToVM compilerToVm) {
+ static void parse(HotSpotJVMCIRuntime runtime) {
Map savedProps = jdk.vm.ci.services.Services.getSavedProperties();
for (Map.Entry e : savedProps.entrySet()) {
String name = e.getKey();
@@ -405,9 +404,7 @@ static void parse(CompilerToVM compilerToVm) {
}
}
msg.format("%nError: A fatal exception has occurred. Program will exit.%n");
- byte[] msgBytes = msg.toString().getBytes();
- compilerToVm.writeDebugOutput(msgBytes, 0, msgBytes.length, true, true);
- compilerToVm.callSystemExit(1);
+ runtime.exitHotSpotWithMessage(1, msg.toString());
} else if (value instanceof Option) {
Option option = (Option) value;
option.init(e.getValue());
@@ -536,7 +533,7 @@ private HotSpotJVMCIRuntime() {
}
// Initialize the Option values.
- Option.parse(compilerToVm);
+ Option.parse(this);
String hostArchitecture = config.getHostArchitectureName();
@@ -549,7 +546,7 @@ private HotSpotJVMCIRuntime() {
hostBackend = registerBackend(factory.createJVMCIBackend(this, null));
}
- compilerFactory = HotSpotJVMCICompilerConfig.getCompilerFactory();
+ compilerFactory = HotSpotJVMCICompilerConfig.getCompilerFactory(this);
if (compilerFactory instanceof HotSpotJVMCICompilerFactory) {
hsCompilerFactory = (HotSpotJVMCICompilerFactory) compilerFactory;
if (hsCompilerFactory.getCompilationLevelAdjustment() != None) {
@@ -1161,12 +1158,12 @@ public void detachCurrentThread() {
}
/**
- * Informs HotSpot that no method whose module is in {@code modules} is to be compiled
- * with {@link #compileMethod}.
+ * Informs HotSpot that no method whose module is in {@code modules} is to be compiled with
+ * {@link #compileMethod}.
*
* @param modules the set of modules containing JVMCI compiler classes
*/
- public void excludeFromJVMCICompilation(Module...modules) {
+ public void excludeFromJVMCICompilation(Module... modules) {
this.excludeFromJVMCICompilation = modules.clone();
}
@@ -1179,4 +1176,15 @@ public void exitHotSpot(int status) {
}
compilerToVm.callSystemExit(status);
}
+
+ /**
+ * Writes a message to HotSpot's log stream and then calls {@link System#exit(int)} in HotSpot's
+ * runtime.
+ */
+ JVMCIError exitHotSpotWithMessage(int status, String format, Object... args) {
+ byte[] messageBytes = String.format(format, args).getBytes();
+ compilerToVm.writeDebugOutput(messageBytes, 0, messageBytes.length, true, true);
+ exitHotSpot(status);
+ throw JVMCIError.shouldNotReachHere();
+ }
}
diff --git a/test/hotspot/jtreg/compiler/jvmci/TestEnableJVMCIProduct.java b/test/hotspot/jtreg/compiler/jvmci/TestEnableJVMCIProduct.java
index d577e30b6cee3..6634c85e40fb6 100644
--- a/test/hotspot/jtreg/compiler/jvmci/TestEnableJVMCIProduct.java
+++ b/test/hotspot/jtreg/compiler/jvmci/TestEnableJVMCIProduct.java
@@ -80,6 +80,10 @@ static void test(String explicitFlag, Expectation... expectations) throws Except
for (Expectation expectation : expectations) {
output.stdoutShouldMatch(expectation.pattern);
}
- output.shouldHaveExitValue(0);
+ if (output.getExitValue() != 0) {
+ // This should only happen when JVMCI compilation is requested and the VM has no
+ // JVMCI compiler (e.g. Graal is not included in the build)
+ output.stdoutShouldMatch("No JVMCI compiler found");
+ }
}
}
From e7ca0c4ae3a8159fdebdfaae0dfcac44d7e028bc Mon Sep 17 00:00:00 2001
From: Magnus Ihse Bursie
Date: Wed, 2 Dec 2020 10:18:15 +0000
Subject: [PATCH 018/504] 8257224: JDK-8251549 didn't update building.html
Reviewed-by: sundar, shade
---
doc/building.html | 51 +++++++++++++++--------------------------------
1 file changed, 16 insertions(+), 35 deletions(-)
diff --git a/doc/building.html b/doc/building.html
index 20adf7e303762..03e87f6fa897e 100644
--- a/doc/building.html
+++ b/doc/building.html
@@ -97,12 +97,10 @@ Building the JDK
Getting Help
Hints and Suggestions for Advanced Users
Understanding the Build System
TL;DR (Instructions for the Impatient)
-If you are eager to try out building the JDK, these simple steps works most of the time. They assume that you have installed Mercurial (and Cygwin if running on Windows) and cloned the top-level JDK repository that you want to build.
+If you are eager to try out building the JDK, these simple steps works most of the time. They assume that you have installed Git (and Cygwin if running on Windows) and cloned the top-level JDK repository that you want to build.
Get the complete source code:
-hg clone http://hg.openjdk.java.net/jdk/jdk
+git clone https://git.openjdk.java.net/jdk/
Run configure:
bash configure
If configure
fails due to missing dependencies (to either the toolchain, build tools, external libraries or the boot JDK), most of the time it prints a suggestion on how to resolve the situation on your platform. Follow the instructions, and try running bash configure
again.
@@ -135,8 +133,8 @@ Introduction
The JDK is a complex software project. Building it requires a certain amount of technical expertise, a fair number of dependencies on external software, and reasonably powerful hardware.
If you just want to use the JDK and not build it yourself, this document is not for you. See for instance OpenJDK installation for some methods of installing a prebuilt JDK.
Getting the Source Code
-Make sure you are getting the correct version. As of JDK 10, the source is no longer split into separate repositories so you only need to clone one single repository. At the OpenJDK Mercurial server you can see a list of all available repositories. If you want to build an older version, e.g. JDK 8, it is recommended that you get the jdk8u
forest, which contains incremental updates, instead of the jdk8
forest, which was frozen at JDK 8 GA.
-If you are new to Mercurial, a good place to start is the Mercurial Beginner's Guide. The rest of this document assumes a working knowledge of Mercurial.
+Make sure you are getting the correct version. As of JDK 10, the source is no longer split into separate repositories so you only need to clone one single repository. At the OpenJDK Git site you can see a list of all available repositories. If you want to build an older version, e.g. JDK 11, it is recommended that you get the jdk11u
repo, which contains incremental updates, instead of the jdk11
repo, which was frozen at JDK 11 GA.
+If you are new to Git, a good place to start is the book Pro Git. The rest of this document assumes a working knowledge of Git.
Special Considerations
For a smooth building experience, it is recommended that you follow these rules on where and how to check out the source code.
@@ -194,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.)
-Internally in the build system, all paths are represented as Unix-style paths, e.g. /cygdrive/c/hg/jdk9/Makefile
rather than C:\hg\jdk9\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.
+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.
Note: Cygwin has a model of continuously updating all packages without any easy way to install or revert to a specific version of a package. This means that whenever you add or update a package in Cygwin, you might (inadvertently) update tools that are used by the JDK build process, and that can cause unexpected build problems.
@@ -758,14 +760,14 @@ Build Failure Summary
=== Output from failing command(s) repeated here ===
* For target hotspot_variant-server_libjvm_objs_psMemoryPool.o:
-/localhome/hg/jdk9-sandbox/hotspot/src/share/vm/services/psMemoryPool.cpp:1:1: error: 'failhere' does not name a type
+/localhome/git/jdk-sandbox/hotspot/src/share/vm/services/psMemoryPool.cpp:1:1: error: 'failhere' does not name a type
... (rest of output omitted)
-* All command lines available in /localhome/hg/jdk9-sandbox/build/linux-x64/make-support/failure-logs.
+* All command lines available in /localhome/git/jdk-sandbox/build/linux-x64/make-support/failure-logs.
=== End of repeated output ===
=== Make failed targets repeated here ===
-lib/CompileJvm.gmk:207: recipe for target '/localhome/hg/jdk9-sandbox/build/linux-x64/hotspot/variant-server/libjvm/objs/psMemoryPool.o' failed
+lib/CompileJvm.gmk:207: recipe for target '/localhome/git/jdk-sandbox/build/linux-x64/hotspot/variant-server/libjvm/objs/psMemoryPool.o' failed
make/Main.gmk:263: recipe for target 'hotspot-server-libs' failed
=== End of repeated output ===
@@ -792,7 +794,7 @@ Problems with Incremental Rebuilds
Here are a suggested list of things to try if you are having unexpected build problems. Each step requires more time than the one before, so try them in order. Most issues will be solved at step 1 or 2.
Make sure your repository is up-to-date
-Run hg pull -u
to make sure you have the latest changes.
+Run git pull origin master
to make sure you have the latest changes.
Clean build results
The simplest way to fix incremental rebuild issues is to run make clean
. This will remove all build results, but not the configuration or any build system support artifacts. In most cases, this will solve build errors resulting from incremental build mismatches.
Completely clean the build directory.
@@ -801,8 +803,8 @@ Problems with Incremental Rebuilds
make dist-clean
bash configure $(cat current-configuration)
make
-Re-clone the Mercurial repository
-Sometimes the Mercurial repository gets in a state that causes the product to be un-buildable. In such a case, the simplest solution is often the "sledgehammer approach": delete the entire repository, and re-clone it. If you have local changes, save them first to a different location using hg export
.
+Re-clone the Git repository
+Sometimes the Git repository gets in a state that causes the product to be un-buildable. In such a case, the simplest solution is often the "sledgehammer approach": delete the entire repository, and re-clone it. If you have local changes, save them first to a different location using git format-patch
.
Specific Build Issues
Clock Skew
@@ -821,19 +823,6 @@ Getting Help
If none of the suggestions in this document helps you, or if you find what you believe is a bug in the build system, please contact the Build Group by sending a mail to build-dev@openjdk.java.net. Please include the relevant parts of the configure and/or build log.
If you need general help or advice about developing for the JDK, you can also contact the Adoption Group. See the section on Contributing to OpenJDK for more information.
Hints and Suggestions for Advanced Users
-Setting Up a Repository for Pushing Changes (defpath)
-To help you prepare a proper push path for a Mercurial repository, there exists a useful tool known as defpath. It will help you setup a proper push path for pushing changes to the JDK.
-Install the extension by cloning http://hg.openjdk.java.net/code-tools/defpath
and updating your .hgrc
file. Here's one way to do this:
-cd ~
-mkdir hg-ext
-cd hg-ext
-hg clone http://hg.openjdk.java.net/code-tools/defpath
-cat << EOT >> ~/.hgrc
-[extensions]
-defpath=~/hg-ext/defpath/defpath.py
-EOT
-You can now setup a proper push path using:
-hg defpath -d -u <your OpenJDK username>
Bash Completion
The configure
and make
commands tries to play nice with bash command-line completion (using <tab>
or <tab><tab>
). To use this functionality, make sure you enable completion in your ~/.bashrc
(see instructions for bash in your operating system).
Make completion will work out of the box, and will complete valid make targets. For instance, typing make jdk-i<tab>
will complete to make jdk-image
.
@@ -886,14 +875,6 @@ Skipping the Dependency Check
Rebuilding Part of java.base (JDK_FILTER)
If you are modifying files in java.base
, which is the by far largest module in the JDK, then you need to rebuild all those files whenever a single file has changed. (This inefficiency will hopefully be addressed in JDK 10.)
As a hack, you can use the make control variable JDK_FILTER
to specify a pattern that will be used to limit the set of files being recompiled. For instance, make java.base JDK_FILTER=javax/crypto
(or, to combine methods, make java.base-java-only JDK_FILTER=javax/crypto
) will limit the compilation to files in the javax.crypto
package.
-Learn About Mercurial
-To become an efficient JDK developer, it is recommended that you invest in learning Mercurial properly. Here are some links that can get you started:
-
Understanding the Build System
This section will give you a more technical description on the details of the build system.
Configurations
From 9a60413ba0d00278a9bbc4bed4740d6526fa1612 Mon Sep 17 00:00:00 2001
From: Stuart Monteith
Date: Wed, 2 Dec 2020 10:22:20 +0000
Subject: [PATCH 019/504] 8248736: [aarch64] runtime/signal/TestSigpoll.java
failed "fatal error: not an ldr (literal) instruction."
Reviewed-by: aph, shade
---
.../cpu/aarch64/gc/shared/barrierSetAssembler_aarch64.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/hotspot/cpu/aarch64/gc/shared/barrierSetAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/gc/shared/barrierSetAssembler_aarch64.cpp
index 951920fdce4d7..440a894ed9d7b 100644
--- a/src/hotspot/cpu/aarch64/gc/shared/barrierSetAssembler_aarch64.cpp
+++ b/src/hotspot/cpu/aarch64/gc/shared/barrierSetAssembler_aarch64.cpp
@@ -254,7 +254,7 @@ void BarrierSetAssembler::nmethod_entry_barrier(MacroAssembler* masm) {
__ cmpw(rscratch1, rscratch2);
__ br(Assembler::EQ, skip);
- __ mov(rscratch1, StubRoutines::aarch64::method_entry_barrier());
+ __ movptr(rscratch1, (uintptr_t) StubRoutines::aarch64::method_entry_barrier());
__ blr(rscratch1);
__ b(skip);
From bff68f1f67fb02b3fc75021fc18502c557d48d39 Mon Sep 17 00:00:00 2001
From: Magnus Ihse Bursie
Date: Wed, 2 Dec 2020 10:30:48 +0000
Subject: [PATCH 020/504] 8257533: legacy-jre-image includes jpackage and jlink
tools
Reviewed-by: alanb, sundar
---
make/common/Modules.gmk | 1 -
1 file changed, 1 deletion(-)
diff --git a/make/common/Modules.gmk b/make/common/Modules.gmk
index 910f8beb2ffb4..f75c76e72c0d7 100644
--- a/make/common/Modules.gmk
+++ b/make/common/Modules.gmk
@@ -125,7 +125,6 @@ endif
JRE_TOOL_MODULES += \
jdk.jdwp.agent \
- jdk.jpackage \
#
################################################################################
From 1fd0ea703522472a14d1d02fe5290e710d7858b1 Mon Sep 17 00:00:00 2001
From: Stefan Karlsson
Date: Wed, 2 Dec 2020 12:28:10 +0000
Subject: [PATCH 021/504] 8256382: Use try_lock for hs_err EventLog printing
Reviewed-by: stuefe
---
src/hotspot/share/utilities/events.hpp | 34 +++++++++++++++++++++++---
1 file changed, 30 insertions(+), 4 deletions(-)
diff --git a/src/hotspot/share/utilities/events.hpp b/src/hotspot/share/utilities/events.hpp
index d4613073673ad..0b1d442d8b33b 100644
--- a/src/hotspot/share/utilities/events.hpp
+++ b/src/hotspot/share/utilities/events.hpp
@@ -311,12 +311,38 @@ inline void Events::log_deopt_message(Thread* thread, const char* format, ...) {
template
inline void EventLogBase::print_log_on(outputStream* out, int max) {
- if (Thread::current_or_null() == NULL) {
- // Not yet attached? Don't try to use locking
+ struct MaybeLocker {
+ Mutex* const _mutex;
+ bool _proceed;
+ bool _locked;
+
+ MaybeLocker(Mutex* mutex) : _mutex(mutex), _proceed(false), _locked(false) {
+ if (Thread::current_or_null() == NULL) {
+ _proceed = true;
+ } else if (VMError::is_error_reported()) {
+ if (_mutex->try_lock_without_rank_check()) {
+ _proceed = _locked = true;
+ }
+ } else {
+ _mutex->lock_without_safepoint_check();
+ _proceed = _locked = true;
+ }
+ }
+ ~MaybeLocker() {
+ if (_locked) {
+ _mutex->unlock();
+ }
+ }
+ };
+
+ MaybeLocker ml(&_mutex);
+
+ if (ml._proceed) {
print_log_impl(out, max);
} else {
- MutexLocker ml(&_mutex, Mutex::_no_safepoint_check_flag);
- print_log_impl(out, max);
+ out->print_cr("%s (%d events):", _name, _count);
+ out->print_cr("No events printed - crash while holding lock");
+ out->cr();
}
}
From 287b829c0463018fb05e51d947d7a6783c03f199 Mon Sep 17 00:00:00 2001
From: Stefan Karlsson
Date: Wed, 2 Dec 2020 12:28:38 +0000
Subject: [PATCH 022/504] 8254877: GCLogPrecious::_lock rank constrains what
locks you are allowed to have when crashing
Reviewed-by: eosterlund
---
src/hotspot/share/gc/shared/gcLogPrecious.cpp | 26 ++++++++++++++-----
1 file changed, 19 insertions(+), 7 deletions(-)
diff --git a/src/hotspot/share/gc/shared/gcLogPrecious.cpp b/src/hotspot/share/gc/shared/gcLogPrecious.cpp
index 3e996c228c3a7..eddbbdcf11d3c 100644
--- a/src/hotspot/share/gc/shared/gcLogPrecious.cpp
+++ b/src/hotspot/share/gc/shared/gcLogPrecious.cpp
@@ -33,7 +33,7 @@ Mutex* GCLogPrecious::_lock = NULL;
void GCLogPrecious::initialize() {
_lines = new (ResourceObj::C_HEAP, mtGC) stringStream();
_temp = new (ResourceObj::C_HEAP, mtGC) stringStream();
- _lock = new Mutex(Mutex::tty,
+ _lock = new Mutex(Mutex::event, /* The lowest lock rank I could find */
"GCLogPrecious Lock",
true,
Mutex::_safepoint_check_never);
@@ -77,11 +77,23 @@ void GCLogPrecious::vwrite_and_debug(LogTargetHandle log,
}
void GCLogPrecious::print_on_error(outputStream* st) {
- if (_lines != NULL) {
- MutexLocker locker(_lock, Mutex::_no_safepoint_check_flag);
- if (_lines->size() > 0) {
- st->print_cr("GC Precious Log:");
- st->print_cr("%s", _lines->base());
- }
+ st->print_cr("GC Precious Log:");
+
+ if (_lines == NULL) {
+ st->print_cr("\n");
+ return;
+ }
+
+ if (!_lock->try_lock_without_rank_check()) {
+ st->print_cr("\n");
+ return;
}
+
+ if (_lines->size() == 0) {
+ st->print_cr("\n");
+ } else {
+ st->print_cr("%s", _lines->base());
+ }
+
+ _lock->unlock();
}
From cfb50a9cb7da16375a26c3f147ebd17ca393f914 Mon Sep 17 00:00:00 2001
From: Coleen Phillimore
Date: Wed, 2 Dec 2020 13:40:26 +0000
Subject: [PATCH 023/504] 8253916: ResourceExhausted/resexhausted001 crashes on
Linux-x64
Reviewed-by: stuefe, sspitsyn, dholmes
---
src/hotspot/share/runtime/stackOverflow.cpp | 5 +----
src/hotspot/share/utilities/debug.hpp | 3 ++-
src/hotspot/share/utilities/vmError.cpp | 4 +++-
test/hotspot/jtreg/ProblemList.txt | 2 --
.../ResourceExhausted/resexhausted001/TestDescription.java | 3 ++-
.../ResourceExhausted/resexhausted004/TestDescription.java | 3 ++-
6 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/src/hotspot/share/runtime/stackOverflow.cpp b/src/hotspot/share/runtime/stackOverflow.cpp
index 01aba3ea2de47..942f3a29e3fda 100644
--- a/src/hotspot/share/runtime/stackOverflow.cpp
+++ b/src/hotspot/share/runtime/stackOverflow.cpp
@@ -103,10 +103,7 @@ void StackOverflow::create_stack_guard_pages() {
} else {
log_warning(os, thread)("Attempt to protect stack guard pages failed ("
PTR_FORMAT "-" PTR_FORMAT ").", p2i(low_addr), p2i(low_addr + len));
- if (os::uncommit_memory((char *) low_addr, len)) {
- log_warning(os, thread)("Attempt to deallocate stack guard pages failed.");
- }
- return;
+ vm_exit_out_of_memory(len, OOM_MPROTECT_ERROR, "memory to guard stack pages");
}
log_debug(os, thread)("Thread " UINTX_FORMAT " stack guard pages activated: "
diff --git a/src/hotspot/share/utilities/debug.hpp b/src/hotspot/share/utilities/debug.hpp
index cd44aea2781f9..8f6858ac58917 100644
--- a/src/hotspot/share/utilities/debug.hpp
+++ b/src/hotspot/share/utilities/debug.hpp
@@ -149,7 +149,8 @@ do {
enum VMErrorType {
INTERNAL_ERROR = 0xe0000000,
OOM_MALLOC_ERROR = 0xe0000001,
- OOM_MMAP_ERROR = 0xe0000002
+ OOM_MMAP_ERROR = 0xe0000002,
+ OOM_MPROTECT_ERROR = 0xe0000003
};
// Set to suppress secondary error reporting.
diff --git a/src/hotspot/share/utilities/vmError.cpp b/src/hotspot/share/utilities/vmError.cpp
index 16e3b8e11c212..9b0dc413bcda9 100644
--- a/src/hotspot/share/utilities/vmError.cpp
+++ b/src/hotspot/share/utilities/vmError.cpp
@@ -510,10 +510,12 @@ void VMError::report(outputStream* st, bool _verbose) {
switch(static_cast(_id)) {
case OOM_MALLOC_ERROR:
case OOM_MMAP_ERROR:
+ case OOM_MPROTECT_ERROR:
if (_size) {
st->print("# Native memory allocation ");
st->print((_id == (int)OOM_MALLOC_ERROR) ? "(malloc) failed to allocate " :
- "(mmap) failed to map ");
+ (_id == (int)OOM_MMAP_ERROR) ? "(mmap) failed to map " :
+ "(mprotect) failed to protect ");
jio_snprintf(buf, sizeof(buf), SIZE_FORMAT, _size);
st->print("%s", buf);
st->print(" bytes");
diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt
index 75fbead6ab989..4c45915438d21 100644
--- a/test/hotspot/jtreg/ProblemList.txt
+++ b/test/hotspot/jtreg/ProblemList.txt
@@ -131,8 +131,6 @@ vmTestbase/metaspace/gc/firstGC_50m/TestDescription.java 8208250 generic-all
vmTestbase/metaspace/gc/firstGC_99m/TestDescription.java 8208250 generic-all
vmTestbase/metaspace/gc/firstGC_default/TestDescription.java 8208250 generic-all
-vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted001/TestDescription.java 8253916 linux-all
-vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted004/TestDescription.java 8253916 linux-all
vmTestbase/nsk/jvmti/AttachOnDemand/attach045/TestDescription.java 8202971 generic-all
vmTestbase/nsk/jvmti/scenarios/jni_interception/JI05/ji05t001/TestDescription.java 8219652 aix-ppc64
vmTestbase/nsk/jvmti/scenarios/jni_interception/JI06/ji06t001/TestDescription.java 8219652 aix-ppc64
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted001/TestDescription.java
index c86d34c9b2c2b..58a1867a9fc77 100644
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted001/TestDescription.java
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted001/TestDescription.java
@@ -24,6 +24,7 @@
/*
* @test
+ * @bug 8253916
*
* @summary converted from VM Testbase nsk/jvmti/ResourceExhausted/resexhausted001.
* VM Testbase keywords: [jpda, jvmti, noras, vm6, nonconcurrent, quarantine, exclude]
@@ -37,7 +38,7 @@
*
* @library /vmTestbase
* /test/lib
- * @run main/othervm/native/timeout=240
+ * @run main/othervm/native/manual/timeout=240
* -agentlib:resexhausted=-waittime=5
* -XX:-UseGCOverheadLimit
* -Xms16m
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted004/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted004/TestDescription.java
index 8b53a5627d523..e795bf1f9d4aa 100644
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted004/TestDescription.java
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted004/TestDescription.java
@@ -24,6 +24,7 @@
/*
* @test
+ * @bug 8253916
*
* @key randomness
* @summary converted from VM Testbase nsk/jvmti/ResourceExhausted/resexhausted004.
@@ -39,7 +40,7 @@
*
* @library /vmTestbase
* /test/lib
- * @run main/othervm/native
+ * @run main/othervm/native/manual
* -agentlib:resexhausted=-waittime=5
* -Xms16m
* -Xmx16m
From 2508bc7c58b631c41f1c2415dd9925d9d309dbe8 Mon Sep 17 00:00:00 2001
From: Coleen Phillimore
Date: Wed, 2 Dec 2020 14:09:55 +0000
Subject: [PATCH 024/504] 8257140: Crash in
JvmtiTagMap::flush_object_free_events()
Reviewed-by: sspitsyn, kbarrett
---
src/hotspot/share/prims/jvmtiEnvBase.cpp | 10 +++++-----
src/hotspot/share/prims/jvmtiTagMap.cpp | 8 ++++++++
src/hotspot/share/prims/jvmtiTagMap.hpp | 1 +
src/hotspot/share/prims/jvmtiTagMapTable.cpp | 13 ++++++++++---
src/hotspot/share/prims/jvmtiTagMapTable.hpp | 1 +
5 files changed, 25 insertions(+), 8 deletions(-)
diff --git a/src/hotspot/share/prims/jvmtiEnvBase.cpp b/src/hotspot/share/prims/jvmtiEnvBase.cpp
index 2065aa68f8c44..55ac65b614fa7 100644
--- a/src/hotspot/share/prims/jvmtiEnvBase.cpp
+++ b/src/hotspot/share/prims/jvmtiEnvBase.cpp
@@ -256,11 +256,11 @@ JvmtiEnvBase::env_dispose() {
// Same situation as with events (see above)
set_native_method_prefixes(0, NULL);
- JvmtiTagMap* tag_map_to_deallocate = _tag_map;
- set_tag_map(NULL);
- // A tag map can be big, deallocate it now
- if (tag_map_to_deallocate != NULL) {
- delete tag_map_to_deallocate;
+ JvmtiTagMap* tag_map_to_clear = tag_map_acquire();
+ // A tag map can be big, clear it now to save memory until
+ // the destructor runs.
+ if (tag_map_to_clear != NULL) {
+ tag_map_to_clear->clear();
}
_needs_clean_up = true;
diff --git a/src/hotspot/share/prims/jvmtiTagMap.cpp b/src/hotspot/share/prims/jvmtiTagMap.cpp
index a6c1b947b4a6b..a20ad93fbb73f 100644
--- a/src/hotspot/share/prims/jvmtiTagMap.cpp
+++ b/src/hotspot/share/prims/jvmtiTagMap.cpp
@@ -97,6 +97,14 @@ JvmtiTagMap::~JvmtiTagMap() {
_hashmap = NULL;
}
+// Called by env_dispose() to reclaim memory before deallocation.
+// Remove all the entries but keep the empty table intact.
+// This needs the table lock.
+void JvmtiTagMap::clear() {
+ MutexLocker ml(lock(), Mutex::_no_safepoint_check_flag);
+ _hashmap->clear();
+}
+
// returns the tag map for the given environments. If the tag map
// doesn't exist then it is created.
JvmtiTagMap* JvmtiTagMap::tag_map_for(JvmtiEnv* env) {
diff --git a/src/hotspot/share/prims/jvmtiTagMap.hpp b/src/hotspot/share/prims/jvmtiTagMap.hpp
index bce2f71c6c55f..ab5f9d7f2b62c 100644
--- a/src/hotspot/share/prims/jvmtiTagMap.hpp
+++ b/src/hotspot/share/prims/jvmtiTagMap.hpp
@@ -119,6 +119,7 @@ class JvmtiTagMap : public CHeapObj {
static void gc_notification(size_t num_dead_entries) NOT_JVMTI_RETURN;
void flush_object_free_events();
+ void clear(); // Clear tagmap table after the env is disposed.
// For ServiceThread
static void flush_all_object_free_events() NOT_JVMTI_RETURN;
diff --git a/src/hotspot/share/prims/jvmtiTagMapTable.cpp b/src/hotspot/share/prims/jvmtiTagMapTable.cpp
index f9f22507ffcf0..90879a63cd9f2 100644
--- a/src/hotspot/share/prims/jvmtiTagMapTable.cpp
+++ b/src/hotspot/share/prims/jvmtiTagMapTable.cpp
@@ -49,9 +49,9 @@ oop JvmtiTagMapEntry::object_no_keepalive() {
JvmtiTagMapTable::JvmtiTagMapTable()
: Hashtable(_table_size, sizeof(JvmtiTagMapEntry)) {}
-JvmtiTagMapTable::~JvmtiTagMapTable() {
- // Delete this table
- log_debug(jvmti, table)("JvmtiTagMapTable deleted");
+void JvmtiTagMapTable::clear() {
+ // Clear this table
+ log_debug(jvmti, table)("JvmtiTagMapTable cleared");
for (int i = 0; i < table_size(); ++i) {
for (JvmtiTagMapEntry* m = bucket(i); m != NULL;) {
JvmtiTagMapEntry* entry = m;
@@ -59,11 +59,18 @@ JvmtiTagMapTable::~JvmtiTagMapTable() {
m = m->next();
free_entry(entry);
}
+ JvmtiTagMapEntry** p = bucket_addr(i);
+ *p = NULL; // clear out buckets.
}
assert(number_of_entries() == 0, "should have removed all entries");
assert(new_entry_free_list() == NULL, "entry present on JvmtiTagMapTable's free list");
}
+JvmtiTagMapTable::~JvmtiTagMapTable() {
+ clear();
+ // base class ~BasicHashtable deallocates the buckets.
+}
+
// Entries are C_Heap allocated
JvmtiTagMapEntry* JvmtiTagMapTable::new_entry(unsigned int hash, WeakHandle w, jlong tag) {
JvmtiTagMapEntry* entry = (JvmtiTagMapEntry*)Hashtable::allocate_new_entry(hash, w);
diff --git a/src/hotspot/share/prims/jvmtiTagMapTable.hpp b/src/hotspot/share/prims/jvmtiTagMapTable.hpp
index 37f290d07f607..5f83f4e44c8ab 100644
--- a/src/hotspot/share/prims/jvmtiTagMapTable.hpp
+++ b/src/hotspot/share/prims/jvmtiTagMapTable.hpp
@@ -90,6 +90,7 @@ class JvmtiTagMapTable : public Hashtable {
// Cleanup cleared entries and post
void remove_dead_entries(JvmtiEnv* env, bool post_object_free);
void rehash();
+ void clear();
};
// A supporting class for iterating over all entries in Hashmap
From 0b8c7807fe9381bf812ea5ae0ae051a46f35b6d8 Mon Sep 17 00:00:00 2001
From: Yumin Qi
Date: Wed, 2 Dec 2020 16:22:51 +0000
Subject: [PATCH 025/504] 8256256: UL should not use heap allocation for output
string
Reviewed-by: dholmes, stuefe
---
src/hotspot/share/logging/logTagSet.cpp | 51 +++++++++++++++++++------
1 file changed, 40 insertions(+), 11 deletions(-)
diff --git a/src/hotspot/share/logging/logTagSet.cpp b/src/hotspot/share/logging/logTagSet.cpp
index 2a2f640e0c660..53ee53bdfceae 100644
--- a/src/hotspot/share/logging/logTagSet.cpp
+++ b/src/hotspot/share/logging/logTagSet.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -121,19 +121,48 @@ void LogTagSet::vwrite(LogLevelType level, const char* fmt, va_list args) {
ret = os::vsnprintf(buf + prefix_len, sizeof(buf) - prefix_len, fmt, args);
} else {
// Buffer too small. Just call printf to find out the length for realloc below.
- ret = os::vsnprintf(buf, sizeof(buf), fmt, args);
+ ret = os::vsnprintf(nullptr, 0, fmt, args);
}
+
assert(ret >= 0, "Log message buffer issue");
- if ((size_t)ret >= sizeof(buf)) {
- size_t newbuf_len = prefix_len + ret + 1;
- char* newbuf = NEW_C_HEAP_ARRAY(char, newbuf_len, mtLogging);
- prefix_len = _write_prefix(newbuf, newbuf_len);
- ret = os::vsnprintf(newbuf + prefix_len, newbuf_len - prefix_len, fmt, saved_args);
- assert(ret >= 0, "Log message buffer issue");
- log(level, newbuf);
- FREE_C_HEAP_ARRAY(char, newbuf);
- } else {
+ if (ret < 0) {
+ // Error, just log contents in buf.
+ log(level, buf);
+ log(level, "Log message buffer issue");
+ va_end(saved_args);
+ return;
+ }
+
+
+ size_t newbuf_len = (size_t)ret + prefix_len + 1; // total bytes needed including prefix.
+ if (newbuf_len <= sizeof(buf)) {
log(level, buf);
+ } else {
+ // Buffer too small, allocate a large enough buffer using malloc/free to avoid circularity.
+ char* newbuf = (char*)::malloc(newbuf_len * sizeof(char));
+ if (newbuf != nullptr) {
+ prefix_len = _write_prefix(newbuf, newbuf_len);
+ ret = os::vsnprintf(newbuf + prefix_len, newbuf_len - prefix_len, fmt, saved_args);
+ assert(ret >= 0, "Log message newbuf issue");
+ // log the contents in newbuf even with error happened.
+ log(level, newbuf);
+ if (ret < 0) {
+ log(level, "Log message newbuf issue");
+ }
+ ::free(newbuf);
+ } else {
+ // Native OOM, use buf to output the least message. At this moment buf is full of either
+ // truncated prefix or truncated prefix + string. Put trunc_msg at the end of buf.
+ const char* trunc_msg = "..(truncated), native OOM";
+ const size_t ltr = strlen(trunc_msg) + 1;
+ ret = os::snprintf(buf + sizeof(buf) - ltr, ltr, "%s", trunc_msg);
+ assert(ret >= 0, "Log message buffer issue");
+ // log the contents in newbuf even with error happened.
+ log(level, buf);
+ if (ret < 0) {
+ log(level, "Log message buffer issue under OOM");
+ }
+ }
}
va_end(saved_args);
}
From 670426646d3513f0b132b954a9e5cf22c37f3654 Mon Sep 17 00:00:00 2001
From: Ioi Lam
Date: Wed, 2 Dec 2020 16:56:55 +0000
Subject: [PATCH 026/504] 8257565: epsilonBarrierSet.hpp should not include
barrierSetAssembler
Reviewed-by: kbarrett, stuefe, shade
---
src/hotspot/cpu/aarch64/aarch64.ad | 1 +
src/hotspot/cpu/aarch64/jvmciCodeInstaller_aarch64.cpp | 1 +
src/hotspot/share/gc/epsilon/epsilonBarrierSet.hpp | 1 -
3 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/hotspot/cpu/aarch64/aarch64.ad b/src/hotspot/cpu/aarch64/aarch64.ad
index e3da0e72c8ea9..d89363099d318 100644
--- a/src/hotspot/cpu/aarch64/aarch64.ad
+++ b/src/hotspot/cpu/aarch64/aarch64.ad
@@ -1238,6 +1238,7 @@ definitions %{
source_hpp %{
#include "asm/macroAssembler.hpp"
+#include "gc/shared/barrierSetAssembler.hpp"
#include "gc/shared/cardTable.hpp"
#include "gc/shared/cardTableBarrierSet.hpp"
#include "gc/shared/collectedHeap.hpp"
diff --git a/src/hotspot/cpu/aarch64/jvmciCodeInstaller_aarch64.cpp b/src/hotspot/cpu/aarch64/jvmciCodeInstaller_aarch64.cpp
index f41d79e102166..cbe58e692dc4f 100644
--- a/src/hotspot/cpu/aarch64/jvmciCodeInstaller_aarch64.cpp
+++ b/src/hotspot/cpu/aarch64/jvmciCodeInstaller_aarch64.cpp
@@ -22,6 +22,7 @@
*/
#include "precompiled.hpp"
+#include "asm/macroAssembler.hpp"
#include "jvmci/jvmci.hpp"
#include "jvmci/jvmciCodeInstaller.hpp"
#include "jvmci/jvmciRuntime.hpp"
diff --git a/src/hotspot/share/gc/epsilon/epsilonBarrierSet.hpp b/src/hotspot/share/gc/epsilon/epsilonBarrierSet.hpp
index f3c07f6cbbfd9..7a8083df6bb4a 100644
--- a/src/hotspot/share/gc/epsilon/epsilonBarrierSet.hpp
+++ b/src/hotspot/share/gc/epsilon/epsilonBarrierSet.hpp
@@ -25,7 +25,6 @@
#ifndef SHARE_GC_EPSILON_EPSILONBARRIERSET_HPP
#define SHARE_GC_EPSILON_EPSILONBARRIERSET_HPP
-#include "gc/shared/barrierSetAssembler.hpp"
#include "gc/shared/barrierSet.hpp"
// No interaction with application is required for Epsilon, and therefore
From 692b273ec53f54a879a4bbaad6c2f5f1d5358a71 Mon Sep 17 00:00:00 2001
From: Vladimir Ivanov
Date: Wed, 2 Dec 2020 17:35:41 +0000
Subject: [PATCH 027/504] 8257189: Handle concurrent updates of MH.form better
Reviewed-by: redestad, psandoz
---
.../java/lang/invoke/DirectMethodHandle.java | 11 +--
.../classes/java/lang/invoke/Invokers.java | 16 ++---
.../classes/java/lang/invoke/LambdaForm.java | 3 +
.../java/lang/invoke/MethodHandle.java | 67 +++++++++++++------
.../java/lang/invoke/MethodHandleImpl.java | 25 +++----
5 files changed, 69 insertions(+), 53 deletions(-)
diff --git a/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java b/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java
index e9eb5f86aaf85..a9ce7622e9b04 100644
--- a/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java
+++ b/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java
@@ -36,6 +36,7 @@
import java.lang.ref.WeakReference;
import java.util.Arrays;
import java.util.Objects;
+import java.util.function.Function;
import static java.lang.invoke.LambdaForm.*;
import static java.lang.invoke.LambdaForm.Kind.*;
@@ -387,10 +388,12 @@ protected WeakReference computeValue(Class> type) {
private void ensureInitialized() {
if (checkInitialized(member)) {
// The coast is clear. Delete the barrier.
- if (member.isField())
- updateForm(preparedFieldLambdaForm(member));
- else
- updateForm(preparedLambdaForm(member));
+ updateForm(new Function<>() {
+ public LambdaForm apply(LambdaForm oldForm) {
+ return (member.isField() ? preparedFieldLambdaForm(member)
+ : preparedLambdaForm(member));
+ }
+ });
}
}
private static boolean checkInitialized(MemberName member) {
diff --git a/src/java.base/share/classes/java/lang/invoke/Invokers.java b/src/java.base/share/classes/java/lang/invoke/Invokers.java
index ee1f9baa3da94..3a9ef635181be 100644
--- a/src/java.base/share/classes/java/lang/invoke/Invokers.java
+++ b/src/java.base/share/classes/java/lang/invoke/Invokers.java
@@ -596,21 +596,17 @@ static MethodHandle getCallSiteTarget(CallSite site) {
@ForceInline
/*non-public*/
static void checkCustomized(MethodHandle mh) {
- if (MethodHandleImpl.isCompileConstant(mh)) return;
- if (mh.form.customized == null) {
- maybeCustomize(mh);
+ if (MethodHandleImpl.isCompileConstant(mh)) {
+ return; // no need to customize a MH when the instance is known to JIT
+ }
+ if (mh.form.customized == null) { // fast approximate check that the underlying form is already customized
+ maybeCustomize(mh); // marked w/ @DontInline
}
}
@DontInline
- /*non-public*/
static void maybeCustomize(MethodHandle mh) {
- byte count = mh.customizationCount;
- if (count >= CUSTOMIZE_THRESHOLD) {
- mh.customize();
- } else {
- mh.customizationCount = (byte)(count+1);
- }
+ mh.maybeCustomize();
}
// Local constant functions:
diff --git a/src/java.base/share/classes/java/lang/invoke/LambdaForm.java b/src/java.base/share/classes/java/lang/invoke/LambdaForm.java
index 0f527b527d054..da52a39dcdbac 100644
--- a/src/java.base/share/classes/java/lang/invoke/LambdaForm.java
+++ b/src/java.base/share/classes/java/lang/invoke/LambdaForm.java
@@ -501,6 +501,9 @@ private static boolean namesOK(int arity, Name[] names) {
/** Customize LambdaForm for a particular MethodHandle */
LambdaForm customize(MethodHandle mh) {
+ if (customized == mh) {
+ return this;
+ }
LambdaForm customForm = new LambdaForm(arity, names, result, forceInline, mh, kind);
if (COMPILE_THRESHOLD >= 0 && isCompiled) {
// If shared LambdaForm has been compiled, compile customized version as well.
diff --git a/src/java.base/share/classes/java/lang/invoke/MethodHandle.java b/src/java.base/share/classes/java/lang/invoke/MethodHandle.java
index e9f8dc918e2ce..04cbe9ca49b88 100644
--- a/src/java.base/share/classes/java/lang/invoke/MethodHandle.java
+++ b/src/java.base/share/classes/java/lang/invoke/MethodHandle.java
@@ -30,13 +30,13 @@
import java.lang.constant.ClassDesc;
import java.lang.constant.Constable;
-import java.lang.constant.ConstantDesc;
import java.lang.constant.DirectMethodHandleDesc;
import java.lang.constant.MethodHandleDesc;
import java.lang.constant.MethodTypeDesc;
import java.util.Arrays;
import java.util.Objects;
import java.util.Optional;
+import java.util.function.Function;
import static java.lang.invoke.MethodHandleInfo.*;
import static java.lang.invoke.MethodHandleStatics.*;
@@ -455,9 +455,8 @@ public abstract class MethodHandle implements Constable {
/*private*/
MethodHandle asTypeCache;
// asTypeCache is not private so that invokers can easily fetch it
- /*non-public*/
- byte customizationCount;
- // customizationCount should be accessible from invokers
+
+ private byte customizationCount;
/**
* Reports the type of this method handle.
@@ -1733,6 +1732,30 @@ Object internalProperties() {
*/
abstract BoundMethodHandle rebind();
+ /* non-public */
+ void maybeCustomize() {
+ if (form.customized == null) {
+ byte count = customizationCount;
+ if (count >= CUSTOMIZE_THRESHOLD) {
+ customize();
+ } else {
+ customizationCount = (byte) (count + 1);
+ }
+ }
+ }
+
+ /** Craft a LambdaForm customized for this particular MethodHandle. */
+ /*non-public*/
+ void customize() {
+ updateForm(new Function<>() {
+ public LambdaForm apply(LambdaForm oldForm) {
+ return oldForm.customize(MethodHandle.this);
+ }
+ });
+ }
+
+ private volatile boolean updateInProgress; // = false;
+
/**
* Replace the old lambda form of this method handle with a new one.
* The new one must be functionally equivalent to the old one.
@@ -1741,26 +1764,26 @@ Object internalProperties() {
* Use with discretion.
*/
/*non-public*/
- void updateForm(LambdaForm newForm) {
- assert(newForm.customized == null || newForm.customized == this);
- if (form == newForm) return;
- newForm.prepare(); // as in MethodHandle.
- UNSAFE.putReference(this, FORM_OFFSET, newForm);
- UNSAFE.fullFence();
- }
-
- /** Craft a LambdaForm customized for this particular MethodHandle */
- /*non-public*/
- void customize() {
- final LambdaForm form = this.form;
- if (form.customized == null) {
- LambdaForm newForm = form.customize(this);
- updateForm(newForm);
+ void updateForm(Function updater) {
+ if (UNSAFE.compareAndSetBoolean(this, UPDATE_OFFSET, false, true)) { // updateInProgress = true
+ // Only 1 thread wins the race and updates MH.form field.
+ try {
+ LambdaForm oldForm = form;
+ LambdaForm newForm = updater.apply(oldForm);
+ if (oldForm != newForm) {
+ assert (newForm.customized == null || newForm.customized == this);
+ newForm.prepare(); // as in MethodHandle.
+ UNSAFE.putReference(this, FORM_OFFSET, newForm);
+ UNSAFE.fullFence();
+ }
+ } finally {
+ updateInProgress = false;
+ }
} else {
- assert(form.customized == this);
+ // Update got lost due to concurrent update. But callers don't care.
}
}
- private static final long FORM_OFFSET
- = UNSAFE.objectFieldOffset(MethodHandle.class, "form");
+ private static final long FORM_OFFSET = UNSAFE.objectFieldOffset(MethodHandle.class, "form");
+ private static final long UPDATE_OFFSET = UNSAFE.objectFieldOffset(MethodHandle.class, "updateInProgress");
}
diff --git a/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java b/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java
index 45cec744792ab..29d3a699a4038 100644
--- a/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java
+++ b/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java
@@ -841,21 +841,9 @@ public MethodHandle asTypeUncached(MethodType newType) {
return (asTypeCache = wrapper);
}
- // Customize target if counting happens for too long.
- private int invocations = CUSTOMIZE_THRESHOLD;
- private void maybeCustomizeTarget() {
- int c = invocations;
- if (c >= 0) {
- if (c == 1) {
- target.customize();
- }
- invocations = c - 1;
- }
- }
-
boolean countDown() {
int c = count;
- maybeCustomizeTarget();
+ target.maybeCustomize(); // customize if counting happens for too long
if (c <= 1) {
// Try to limit number of updates. MethodHandle.updateForm() doesn't guarantee LF update visibility.
if (isCounting) {
@@ -872,12 +860,15 @@ boolean countDown() {
@Hidden
static void maybeStopCounting(Object o1) {
- CountingWrapper wrapper = (CountingWrapper) o1;
+ final CountingWrapper wrapper = (CountingWrapper) o1;
if (wrapper.countDown()) {
// Reached invocation threshold. Replace counting behavior with a non-counting one.
- LambdaForm lform = wrapper.nonCountingFormProducer.apply(wrapper.target);
- lform.compileToBytecode(); // speed up warmup by avoiding LF interpretation again after transition
- wrapper.updateForm(lform);
+ wrapper.updateForm(new Function<>() {
+ public LambdaForm apply(LambdaForm oldForm) {
+ LambdaForm lform = wrapper.nonCountingFormProducer.apply(wrapper.target);
+ lform.compileToBytecode(); // speed up warmup by avoiding LF interpretation again after transition
+ return lform;
+ }});
}
}
From 93b6ab56ae1499616d38c0b62f4256f1d7c17ce5 Mon Sep 17 00:00:00 2001
From: Christoph Langer
Date: Wed, 2 Dec 2020 19:23:26 +0000
Subject: [PATCH 028/504] 8256818: SSLSocket that is never bound or connected
leaks socket resources
Reviewed-by: xuelei
---
.../sun/security/ssl/SSLSocketImpl.java | 37 +++++++-----
.../checkHandles/CheckHandles.java | 16 +++--
.../ssl/SSLSocketImpl/SSLSocketLeak.java | 59 +++++++++++++++++++
test/lib/jdk/test/lib/util/FileUtils.java | 32 +++++++---
.../jdk/test/lib/util/libFileUtils.c} | 2 +-
5 files changed, 114 insertions(+), 32 deletions(-)
create mode 100644 test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketLeak.java
rename test/{jdk/java/lang/ProcessBuilder/checkHandles/libCheckHandles.c => lib/jdk/test/lib/util/libFileUtils.c} (93%)
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 0412d4f3eda39..439be80a1e6ed 100644
--- a/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java
+++ b/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java
@@ -553,7 +553,7 @@ public boolean isClosed() {
// locks may be deadlocked.
@Override
public void close() throws IOException {
- if (tlsIsClosed) {
+ if (isClosed()) {
return;
}
@@ -562,19 +562,16 @@ public void close() throws IOException {
}
try {
- // shutdown output bound, which may have been closed previously.
- if (!isOutputShutdown()) {
- duplexCloseOutput();
- }
-
- // shutdown input bound, which may have been closed previously.
- if (!isInputShutdown()) {
- duplexCloseInput();
- }
+ if (isConnected()) {
+ // shutdown output bound, which may have been closed previously.
+ if (!isOutputShutdown()) {
+ duplexCloseOutput();
+ }
- if (!isClosed()) {
- // close the connection directly
- closeSocket(false);
+ // shutdown input bound, which may have been closed previously.
+ if (!isInputShutdown()) {
+ duplexCloseInput();
+ }
}
} catch (IOException ioe) {
// ignore the exception
@@ -582,7 +579,19 @@ public void close() throws IOException {
SSLLogger.warning("SSLSocket duplex close failed", ioe);
}
} finally {
- tlsIsClosed = true;
+ if (!isClosed()) {
+ // close the connection directly
+ try {
+ closeSocket(false);
+ } catch (IOException ioe) {
+ // ignore the exception
+ if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
+ SSLLogger.warning("SSLSocket close failed", ioe);
+ }
+ } finally {
+ tlsIsClosed = true;
+ }
+ }
}
}
diff --git a/test/jdk/java/lang/ProcessBuilder/checkHandles/CheckHandles.java b/test/jdk/java/lang/ProcessBuilder/checkHandles/CheckHandles.java
index 14d6b4383cdab..69686573be51f 100644
--- a/test/jdk/java/lang/ProcessBuilder/checkHandles/CheckHandles.java
+++ b/test/jdk/java/lang/ProcessBuilder/checkHandles/CheckHandles.java
@@ -27,32 +27,30 @@
import java.io.InputStreamReader;
import java.lang.ProcessHandle;
+import jdk.test.lib.util.FileUtils;
+
/*
* @test
* @bug 8239893
* @summary Verify that handles for processes that terminate do not accumulate
* @requires ((os.family == "windows") & (vm.compMode != "Xcomp"))
+ * @library /test/lib
* @run main/othervm/native -Xint CheckHandles
*/
public class CheckHandles {
- // Return the current process handle count
- private static native long getProcessHandleCount();
-
public static void main(String[] args) throws Exception {
- System.loadLibrary("CheckHandles");
-
System.out.println("mypid: " + ProcessHandle.current().pid());
// Warmup the process launch mechanism and vm to stabilize the number of handles in use
int MAX_WARMUP = 20;
- long prevCount = getProcessHandleCount();
+ long prevCount = FileUtils.getProcessHandleCount();
for (int i = 0; i < MAX_WARMUP; i++) {
oneProcess();
System.gc(); // an opportunity to close unreferenced handles
sleep(10);
- long count = getProcessHandleCount();
+ long count = FileUtils.getProcessHandleCount();
if (count < 0)
throw new AssertionError("getProcessHandleCount failed");
System.out.println("warmup handle delta: " + (count - prevCount));
@@ -61,7 +59,7 @@ public static void main(String[] args) throws Exception {
System.out.println("Warmup done");
System.out.println();
- prevCount = getProcessHandleCount();
+ prevCount = FileUtils.getProcessHandleCount();
long startHandles = prevCount;
long maxHandles = startHandles;
int MAX_SPAWN = 50;
@@ -70,7 +68,7 @@ public static void main(String[] args) throws Exception {
System.gc(); // an opportunity to close unreferenced handles
sleep(10);
- long count = getProcessHandleCount();
+ long count = FileUtils.getProcessHandleCount();
if (count < 0)
throw new AssertionError("getProcessHandleCount failed");
System.out.println("handle delta: " + (count - prevCount));
diff --git a/test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketLeak.java b/test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketLeak.java
new file mode 100644
index 0000000000000..dcca7246bcf78
--- /dev/null
+++ b/test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketLeak.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2020 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
+ * 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 javax.net.SocketFactory;
+import javax.net.ssl.SSLSocketFactory;
+
+import jdk.test.lib.util.FileUtils;
+
+/*
+ * @test
+ * @bug 8256818
+ * @summary Test that creating and closing SSL Sockets without bind/connect
+ * will not leave leaking socket file descriptors
+ * @library /test/lib
+ * @run main/othervm SSLSocketLeak
+ */
+public class SSLSocketLeak {
+
+ private static final int NUM_TEST_SOCK = 500;
+
+ public static void main(String[] args) throws IOException {
+ long fds_start = FileUtils.getProcessHandleCount();
+ System.out.println("FDs at the beginning: " + fds_start);
+
+ SocketFactory f = SSLSocketFactory.getDefault();
+ for (int i = 0; i < NUM_TEST_SOCK; i++) {
+ f.createSocket().close();
+ }
+
+ long fds_end = FileUtils.getProcessHandleCount();
+ System.out.println("FDs in the end: " + fds_end);
+
+ if ((fds_end - fds_start) > (NUM_TEST_SOCK / 10)) {
+ throw new RuntimeException("Too many open file descriptors. Looks leaky.");
+ }
+ }
+}
diff --git a/test/lib/jdk/test/lib/util/FileUtils.java b/test/lib/jdk/test/lib/util/FileUtils.java
index 5997696fa0188..14b70076af258 100644
--- a/test/lib/jdk/test/lib/util/FileUtils.java
+++ b/test/lib/jdk/test/lib/util/FileUtils.java
@@ -23,34 +23,34 @@
package jdk.test.lib.util;
-import jdk.test.lib.Platform;
-
import java.io.BufferedReader;
-import java.io.InputStreamReader;
import java.io.IOException;
+import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.UncheckedIOException;
import java.lang.ProcessBuilder.Redirect;
+import java.lang.management.ManagementFactory;
import java.nio.file.DirectoryNotEmptyException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
-import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.time.Instant;
-import java.time.Duration;
-import java.util.Arrays;
import java.util.ArrayList;
-import java.util.ArrayDeque;
+import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
+import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
-import java.util.concurrent.TimeUnit;
+
+import jdk.test.lib.Platform;
+
+import com.sun.management.UnixOperatingSystemMXBean;
/**
* Common library for various test file utility functions.
@@ -59,6 +59,7 @@ public final class FileUtils {
private static final boolean IS_WINDOWS = Platform.isWindows();
private static final int RETRY_DELETE_MILLIS = IS_WINDOWS ? 500 : 0;
private static final int MAX_RETRY_DELETE_TIMES = IS_WINDOWS ? 15 : 0;
+ private static volatile boolean nativeLibLoaded;
/**
* Deletes a file, retrying if necessary.
@@ -363,6 +364,21 @@ public static void listFileDescriptors(PrintStream ps) {
});
}
+ // Return the current process handle count
+ public static long getProcessHandleCount() {
+ if (IS_WINDOWS) {
+ if (!nativeLibLoaded) {
+ System.loadLibrary("FileUtils");
+ nativeLibLoaded = true;
+ }
+ return getWinProcessHandleCount();
+ } else {
+ return ((UnixOperatingSystemMXBean)ManagementFactory.getOperatingSystemMXBean()).getOpenFileDescriptorCount();
+ }
+ }
+
+ private static native long getWinProcessHandleCount();
+
// Possible command locations and arguments
static String[][] lsCommands = new String[][] {
{"/usr/bin/lsof", "-p"},
diff --git a/test/jdk/java/lang/ProcessBuilder/checkHandles/libCheckHandles.c b/test/lib/jdk/test/lib/util/libFileUtils.c
similarity index 93%
rename from test/jdk/java/lang/ProcessBuilder/checkHandles/libCheckHandles.c
rename to test/lib/jdk/test/lib/util/libFileUtils.c
index d23d3db6a10de..1af90afff49eb 100644
--- a/test/jdk/java/lang/ProcessBuilder/checkHandles/libCheckHandles.c
+++ b/test/lib/jdk/test/lib/util/libFileUtils.c
@@ -29,7 +29,7 @@
#include "jni.h"
#include
-JNIEXPORT jlong JNICALL Java_CheckHandles_getProcessHandleCount(JNIEnv *env)
+JNIEXPORT jlong JNICALL Java_jdk_test_lib_util_FileUtils_getWinProcessHandleCount(JNIEnv *env)
{
DWORD handleCount;
HANDLE handle = GetCurrentProcess();
From 3e89981d98b51b4012c492941bfdcf4106422632 Mon Sep 17 00:00:00 2001
From: Leonid Mesnik
Date: Wed, 2 Dec 2020 20:16:28 +0000
Subject: [PATCH 029/504] 8257623:
vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted001/TestDescription.java
shouldn't use timeout
Reviewed-by: sspitsyn, dcubed
---
.../ResourceExhausted/resexhausted001/TestDescription.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted001/TestDescription.java
index 58a1867a9fc77..3642f3ceb0ed1 100644
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted001/TestDescription.java
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted001/TestDescription.java
@@ -38,7 +38,7 @@
*
* @library /vmTestbase
* /test/lib
- * @run main/othervm/native/manual/timeout=240
+ * @run main/othervm/native/manual
* -agentlib:resexhausted=-waittime=5
* -XX:-UseGCOverheadLimit
* -Xms16m
From 7104400ad8b5864d646d2b2792f1fdb20d35eaef Mon Sep 17 00:00:00 2001
From: Vladimir Ivanov
Date: Wed, 2 Dec 2020 21:47:27 +0000
Subject: [PATCH 030/504] 8257164: Share LambdaForms for VH linkers/invokers
Reviewed-by: redestad, kvn, psandoz
---
.../classes/java/lang/invoke/Invokers.java | 58 +++++++++++--------
.../java/lang/invoke/MethodHandleNatives.java | 2 +-
.../java/lang/invoke/MethodTypeForm.java | 5 +-
3 files changed, 38 insertions(+), 27 deletions(-)
diff --git a/src/java.base/share/classes/java/lang/invoke/Invokers.java b/src/java.base/share/classes/java/lang/invoke/Invokers.java
index 3a9ef635181be..65907fd52141c 100644
--- a/src/java.base/share/classes/java/lang/invoke/Invokers.java
+++ b/src/java.base/share/classes/java/lang/invoke/Invokers.java
@@ -139,7 +139,7 @@ private MethodHandle makeVarHandleMethodInvoker(VarHandle.AccessMode ak, boolean
MethodType mtype = targetType;
MethodType invokerType = mtype.insertParameterTypes(0, VarHandle.class);
- LambdaForm lform = varHandleMethodInvokerHandleForm(ak, mtype, isExact);
+ LambdaForm lform = varHandleMethodInvokerHandleForm(mtype, isExact);
VarHandle.AccessDescriptor ad = new VarHandle.AccessDescriptor(mtype, ak.at.ordinal(), ak.ordinal());
MethodHandle invoker = BoundMethodHandle.bindSingle(invokerType, lform, ad);
@@ -346,20 +346,22 @@ static LambdaForm invokeHandleForm(MethodType mtype, boolean customized, int whi
}
- static MemberName varHandleInvokeLinkerMethod(VarHandle.AccessMode ak, MethodType mtype) {
- LambdaForm lform;
- if (mtype.parameterSlotCount() <= MethodType.MAX_MH_ARITY - MH_LINKER_ARG_APPENDED) {
- lform = varHandleMethodGenericLinkerHandleForm(ak, mtype);
- } else {
- // TODO
+ static MemberName varHandleInvokeLinkerMethod(MethodType mtype) {
+ if (mtype.parameterSlotCount() > MethodType.MAX_MH_ARITY - MH_LINKER_ARG_APPENDED) {
throw newInternalError("Unsupported parameter slot count " + mtype.parameterSlotCount());
}
+ LambdaForm lform = varHandleMethodGenericLinkerHandleForm(mtype);
return lform.vmentry;
}
- private static LambdaForm varHandleMethodGenericLinkerHandleForm(VarHandle.AccessMode ak,
- MethodType mtype) {
- // TODO Cache form?
+ private static LambdaForm varHandleMethodGenericLinkerHandleForm(MethodType mtype) {
+ mtype = mtype.basicType(); // normalize Z to I, String to Object, etc.
+
+ int which = MethodTypeForm.LF_VH_GEN_LINKER;
+ LambdaForm lform = mtype.form().cachedLambdaForm(which);
+ if (lform != null) {
+ return lform;
+ }
final int THIS_VH = 0;
final int ARG_BASE = THIS_VH + 1;
@@ -396,19 +398,26 @@ private static LambdaForm varHandleMethodGenericLinkerHandleForm(VarHandle.Acces
MethodType outCallType = mtype.insertParameterTypes(0, VarHandle.class)
.basicType();
names[LINKER_CALL] = new Name(outCallType, outArgs);
- LambdaForm lform = new LambdaForm(ARG_LIMIT + 1, names, VARHANDLE_LINKER);
+ lform = new LambdaForm(ARG_LIMIT + 1, names, VARHANDLE_LINKER);
if (LambdaForm.debugNames()) {
- String name = ak.methodName() + ":VarHandle_invoke_MT_" +
- shortenSignature(basicTypeSignature(mtype));
+ String name = "VarHandle_invoke_MT_" + shortenSignature(basicTypeSignature(mtype));
LambdaForm.associateWithDebugName(lform, name);
}
lform.compileToBytecode();
+
+ lform = mtype.form().setCachedLambdaForm(which, lform);
+
return lform;
}
- private static LambdaForm varHandleMethodInvokerHandleForm(VarHandle.AccessMode ak,
- MethodType mtype, boolean isExact) {
- // TODO Cache form?
+ private static LambdaForm varHandleMethodInvokerHandleForm(MethodType mtype, boolean isExact) {
+ mtype = mtype.basicType(); // normalize Z to I, String to Object, etc.
+
+ int which = (isExact ? MethodTypeForm.LF_VH_EX_INVOKER : MethodTypeForm.LF_VH_GEN_INVOKER);
+ LambdaForm lform = mtype.form().cachedLambdaForm(which);
+ if (lform != null) {
+ return lform;
+ }
final int THIS_MH = 0;
final int CALL_VH = THIS_MH + 1;
@@ -448,17 +457,18 @@ private static LambdaForm varHandleMethodInvokerHandleForm(VarHandle.AccessMode
}
MethodType outCallType = mtype.insertParameterTypes(0, VarHandle.class)
- .basicType();
+ .basicType();
names[LINKER_CALL] = new Name(outCallType, outArgs);
Kind kind = isExact ? VARHANDLE_EXACT_INVOKER : VARHANDLE_INVOKER;
- LambdaForm lform = new LambdaForm(ARG_LIMIT, names, kind);
+ lform = new LambdaForm(ARG_LIMIT, names, kind);
if (LambdaForm.debugNames()) {
- String name = ak.methodName() +
- (isExact ? ":VarHandle_exactInvoker_" : ":VarHandle_invoker_") +
- shortenSignature(basicTypeSignature(mtype));
+ String name = (isExact ? "VarHandle_exactInvoker_" : "VarHandle_invoker_") + shortenSignature(basicTypeSignature(mtype));
LambdaForm.associateWithDebugName(lform, name);
}
lform.prepare();
+
+ lform = mtype.form().setCachedLambdaForm(which, lform);
+
return lform;
}
@@ -473,12 +483,10 @@ static MethodHandle checkVarHandleGenericType(VarHandle handle, VarHandle.Access
// Test for exact match on invoker types
// TODO match with erased types and add cast of return value to lambda form
MethodHandle mh = handle.getMethodHandle(ad.mode);
- if (mh.type() == ad.symbolicMethodTypeInvoker) {
- return mh;
- }
- else {
+ if (mh.type() != ad.symbolicMethodTypeInvoker) {
return mh.asType(ad.symbolicMethodTypeInvoker);
}
+ return mh;
}
@ForceInline
diff --git a/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java b/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java
index 0112120e98ed7..2d6925f206607 100644
--- a/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java
+++ b/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java
@@ -578,7 +578,7 @@ VarHandleGuards.class, getVarHandleGuardMethodName(guardType),
// Fall back to lambda form linkage if guard method is not available
// TODO Optionally log fallback ?
}
- return Invokers.varHandleInvokeLinkerMethod(ak, mtype);
+ return Invokers.varHandleInvokeLinkerMethod(mtype);
}
static String getVarHandleGuardMethodName(MethodType guardType) {
String prefix = "guard_";
diff --git a/src/java.base/share/classes/java/lang/invoke/MethodTypeForm.java b/src/java.base/share/classes/java/lang/invoke/MethodTypeForm.java
index ece336136e4d8..2c0e7f3d7d4e3 100644
--- a/src/java.base/share/classes/java/lang/invoke/MethodTypeForm.java
+++ b/src/java.base/share/classes/java/lang/invoke/MethodTypeForm.java
@@ -87,7 +87,10 @@ final class MethodTypeForm {
LF_LOOP = 19, // loop
LF_INVSPECIAL_IFC = 20, // DMH invokeSpecial of (private) interface method
LF_INVNATIVE = 21, // NMH invokeNative
- LF_LIMIT = 22;
+ LF_VH_EX_INVOKER = 22, // VarHandle exact invoker
+ LF_VH_GEN_INVOKER = 23, // VarHandle generic invoker
+ LF_VH_GEN_LINKER = 24, // VarHandle generic linker
+ LF_LIMIT = 25;
/** Return the type corresponding uniquely (1-1) to this MT-form.
* It might have any primitive returns or arguments, but will have no references except Object.
From 3da30e991a741fd985d844afe1be5a09c5d7d4a1 Mon Sep 17 00:00:00 2001
From: Calvin Cheung
Date: Wed, 2 Dec 2020 22:17:46 +0000
Subject: [PATCH 031/504] 8257241: CDS should not handle
disableEagerInitialization for archived lambda proxy classes
Reviewed-by: iklam, redestad, mchung
---
.../classfile/systemDictionaryShared.cpp | 7 +-
.../classfile/systemDictionaryShared.hpp | 3 +-
src/hotspot/share/include/jvm.h | 3 +-
src/hotspot/share/prims/jvm.cpp | 5 +-
.../invoke/InnerClassLambdaMetafactory.java | 58 ++++----
.../lang/invoke/LambdaProxyClassArchive.java | 10 +-
.../native/libjava/LambdaProxyClassArchive.c | 5 +-
.../runtime/cds/appcds/LambdaEagerInit.java | 133 ++++++++++++++++++
.../test-classes/LambdaEagerInitTest.java | 86 +++++++++++
9 files changed, 260 insertions(+), 50 deletions(-)
create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/LambdaEagerInit.java
create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/test-classes/LambdaEagerInitTest.java
diff --git a/src/hotspot/share/classfile/systemDictionaryShared.cpp b/src/hotspot/share/classfile/systemDictionaryShared.cpp
index 237116ce13e9a..9c68e5f1fe7b9 100644
--- a/src/hotspot/share/classfile/systemDictionaryShared.cpp
+++ b/src/hotspot/share/classfile/systemDictionaryShared.cpp
@@ -1684,8 +1684,7 @@ InstanceKlass* SystemDictionaryShared::get_shared_nest_host(InstanceKlass* lambd
}
InstanceKlass* SystemDictionaryShared::prepare_shared_lambda_proxy_class(InstanceKlass* lambda_ik,
- InstanceKlass* caller_ik,
- bool initialize, TRAPS) {
+ InstanceKlass* caller_ik, TRAPS) {
Handle class_loader(THREAD, caller_ik->class_loader());
Handle protection_domain;
PackageEntry* pkg_entry = get_package_entry_from_class_name(class_loader, caller_ik->name());
@@ -1726,9 +1725,7 @@ InstanceKlass* SystemDictionaryShared::prepare_shared_lambda_proxy_class(Instanc
SystemDictionary::post_class_load_event(&class_load_start_event, loaded_lambda, ClassLoaderData::class_loader_data(class_loader()));
}
- if (initialize) {
- loaded_lambda->initialize(CHECK_NULL);
- }
+ loaded_lambda->initialize(CHECK_NULL);
return loaded_lambda;
}
diff --git a/src/hotspot/share/classfile/systemDictionaryShared.hpp b/src/hotspot/share/classfile/systemDictionaryShared.hpp
index 92046292d752b..4da9beb834fb2 100644
--- a/src/hotspot/share/classfile/systemDictionaryShared.hpp
+++ b/src/hotspot/share/classfile/systemDictionaryShared.hpp
@@ -304,8 +304,7 @@ class SystemDictionaryShared: public SystemDictionary {
Symbol* instantiated_method_type) NOT_CDS_RETURN_(NULL);
static InstanceKlass* get_shared_nest_host(InstanceKlass* lambda_ik) NOT_CDS_RETURN_(NULL);
static InstanceKlass* prepare_shared_lambda_proxy_class(InstanceKlass* lambda_ik,
- InstanceKlass* caller_ik,
- bool initialize, TRAPS) NOT_CDS_RETURN_(NULL);
+ InstanceKlass* caller_ik, TRAPS) NOT_CDS_RETURN_(NULL);
static bool check_linking_constraints(InstanceKlass* klass, TRAPS) NOT_CDS_RETURN_(false);
static void record_linking_constraint(Symbol* name, InstanceKlass* klass,
Handle loader1, Handle loader2, TRAPS) NOT_CDS_RETURN;
diff --git a/src/hotspot/share/include/jvm.h b/src/hotspot/share/include/jvm.h
index f6e53e2dc3f8a..87e2c422fe533 100644
--- a/src/hotspot/share/include/jvm.h
+++ b/src/hotspot/share/include/jvm.h
@@ -194,8 +194,7 @@ JVM_LookupLambdaProxyClassFromArchive(JNIEnv* env, jclass caller,
jobject invokedType,
jobject methodType,
jobject implMethodMember,
- jobject instantiatedMethodType,
- jboolean initialize);
+ jobject instantiatedMethodType);
JNIEXPORT jboolean JNICALL
JVM_IsCDSDumpingEnabled(JNIEnv* env);
diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp
index 3bb1e7446b449..5c237dd6f243e 100644
--- a/src/hotspot/share/prims/jvm.cpp
+++ b/src/hotspot/share/prims/jvm.cpp
@@ -3825,8 +3825,7 @@ JVM_ENTRY(jclass, JVM_LookupLambdaProxyClassFromArchive(JNIEnv* env,
jobject invokedType,
jobject methodType,
jobject implMethodMember,
- jobject instantiatedMethodType,
- jboolean initialize))
+ jobject instantiatedMethodType))
JVMWrapper("JVM_LookupLambdaProxyClassFromArchive");
#if INCLUDE_CDS
@@ -3860,7 +3859,7 @@ JVM_ENTRY(jclass, JVM_LookupLambdaProxyClassFromArchive(JNIEnv* env,
method_type, m, instantiated_method_type);
jclass jcls = NULL;
if (lambda_ik != NULL) {
- InstanceKlass* loaded_lambda = SystemDictionaryShared::prepare_shared_lambda_proxy_class(lambda_ik, caller_ik, initialize, THREAD);
+ InstanceKlass* loaded_lambda = SystemDictionaryShared::prepare_shared_lambda_proxy_class(lambda_ik, caller_ik, THREAD);
jcls = loaded_lambda == NULL ? NULL : (jclass) JNIHandles::make_local(THREAD, loaded_lambda->java_mirror());
}
return jcls;
diff --git a/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java b/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java
index a6dbe6ef23f49..4d073178494c1 100644
--- a/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java
+++ b/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java
@@ -271,37 +271,37 @@ public Constructor>[] run() {
* registers the lambda proxy class for including into the CDS archive.
*/
private Class> spinInnerClass() throws LambdaConversionException {
- // include lambda proxy class in CDS archive at dump time
- if (CDS.isDumpingArchive()) {
- Class> innerClass = generateInnerClass();
- LambdaProxyClassArchive.register(targetClass,
- samMethodName,
- invokedType,
- samMethodType,
- implMethod,
- instantiatedMethodType,
- isSerializable,
- markerInterfaces,
- additionalBridges,
- innerClass);
- return innerClass;
- }
+ // CDS does not handle disableEagerInitialization.
+ if (!disableEagerInitialization) {
+ // include lambda proxy class in CDS archive at dump time
+ if (CDS.isDumpingArchive()) {
+ Class> innerClass = generateInnerClass();
+ LambdaProxyClassArchive.register(targetClass,
+ samMethodName,
+ invokedType,
+ samMethodType,
+ implMethod,
+ instantiatedMethodType,
+ isSerializable,
+ markerInterfaces,
+ additionalBridges,
+ innerClass);
+ return innerClass;
+ }
- // load from CDS archive if present
- Class> innerClass = LambdaProxyClassArchive.find(targetClass,
- samMethodName,
- invokedType,
- samMethodType,
- implMethod,
- instantiatedMethodType,
- isSerializable,
- markerInterfaces,
- additionalBridges,
- !disableEagerInitialization);
- if (innerClass == null) {
- innerClass = generateInnerClass();
+ // load from CDS archive if present
+ Class> innerClass = LambdaProxyClassArchive.find(targetClass,
+ samMethodName,
+ invokedType,
+ samMethodType,
+ implMethod,
+ instantiatedMethodType,
+ isSerializable,
+ markerInterfaces,
+ additionalBridges);
+ if (innerClass != null) return innerClass;
}
- return innerClass;
+ return generateInnerClass();
}
/**
diff --git a/src/java.base/share/classes/java/lang/invoke/LambdaProxyClassArchive.java b/src/java.base/share/classes/java/lang/invoke/LambdaProxyClassArchive.java
index 438bfd0210f9d..40f1467c045d1 100644
--- a/src/java.base/share/classes/java/lang/invoke/LambdaProxyClassArchive.java
+++ b/src/java.base/share/classes/java/lang/invoke/LambdaProxyClassArchive.java
@@ -50,8 +50,7 @@ private static native Class> findFromArchive(Class> caller,
MethodType invokedType,
MethodType samMethodType,
MemberName implMethod,
- MethodType instantiatedMethodType,
- boolean initialize);
+ MethodType instantiatedMethodType);
/**
* Registers the lambdaProxyClass into CDS archive.
@@ -101,16 +100,15 @@ static Class> find(Class> caller,
MethodType instantiatedMethodType,
boolean isSerializable,
Class>[] markerInterfaces,
- MethodType[] additionalBridges,
- boolean initialize) {
+ MethodType[] additionalBridges) {
if (CDS.isDumpingArchive())
throw new IllegalStateException("cannot load class from CDS archive at dump time");
- if (!loadedByBuiltinLoader(caller) || !initialize ||
+ if (!loadedByBuiltinLoader(caller) ||
!CDS.isSharingEnabled() || isSerializable || markerInterfaces.length > 0 || additionalBridges.length > 0)
return null;
return findFromArchive(caller, invokedName, invokedType, samMethodType,
- implMethod.internalMemberName(), instantiatedMethodType, initialize);
+ implMethod.internalMemberName(), instantiatedMethodType);
}
}
diff --git a/src/java.base/share/native/libjava/LambdaProxyClassArchive.c b/src/java.base/share/native/libjava/LambdaProxyClassArchive.c
index 5d87535926ef4..b77376602f889 100644
--- a/src/java.base/share/native/libjava/LambdaProxyClassArchive.c
+++ b/src/java.base/share/native/libjava/LambdaProxyClassArchive.c
@@ -51,9 +51,8 @@ Java_java_lang_invoke_LambdaProxyClassArchive_findFromArchive(JNIEnv *env, jclas
jobject invokedType,
jobject methodType,
jobject implMethodMember,
- jobject instantiatedMethodType,
- jboolean initialize) {
+ jobject instantiatedMethodType) {
return JVM_LookupLambdaProxyClassFromArchive(env, caller, invokedName, invokedType,
methodType, implMethodMember,
- instantiatedMethodType, initialize);
+ instantiatedMethodType);
}
diff --git a/test/hotspot/jtreg/runtime/cds/appcds/LambdaEagerInit.java b/test/hotspot/jtreg/runtime/cds/appcds/LambdaEagerInit.java
new file mode 100644
index 0000000000000..79667bc4df1cc
--- /dev/null
+++ b/test/hotspot/jtreg/runtime/cds/appcds/LambdaEagerInit.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 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
+ * @bug 8257241
+ * @summary Run the LambdaEagerInitTest.java test in static CDS archive mode.
+ * Create a custom base archive with the -Djdk.internal.lambda.disableEagerInitialization=true property.
+ * Run with the custom base archive with and without specifying the property.
+ * With the disableEagerInit set to true during dump time, lambda proxy classes
+ * will not be archived. During runtime, lambda proxy classes will not be loaded
+ * from the archive.
+ * Run with the default CDS archive, lambda proxy classes will be loaded
+ * from the archive if the property is not set.
+ * @requires vm.cds
+ * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds test-classes
+ * @run main/othervm LambdaEagerInit
+ */
+
+import java.io.File;
+
+import jdk.test.lib.cds.CDSOptions;
+import jdk.test.lib.cds.CDSTestUtils;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class LambdaEagerInit {
+ public static void main(String[] args) throws Exception {
+ createArchiveWithEagerInitializationEnabled();
+ testWithEagerInitializationEnabled();
+ testWithEagerInitializationDisabled();
+ // Skip testing with default CDS archive on aarch64 platform because
+ // default archive isn't being generated on that platform.
+ if (!("aarch64".equals(System.getProperty("os.arch")))) {
+ testDefaultArchiveWithEagerInitializationEnabled();
+ testDefaultArchiveWithEagerInitializationDisabled();
+ }
+ }
+
+ private static final String classDir = System.getProperty("test.classes");
+ private static final String mainClass = LambdaEagerInitTest.class.getName();
+ private static final String testProperty = "-Djdk.internal.lambda.disableEagerInitialization=true";
+ private static final String lambdaNotLoadedFromArchive =
+ ".class.load. java.util.stream.Collectors[$][$]Lambda[$].*/0x.*source:.*java.*util.*stream.*Collectors";
+ private static final String lambdaLoadedFromArchive =
+ ".class.load. java.util.stream.Collectors[$][$]Lambda[$].*/0x.*source:.*shared.*objects.*file";
+ private static final String cdsLoadedLambdaProxy = ".cds.*Loaded.*lambda.*proxy";
+ private static final String archiveName = mainClass + ".jsa";
+ private static String appJar;
+
+ static void createArchiveWithEagerInitializationEnabled() throws Exception {
+ appJar = JarBuilder.build("lambda_eager", new File(classDir), null);
+
+ // create base archive with the -Djdk.internal.lambda.disableEagerInitialization=true property
+ CDSOptions opts = (new CDSOptions())
+ .addPrefix(testProperty,
+ "-Xlog:class+load,cds")
+ .setArchiveName(archiveName);
+ CDSTestUtils.createArchiveAndCheck(opts);
+ }
+
+ static void testWithEagerInitializationEnabled() throws Exception {
+ // run with custom base archive with the -Djdk.internal.lambda.disableEagerInitialization=true property
+ CDSOptions runOpts = (new CDSOptions())
+ .addPrefix("-cp", appJar, testProperty, "-Xlog:class+load,cds=debug")
+ .setArchiveName(archiveName)
+ .setUseVersion(false)
+ .addSuffix(mainClass);
+ OutputAnalyzer output = CDSTestUtils.runWithArchive(runOpts);
+ output.shouldMatch(lambdaNotLoadedFromArchive)
+ .shouldNotMatch(cdsLoadedLambdaProxy)
+ .shouldHaveExitValue(0);
+ }
+
+ static void testWithEagerInitializationDisabled() throws Exception {
+ // run with custom base archive without the -Djdk.internal.lambda.disableEagerInitialization=true property
+ CDSOptions runOpts = (new CDSOptions())
+ .addPrefix("-cp", appJar, "-Xlog:class+load,cds=debug")
+ .setArchiveName(archiveName)
+ .setUseVersion(false)
+ .addSuffix(mainClass);
+ OutputAnalyzer output = CDSTestUtils.runWithArchive(runOpts);
+ output.shouldMatch(lambdaNotLoadedFromArchive)
+ .shouldNotMatch(cdsLoadedLambdaProxy)
+ .shouldHaveExitValue(0);
+ }
+
+ static void testDefaultArchiveWithEagerInitializationEnabled() throws Exception {
+ // run with default CDS archive with the -Djdk.internal.lambda.disableEagerInitialization=true property
+ CDSOptions runOpts = (new CDSOptions())
+ .addPrefix("-cp", appJar, testProperty, "-Xlog:class+load,cds=debug")
+ .setUseSystemArchive(true)
+ .setUseVersion(false)
+ .addSuffix(mainClass);
+ OutputAnalyzer output = CDSTestUtils.runWithArchive(runOpts);
+ output.shouldMatch(lambdaNotLoadedFromArchive)
+ .shouldNotMatch(cdsLoadedLambdaProxy)
+ .shouldHaveExitValue(0);
+ }
+
+ static void testDefaultArchiveWithEagerInitializationDisabled() throws Exception {
+ // run with default CDS archive without the -Djdk.internal.lambda.disableEagerInitialization=true property
+ CDSOptions runOpts = (new CDSOptions())
+ .addPrefix("-cp", appJar, "-Xlog:class+load,cds=debug")
+ .setUseSystemArchive(true)
+ .setUseVersion(false)
+ .addSuffix(mainClass);
+ OutputAnalyzer output = CDSTestUtils.runWithArchive(runOpts);
+ output.shouldMatch(lambdaLoadedFromArchive)
+ .shouldMatch(cdsLoadedLambdaProxy)
+ .shouldHaveExitValue(0);
+ }
+}
diff --git a/test/hotspot/jtreg/runtime/cds/appcds/test-classes/LambdaEagerInitTest.java b/test/hotspot/jtreg/runtime/cds/appcds/test-classes/LambdaEagerInitTest.java
new file mode 100644
index 0000000000000..c40b07db41e05
--- /dev/null
+++ b/test/hotspot/jtreg/runtime/cds/appcds/test-classes/LambdaEagerInitTest.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 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.
+ */
+
+/*
+ * This file is copied from open/test/jdk/java/lang/invoke/lambda.
+ * It is being used as the main class for the appcds/LambdaEagerInit.java test.
+ */
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static jdk.test.lib.Asserts.*;
+
+public class LambdaEagerInitTest {
+
+ interface H {Object m(String s);}
+
+ private static Set allowedStaticFields(boolean nonCapturing) {
+ Set s = new HashSet<>();
+ if (Boolean.getBoolean("jdk.internal.lambda.disableEagerInitialization")) {
+ if (nonCapturing) s.add("LAMBDA_INSTANCE$");
+ }
+ return s;
+ }
+
+ private void nonCapturingLambda() {
+ H la = s -> s;
+ assertEquals("hi", la.m("hi"));
+ Class extends H> c1 = la.getClass();
+ verifyLambdaClass(la.getClass(), true);
+ }
+
+ private void capturingLambda() {
+ H la = s -> concat(s, "foo");
+ assertEquals("hi foo", la.m("hi"));
+ verifyLambdaClass(la.getClass(), false);
+ }
+
+ private void verifyLambdaClass(Class> c, boolean nonCapturing) {
+ Set staticFields = new HashSet<>();
+ Set instanceFields = new HashSet<>();
+ for (Field f : c.getDeclaredFields()) {
+ if (Modifier.isStatic(f.getModifiers())) {
+ staticFields.add(f.getName());
+ } else {
+ instanceFields.add(f.getName());
+ }
+ }
+ assertEquals(instanceFields.size(), nonCapturing ? 0 : 1, "Unexpected instance fields");
+ assertEquals(staticFields, allowedStaticFields(nonCapturing), "Unexpected static fields");
+ }
+
+ private String concat(String... ss) {
+ return Arrays.stream(ss).collect(Collectors.joining(" "));
+ }
+
+ public static void main(String[] args) {
+ LambdaEagerInitTest test = new LambdaEagerInitTest();
+ test.nonCapturingLambda();
+ test.capturingLambda();
+ }
+}
From cc1915b3b320d9729772a81642cf5ca6563094cd Mon Sep 17 00:00:00 2001
From: Anthony Scarpino
Date: Wed, 2 Dec 2020 23:10:32 +0000
Subject: [PATCH 032/504] 8253821: Improve ByteBuffer performance with GCM
Reviewed-by: xuelei, valeriep
---
.../com/sun/crypto/provider/AESCipher.java | 41 +-
.../com/sun/crypto/provider/CipherCore.java | 59 +-
.../sun/crypto/provider/FeedbackCipher.java | 24 +
.../classes/com/sun/crypto/provider/GCTR.java | 114 ++-
.../com/sun/crypto/provider/GHASH.java | 33 +
.../crypto/provider/GaloisCounterMode.java | 475 +++++++++-
.../provider/Cipher/AEAD/GCMBufferTest.java | 851 ++++++++++++++++++
.../Cipher/AEAD/GCMIncrementByte4.java | 43 +
.../Cipher/AEAD/GCMIncrementDirect4.java | 41 +
.../Cipher/AEAD/OverlapByteBuffer.java | 159 ++++
.../provider/Cipher/AEAD/SameBuffer.java | 11 +
.../provider/Cipher/AES/TestKATForGCM.java | 239 +++--
.../TextLength/SameBufferOverwrite.java | 128 +++
.../CipherByteBufferOverwriteTest.java | 58 +-
.../ssl/SSLSession/CheckSessionContext.java | 21 +
15 files changed, 2137 insertions(+), 160 deletions(-)
create mode 100644 test/jdk/com/sun/crypto/provider/Cipher/AEAD/GCMBufferTest.java
create mode 100644 test/jdk/com/sun/crypto/provider/Cipher/AEAD/GCMIncrementByte4.java
create mode 100644 test/jdk/com/sun/crypto/provider/Cipher/AEAD/GCMIncrementDirect4.java
create mode 100644 test/jdk/com/sun/crypto/provider/Cipher/AEAD/OverlapByteBuffer.java
create mode 100644 test/jdk/com/sun/crypto/provider/Cipher/TextLength/SameBufferOverwrite.java
diff --git a/src/java.base/share/classes/com/sun/crypto/provider/AESCipher.java b/src/java.base/share/classes/com/sun/crypto/provider/AESCipher.java
index e7669109e1294..d0f9f9886b1d4 100644
--- a/src/java.base/share/classes/com/sun/crypto/provider/AESCipher.java
+++ b/src/java.base/share/classes/com/sun/crypto/provider/AESCipher.java
@@ -25,12 +25,21 @@
package com.sun.crypto.provider;
-import java.security.*;
-import java.security.spec.*;
-import javax.crypto.*;
-import javax.crypto.spec.*;
import javax.crypto.BadPaddingException;
+import javax.crypto.CipherSpi;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.ShortBufferException;
import java.nio.ByteBuffer;
+import java.security.AlgorithmParameters;
+import java.security.GeneralSecurityException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.ProviderException;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
/**
* This class implements the AES algorithm in its various modes
@@ -411,6 +420,7 @@ protected int engineUpdate(byte[] input, int inputOffset, int inputLen,
outputOffset);
}
+
/**
* Encrypts or decrypts data in a single-part operation,
* or finishes a multiple-part operation.
@@ -641,5 +651,26 @@ protected void engineUpdateAAD(ByteBuffer src) {
}
}
}
-}
+ /**
+ * Finalize crypto operation with ByteBuffers
+ *
+ * @param input the input ByteBuffer
+ * @param output the output ByteBuffer
+ *
+ * @return output length
+ * @throws ShortBufferException
+ * @throws IllegalBlockSizeException
+ * @throws BadPaddingException
+ */
+ @Override
+ protected int engineDoFinal(ByteBuffer input, ByteBuffer output)
+ throws ShortBufferException, IllegalBlockSizeException,
+ BadPaddingException {
+ if (core.getMode() == CipherCore.GCM_MODE && !input.hasArray()) {
+ return core.gcmDoFinal(input, output);
+ } else {
+ return super.engineDoFinal(input, output);
+ }
+ }
+}
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 ddee737674a34..c804bcc00b2c6 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
@@ -25,6 +25,7 @@
package com.sun.crypto.provider;
+import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Locale;
@@ -722,8 +723,7 @@ int update(byte[] input, int inputOffset, int inputLen, byte[] output,
len = (len > 0 ? (len - (len % unitBytes)) : 0);
// check output buffer capacity
- if ((output == null) ||
- ((output.length - outputOffset) < len)) {
+ if (output == null || (output.length - outputOffset) < len) {
throw new ShortBufferException("Output buffer must be "
+ "(at least) " + len
+ " bytes long");
@@ -917,10 +917,10 @@ int doFinal(byte[] input, int inputOffset, int inputLen, byte[] output,
int estOutSize = getOutputSizeByOperation(inputLen, true);
int outputCapacity = checkOutputCapacity(output, outputOffset,
estOutSize);
- int offset = decrypting ? 0 : outputOffset; // 0 for decrypting
+ int offset = outputOffset;
byte[] finalBuf = prepareInputBuffer(input, inputOffset,
inputLen, output, outputOffset);
- byte[] outWithPadding = null; // for decrypting only
+ byte[] internalOutput = null; // for decrypting only
int finalOffset = (finalBuf == input) ? inputOffset : 0;
int finalBufLen = (finalBuf == input) ? inputLen : finalBuf.length;
@@ -934,11 +934,14 @@ int doFinal(byte[] input, int inputOffset, int inputLen, byte[] output,
if (outputCapacity < estOutSize) {
cipher.save();
}
- // create temporary output buffer so that only "real"
- // data bytes are passed to user's output buffer.
- outWithPadding = new byte[estOutSize];
+ if (getMode() != GCM_MODE || outputCapacity < estOutSize) {
+ // create temporary output buffer if the estimated size is larger
+ // than the user-provided buffer.
+ internalOutput = new byte[estOutSize];
+ offset = 0;
+ }
}
- byte[] outBuffer = decrypting ? outWithPadding : output;
+ byte[] outBuffer = (internalOutput != null) ? internalOutput : output;
int outLen = fillOutputBuffer(finalBuf, finalOffset, outBuffer,
offset, finalBufLen, input);
@@ -954,9 +957,11 @@ int doFinal(byte[] input, int inputOffset, int inputLen, byte[] output,
+ " bytes needed");
}
// copy the result into user-supplied output buffer
- System.arraycopy(outWithPadding, 0, output, outputOffset, outLen);
- // decrypt mode. Zero out output data that's not required
- Arrays.fill(outWithPadding, (byte) 0x00);
+ if (internalOutput != null) {
+ System.arraycopy(internalOutput, 0, output, outputOffset, outLen);
+ // decrypt mode. Zero out output data that's not required
+ Arrays.fill(internalOutput, (byte) 0x00);
+ }
}
endDoFinal();
return outLen;
@@ -970,16 +975,15 @@ private void endDoFinal() {
}
}
- private int unpad(int outLen, byte[] outWithPadding)
+ private int unpad(int outLen, int off, byte[] outWithPadding)
throws BadPaddingException {
- int padStart = padding.unpad(outWithPadding, 0, outLen);
+ int padStart = padding.unpad(outWithPadding, off, outLen);
if (padStart < 0) {
throw new BadPaddingException("Given final block not " +
"properly padded. Such issues can arise if a bad key " +
"is used during decryption.");
}
- outLen = padStart;
- return outLen;
+ return padStart - off;
}
private byte[] prepareInputBuffer(byte[] input, int inputOffset,
@@ -1055,7 +1059,7 @@ private int fillOutputBuffer(byte[] finalBuf, int finalOffset,
len = finalNoPadding(finalBuf, finalOffset, output,
outOfs, finalBufLen);
if (decrypting && padding != null) {
- len = unpad(len, output);
+ len = unpad(len, outOfs, output);
}
return len;
} finally {
@@ -1225,4 +1229,27 @@ void updateAAD(byte[] src, int offset, int len) {
checkReinit();
cipher.updateAAD(src, offset, len);
}
+
+ // This must only be used with GCM.
+ // If some data has been buffered from an update call, operate on the buffer
+ // then run doFinal.
+ int gcmDoFinal(ByteBuffer src, ByteBuffer dst) throws ShortBufferException,
+ IllegalBlockSizeException, BadPaddingException {
+ int estOutSize = getOutputSizeByOperation(src.remaining(), true);
+ if (estOutSize > dst.remaining()) {
+ throw new ShortBufferException("output buffer too small");
+ }
+
+ if (decrypting) {
+ if (buffered > 0) {
+ cipher.decrypt(buffer, 0, buffered, new byte[0], 0);
+ }
+ return cipher.decryptFinal(src, dst);
+ } else {
+ if (buffered > 0) {
+ ((GaloisCounterMode)cipher).encrypt(buffer, 0, buffered);
+ }
+ return cipher.encryptFinal(src, dst);
+ }
+ }
}
diff --git a/src/java.base/share/classes/com/sun/crypto/provider/FeedbackCipher.java b/src/java.base/share/classes/com/sun/crypto/provider/FeedbackCipher.java
index a6d46adf0e391..c7bb57664a153 100644
--- a/src/java.base/share/classes/com/sun/crypto/provider/FeedbackCipher.java
+++ b/src/java.base/share/classes/com/sun/crypto/provider/FeedbackCipher.java
@@ -25,6 +25,7 @@
package com.sun.crypto.provider;
+import java.nio.ByteBuffer;
import java.security.InvalidKeyException;
import java.security.InvalidAlgorithmParameterException;
import javax.crypto.*;
@@ -242,4 +243,27 @@ int getBufferedLength() {
// internally during decryption mode
return 0;
}
+
+ /*
+ * ByteBuffer methods should not be accessed as CipherCore and AESCipher
+ * copy the data to byte arrays. These methods are to satisfy the compiler.
+ */
+ int encrypt(ByteBuffer src, ByteBuffer dst) {
+ throw new UnsupportedOperationException("ByteBuffer not supported");
+ };
+
+ int decrypt(ByteBuffer src, ByteBuffer dst) {
+ throw new UnsupportedOperationException("ByteBuffer not supported");
+ };
+
+ int encryptFinal(ByteBuffer src, ByteBuffer dst)
+ throws IllegalBlockSizeException, ShortBufferException {
+ throw new UnsupportedOperationException("ByteBuffer not supported");
+ };
+
+ int decryptFinal(ByteBuffer src, ByteBuffer dst)
+ throws IllegalBlockSizeException, AEADBadTagException,
+ ShortBufferException {
+ throw new UnsupportedOperationException("ByteBuffer not supported");
+ }
}
diff --git a/src/java.base/share/classes/com/sun/crypto/provider/GCTR.java b/src/java.base/share/classes/com/sun/crypto/provider/GCTR.java
index 60d26083b7fed..1a09a617a4d45 100644
--- a/src/java.base/share/classes/com/sun/crypto/provider/GCTR.java
+++ b/src/java.base/share/classes/com/sun/crypto/provider/GCTR.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -54,11 +54,15 @@
*/
final class GCTR extends CounterMode {
+ // Maximum buffer size rotating ByteBuffer->byte[] intrinsic copy
+ private static final int MAX_LEN = 1024;
+
GCTR(SymmetricCipher cipher, byte[] initialCounterBlk) {
super(cipher);
if (initialCounterBlk.length != AES_BLOCK_SIZE) {
- throw new RuntimeException("length of initial counter block (" + initialCounterBlk.length +
- ") not equal to AES_BLOCK_SIZE (" + AES_BLOCK_SIZE + ")");
+ throw new RuntimeException("length of initial counter block (" +
+ initialCounterBlk.length + ") not equal to AES_BLOCK_SIZE (" +
+ AES_BLOCK_SIZE + ")");
}
iv = initialCounterBlk;
@@ -112,9 +116,89 @@ int update(byte[] in, int inOfs, int inLen, byte[] out, int outOfs) {
}
}
+ // input must be multiples of AES blocks, 128-bit, when calling update
+ int update(byte[] in, int inOfs, int inLen, ByteBuffer dst) {
+ if (inLen - inOfs > in.length) {
+ throw new RuntimeException("input length out of bound");
+ }
+ if (inLen < 0 || inLen % AES_BLOCK_SIZE != 0) {
+ throw new RuntimeException("input length unsupported");
+ }
+ // See GaloisCounterMode. decryptFinal(bytebuffer, bytebuffer) for
+ // details on the check for 'dst' having enough space for the result.
+
+ long blocksLeft = blocksUntilRollover();
+ int numOfCompleteBlocks = inLen / AES_BLOCK_SIZE;
+ if (numOfCompleteBlocks >= blocksLeft) {
+ // Counter Mode encryption cannot be used because counter will
+ // roll over incorrectly. Use GCM-specific code instead.
+ byte[] encryptedCntr = new byte[AES_BLOCK_SIZE];
+ for (int i = 0; i < numOfCompleteBlocks; i++) {
+ embeddedCipher.encryptBlock(counter, 0, encryptedCntr, 0);
+ for (int n = 0; n < AES_BLOCK_SIZE; n++) {
+ int index = (i * AES_BLOCK_SIZE + n);
+ dst.put((byte) ((in[inOfs + index] ^ encryptedCntr[n])));
+ }
+ GaloisCounterMode.increment32(counter);
+ }
+ return inLen;
+ } else {
+ int len = inLen - inLen % AES_BLOCK_SIZE;
+ int processed = len;
+ byte[] out = new byte[Math.min(MAX_LEN, len)];
+ int offset = inOfs;
+ while (processed > MAX_LEN) {
+ encrypt(in, offset, MAX_LEN, out, 0);
+ dst.put(out, 0, MAX_LEN);
+ processed -= MAX_LEN;
+ offset += MAX_LEN;
+ }
+ encrypt(in, offset, processed, out, 0);
+ // If dst is less than blocksize, insert only what it can. Extra
+ // bytes would cause buffers with enough size to fail with a
+ // short buffer
+ dst.put(out, 0, Math.min(dst.remaining(), processed));
+ return len;
+ }
+ }
+
+ // input operates on multiples of AES blocks, 128-bit, when calling update.
+ // The remainder is left in the src buffer.
+ int update(ByteBuffer src, ByteBuffer dst) {
+ long blocksLeft = blocksUntilRollover();
+ int numOfCompleteBlocks = src.remaining() / AES_BLOCK_SIZE;
+ if (numOfCompleteBlocks >= blocksLeft) {
+ // Counter Mode encryption cannot be used because counter will
+ // roll over incorrectly. Use GCM-specific code instead.
+ byte[] encryptedCntr = new byte[AES_BLOCK_SIZE];
+ for (int i = 0; i < numOfCompleteBlocks; i++) {
+ embeddedCipher.encryptBlock(counter, 0, encryptedCntr, 0);
+ for (int n = 0; n < AES_BLOCK_SIZE; n++) {
+ dst.put((byte) (src.get() ^ encryptedCntr[n]));
+ }
+ GaloisCounterMode.increment32(counter);
+ }
+ return numOfCompleteBlocks * AES_BLOCK_SIZE;
+ }
+
+ int len = src.remaining() - (src.remaining() % AES_BLOCK_SIZE);
+ int processed = len;
+ byte[] in = new byte[Math.min(MAX_LEN, len)];
+ while (processed > MAX_LEN) {
+ src.get(in, 0, MAX_LEN);
+ encrypt(in, 0, MAX_LEN, in, 0);
+ dst.put(in, 0, MAX_LEN);
+ processed -= MAX_LEN;
+ }
+ src.get(in, 0, processed);
+ encrypt(in, 0, processed, in, 0);
+ dst.put(in, 0, processed);
+ return len;
+ }
+
// input can be arbitrary size when calling doFinal
int doFinal(byte[] in, int inOfs, int inLen, byte[] out,
- int outOfs) throws IllegalBlockSizeException {
+ int outOfs) throws IllegalBlockSizeException {
try {
if (inLen < 0) {
throw new IllegalBlockSizeException("Negative input size!");
@@ -130,7 +214,7 @@ int doFinal(byte[] in, int inOfs, int inLen, byte[] out,
for (int n = 0; n < lastBlockSize; n++) {
out[outOfs + completeBlkLen + n] =
(byte) ((in[inOfs + completeBlkLen + n] ^
- encryptedCntr[n]));
+ encryptedCntr[n]));
}
}
}
@@ -139,4 +223,24 @@ int doFinal(byte[] in, int inOfs, int inLen, byte[] out,
}
return inLen;
}
+
+ // src can be arbitrary size when calling doFinal
+ int doFinal(ByteBuffer src, ByteBuffer dst) {
+ int len = src.remaining();
+ int lastBlockSize = len % AES_BLOCK_SIZE;
+ try {
+ update(src, dst);
+ if (lastBlockSize != 0) {
+ // do the last partial block
+ byte[] encryptedCntr = new byte[AES_BLOCK_SIZE];
+ embeddedCipher.encryptBlock(counter, 0, encryptedCntr, 0);
+ for (int n = 0; n < lastBlockSize; n++) {
+ dst.put((byte) (src.get() ^ encryptedCntr[n]));
+ }
+ }
+ } finally {
+ reset();
+ }
+ return len;
+ }
}
diff --git a/src/java.base/share/classes/com/sun/crypto/provider/GHASH.java b/src/java.base/share/classes/com/sun/crypto/provider/GHASH.java
index 7ee114624eeff..e9ce33b6b582b 100644
--- a/src/java.base/share/classes/com/sun/crypto/provider/GHASH.java
+++ b/src/java.base/share/classes/com/sun/crypto/provider/GHASH.java
@@ -29,6 +29,7 @@
package com.sun.crypto.provider;
+import java.nio.ByteBuffer;
import java.security.ProviderException;
import jdk.internal.vm.annotation.IntrinsicCandidate;
@@ -198,6 +199,38 @@ void update(byte[] in, int inOfs, int inLen) {
processBlocks(in, inOfs, inLen/AES_BLOCK_SIZE, state, subkeyHtbl);
}
+ // Maximum buffer size rotating ByteBuffer->byte[] intrinsic copy
+ private static final int MAX_LEN = 1024;
+
+ // Will process as many blocks it can and will leave the remaining.
+ int update(ByteBuffer src, int inLen) {
+ inLen -= (inLen % AES_BLOCK_SIZE);
+ if (inLen == 0) {
+ return 0;
+ }
+
+ int processed = inLen;
+ byte[] in = new byte[Math.min(MAX_LEN, inLen)];
+ while (processed > MAX_LEN ) {
+ src.get(in, 0, MAX_LEN);
+ update(in, 0 , MAX_LEN);
+ processed -= MAX_LEN;
+ }
+ src.get(in, 0, processed);
+ update(in, 0, processed);
+ return inLen;
+ }
+
+ void doLastBlock(ByteBuffer src, int inLen) {
+ int processed = update(src, inLen);
+ if (inLen == processed) {
+ return;
+ }
+ byte[] block = new byte[AES_BLOCK_SIZE];
+ src.get(block, 0, inLen - processed);
+ update(block, 0, AES_BLOCK_SIZE);
+ }
+
private static void ghashRangeCheck(byte[] in, int inOfs, int inLen, long[] st, long[] subH) {
if (inLen < 0) {
throw new RuntimeException("invalid input length: " + inLen);
diff --git a/src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java b/src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java
index 178bdb024a2bc..cde13fff1c247 100644
--- a/src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java
+++ b/src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java
@@ -25,13 +25,21 @@
package com.sun.crypto.provider;
-import java.util.Arrays;
-import java.io.*;
-import java.security.*;
-import javax.crypto.*;
-import static com.sun.crypto.provider.AESConstants.AES_BLOCK_SIZE;
+import sun.nio.ch.DirectBuffer;
import sun.security.util.ArrayUtil;
+import javax.crypto.AEADBadTagException;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.ShortBufferException;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.ProviderException;
+
+import static com.sun.crypto.provider.AESConstants.AES_BLOCK_SIZE;
+
/**
* This class represents ciphers in GaloisCounter (GCM) mode.
@@ -68,9 +76,12 @@ final class GaloisCounterMode extends FeedbackCipher {
private ByteArrayOutputStream aadBuffer = new ByteArrayOutputStream();
private int sizeOfAAD = 0;
- // buffer for storing input in decryption, not used for encryption
+ // buffer data for crypto operation
private ByteArrayOutputStream ibuffer = null;
+ // Original dst buffer if there was an overlap situation
+ private ByteBuffer originalDst = null;
+
// in bytes; need to convert to bits (default value 128) when needed
private int tagLenBytes = DEFAULT_TAG_LEN;
@@ -177,8 +188,17 @@ private static byte[] getJ0(byte[] iv, byte[] subkeyH) {
return j0;
}
- private static void checkDataLength(int processed, int len) {
- if (processed > MAX_BUF_SIZE - len) {
+ /**
+ * Calculate if the given data lengths and the already processed data
+ * exceeds the maximum allowed processed data by GCM.
+ * @param lengths lengths of unprocessed data.
+ */
+ private void checkDataLength(int ... lengths) {
+ int max = MAX_BUF_SIZE;
+ for (int len : lengths) {
+ max = Math.subtractExact(max, len);
+ }
+ if (processed > max) {
throw new ProviderException("SunJCE provider only supports " +
"input size up to " + MAX_BUF_SIZE + " bytes");
}
@@ -426,6 +446,64 @@ void doLastBlock(byte[] in, int inOfs, int len, byte[] out, int outOfs,
}
}
+ // Process en/decryption all the way to the last block. It takes both
+ // For input it takes the ibuffer which is wrapped in 'buffer' and 'src'
+ // from doFinal.
+ void doLastBlock(ByteBuffer buffer, ByteBuffer src, ByteBuffer dst)
+ throws IllegalBlockSizeException {
+
+ if (buffer != null && buffer.remaining() > 0) {
+ // en/decrypt on how much buffer there is in AES_BLOCK_SIZE
+ processed += gctrPAndC.update(buffer, dst);
+
+ // Process the remainder in the buffer
+ if (buffer.remaining() > 0) {
+ // Copy the remainder of the buffer into the extra block
+ byte[] block = new byte[AES_BLOCK_SIZE];
+ int over = buffer.remaining();
+ int len = over; // how much is processed by in the extra block
+ buffer.get(block, 0, over);
+
+ // if src is empty, update the final block and wait for later
+ // to finalize operation
+ if (src.remaining() > 0) {
+ // Fill out block with what is in data
+ if (src.remaining() > AES_BLOCK_SIZE - over) {
+ src.get(block, over, AES_BLOCK_SIZE - over);
+ len += AES_BLOCK_SIZE - over;
+ } else {
+ // If the remaining in buffer + data does not fill a
+ // block, complete the ghash operation
+ int l = src.remaining();
+ src.get(block, over, l);
+ len += l;
+ }
+ }
+ gctrPAndC.update(block, 0, AES_BLOCK_SIZE, dst);
+ processed += len;
+ }
+ }
+
+ // en/decrypt whatever remains in src.
+ // If src has been consumed, this will be a no-op
+ processed += gctrPAndC.doFinal(src, dst);
+ }
+
+ /*
+ * This method is for CipherCore to insert the remainder of its buffer
+ * into the ibuffer before a doFinal(ByteBuffer, ByteBuffer) operation
+ */
+ int encrypt(byte[] in, int inOfs, int len) {
+ if (len > 0) {
+ // store internally until encryptFinal
+ ArrayUtil.nullAndBoundsCheck(in, inOfs, len);
+ if (ibuffer == null) {
+ ibuffer = new ByteArrayOutputStream();
+ }
+ ibuffer.write(in, inOfs, len);
+ }
+ return len;
+ }
/**
* Performs encryption operation.
@@ -436,32 +514,93 @@ void doLastBlock(byte[] in, int inOfs, int len, byte[] out, int outOfs,
*
* @param in the buffer with the input data to be encrypted
* @param inOfs the offset in in
- * @param len the length of the input data
+ * @param inLen the length of the input data
* @param out the buffer for the result
* @param outOfs the offset in out
- * @exception ProviderException if len
is not
- * a multiple of the block size
* @return the number of bytes placed into the out
buffer
*/
- int encrypt(byte[] in, int inOfs, int len, byte[] out, int outOfs) {
- ArrayUtil.blockSizeCheck(len, blockSize);
-
- checkDataLength(processed, len);
+ int encrypt(byte[] in, int inOfs, int inLen, byte[] out, int outOfs) {
+ checkDataLength(inLen, getBufferedLength());
+ ArrayUtil.nullAndBoundsCheck(in, inOfs, inLen);
+ ArrayUtil.nullAndBoundsCheck(out, outOfs, inLen);
processAAD();
+ // 'inLen' stores the length to use with buffer 'in'.
+ // 'len' stores the length returned by the method.
+ int len = inLen;
+
+ // if there is enough data in the ibuffer and 'in', encrypt it.
+ if (ibuffer != null && ibuffer.size() > 0) {
+ byte[] buffer = ibuffer.toByteArray();
+ // number of bytes not filling a block
+ int remainder = ibuffer.size() % blockSize;
+ // number of bytes along block boundary
+ int blen = ibuffer.size() - remainder;
+
+ // If there is enough bytes in ibuffer for a block or more,
+ // encrypt that first.
+ if (blen > 0) {
+ encryptBlocks(buffer, 0, blen, out, outOfs);
+ outOfs += blen;
+ }
- if (len > 0) {
- ArrayUtil.nullAndBoundsCheck(in, inOfs, len);
- ArrayUtil.nullAndBoundsCheck(out, outOfs, len);
+ // blen is now the offset for 'buffer'
+
+ // Construct and encrypt a block if there is enough 'buffer' and
+ // 'in' to make one
+ if ((inLen + remainder) >= blockSize) {
+ byte[] block = new byte[blockSize];
+
+ System.arraycopy(buffer, blen, block, 0, remainder);
+ int inLenUsed = blockSize - remainder;
+ System.arraycopy(in, inOfs, block, remainder, inLenUsed);
+
+ encryptBlocks(block, 0, blockSize, out, outOfs);
+ inOfs += inLenUsed;
+ inLen -= inLenUsed;
+ len += (blockSize - inLenUsed);
+ outOfs += blockSize;
+ ibuffer.reset();
+ // Code below will write the remainder from 'in' to ibuffer
+ } else if (remainder > 0) {
+ // If a block or more was encrypted from 'buffer' only, but the
+ // rest of 'buffer' with 'in' could not construct a block, then
+ // put the rest of 'buffer' back into ibuffer.
+ ibuffer.reset();
+ ibuffer.write(buffer, blen, remainder);
+ // Code below will write the remainder from 'in' to ibuffer
+ }
+ // If blen == 0 and there was not enough to construct a block
+ // from 'buffer' and 'in', then let the below code append 'in' to
+ // the ibuffer.
+ }
+
+ // Write any remaining bytes outside the blockSize into ibuffer.
+ int remainder = inLen % blockSize;
+ if (remainder > 0) {
+ if (ibuffer == null) {
+ ibuffer = new ByteArrayOutputStream(inLen % blockSize);
+ }
+ len -= remainder;
+ inLen -= remainder;
+ // remainder offset is based on original buffer length
+ ibuffer.write(in, inOfs + inLen, remainder);
+ }
- gctrPAndC.update(in, inOfs, len, out, outOfs);
- processed += len;
- ghashAllToS.update(out, outOfs, len);
+ // Encrypt the remaining blocks inside of 'in'
+ if (inLen > 0) {
+ encryptBlocks(in, inOfs, inLen, out, outOfs);
}
return len;
}
+ void encryptBlocks(byte[] in, int inOfs, int len, byte[] out, int outOfs) {
+ gctrPAndC.update(in, inOfs, len, out, outOfs);
+ processed += len;
+ ghashAllToS.update(out, outOfs, len);
+ }
+
/**
* Performs encryption operation for the last time.
*
@@ -474,10 +613,8 @@ int encrypt(byte[] in, int inOfs, int len, byte[] out, int outOfs) {
*/
int encryptFinal(byte[] in, int inOfs, int len, byte[] out, int outOfs)
throws IllegalBlockSizeException, ShortBufferException {
- if (len > MAX_BUF_SIZE - tagLenBytes) {
- throw new ShortBufferException
- ("Can't fit both data and tag into one buffer");
- }
+ checkDataLength(len, getBufferedLength(), tagLenBytes);
+
try {
ArrayUtil.nullAndBoundsCheck(out, outOfs,
(len + tagLenBytes));
@@ -485,8 +622,6 @@ int encryptFinal(byte[] in, int inOfs, int len, byte[] out, int outOfs)
throw new ShortBufferException("Output buffer too small");
}
- checkDataLength(processed, len);
-
processAAD();
if (len > 0) {
ArrayUtil.nullAndBoundsCheck(in, inOfs, len);
@@ -494,15 +629,45 @@ int encryptFinal(byte[] in, int inOfs, int len, byte[] out, int outOfs)
doLastBlock(in, inOfs, len, out, outOfs, true);
}
- byte[] lengthBlock =
- getLengthBlock(sizeOfAAD, processed);
- ghashAllToS.update(lengthBlock);
- byte[] s = ghashAllToS.digest();
- byte[] sOut = new byte[s.length];
+ byte[] block = getLengthBlock(sizeOfAAD, processed);
+ ghashAllToS.update(block);
+ block = ghashAllToS.digest();
GCTR gctrForSToTag = new GCTR(embeddedCipher, this.preCounterBlock);
- gctrForSToTag.doFinal(s, 0, s.length, sOut, 0);
+ gctrForSToTag.doFinal(block, 0, tagLenBytes, block, 0);
+
+ System.arraycopy(block, 0, out, (outOfs + len), tagLenBytes);
+ return (len + tagLenBytes);
+ }
+
+ int encryptFinal(ByteBuffer src, ByteBuffer dst)
+ throws IllegalBlockSizeException, ShortBufferException {
+ dst = overlapDetection(src, dst);
+ int len = src.remaining();
+ len += getBufferedLength();
+
+ // 'len' includes ibuffer data
+ checkDataLength(len, tagLenBytes);
+ dst.mark();
+ if (dst.remaining() < len + tagLenBytes) {
+ throw new ShortBufferException("Output buffer too small");
+ }
+
+ processAAD();
+ if (len > 0) {
+ doLastBlock((ibuffer == null || ibuffer.size() == 0) ?
+ null : ByteBuffer.wrap(ibuffer.toByteArray()), src, dst);
+ dst.reset();
+ ghashAllToS.doLastBlock(dst, len);
+ }
+
+ byte[] block = getLengthBlock(sizeOfAAD, processed);
+ ghashAllToS.update(block);
+ block = ghashAllToS.digest();
+ GCTR gctrForSToTag = new GCTR(embeddedCipher, this.preCounterBlock);
+ gctrForSToTag.doFinal(block, 0, tagLenBytes, block, 0);
+ dst.put(block, 0, tagLenBytes);
+ restoreDst(dst);
- System.arraycopy(sOut, 0, out, (outOfs + len), tagLenBytes);
return (len + tagLenBytes);
}
@@ -524,10 +689,6 @@ int encryptFinal(byte[] in, int inOfs, int len, byte[] out, int outOfs)
* @return the number of bytes placed into the out
buffer
*/
int decrypt(byte[] in, int inOfs, int len, byte[] out, int outOfs) {
- ArrayUtil.blockSizeCheck(len, blockSize);
-
- checkDataLength(ibuffer.size(), len);
-
processAAD();
if (len > 0) {
@@ -540,6 +701,19 @@ int decrypt(byte[] in, int inOfs, int len, byte[] out, int outOfs) {
return 0;
}
+ int decrypt(ByteBuffer src, ByteBuffer dst) {
+ if (src.remaining() > 0) {
+ byte[] b = new byte[src.remaining()];
+ src.get(b);
+ try {
+ ibuffer.write(b);
+ } catch (IOException e) {
+ throw new ProviderException("Unable to add remaining input to the buffer", e);
+ }
+ }
+ return 0;
+ }
+
/**
* Performs decryption operation for the last time.
*
@@ -566,11 +740,11 @@ int decryptFinal(byte[] in, int inOfs, int len,
// do this check here can also catch the potential integer overflow
// scenario for the subsequent output buffer capacity check.
- checkDataLength(ibuffer.size(), (len - tagLenBytes));
+ checkDataLength(getBufferedLength(), (len - tagLenBytes));
try {
ArrayUtil.nullAndBoundsCheck(out, outOfs,
- (ibuffer.size() + len) - tagLenBytes);
+ (getBufferedLength() + len) - tagLenBytes);
} catch (ArrayIndexOutOfBoundsException aiobe) {
throw new ShortBufferException("Output buffer too small");
}
@@ -586,7 +760,7 @@ int decryptFinal(byte[] in, int inOfs, int len,
// If decryption is in-place or there is buffered "ibuffer" data, copy
// the "in" byte array into the ibuffer before proceeding.
- if (in == out || ibuffer.size() > 0) {
+ if (in == out || getBufferedLength() > 0) {
if (len > 0) {
ibuffer.write(in, inOfs, len);
}
@@ -602,19 +776,16 @@ int decryptFinal(byte[] in, int inOfs, int len,
doLastBlock(in, inOfs, len, out, outOfs, false);
}
- byte[] lengthBlock =
- getLengthBlock(sizeOfAAD, processed);
- ghashAllToS.update(lengthBlock);
-
- byte[] s = ghashAllToS.digest();
- byte[] sOut = new byte[s.length];
+ byte[] block = getLengthBlock(sizeOfAAD, processed);
+ ghashAllToS.update(block);
+ block = ghashAllToS.digest();
GCTR gctrForSToTag = new GCTR(embeddedCipher, this.preCounterBlock);
- gctrForSToTag.doFinal(s, 0, s.length, sOut, 0);
+ gctrForSToTag.doFinal(block, 0, tagLenBytes, block, 0);
// check entire authentication tag for time-consistency
int mismatch = 0;
for (int i = 0; i < tagLenBytes; i++) {
- mismatch |= tag[i] ^ sOut[i];
+ mismatch |= tag[i] ^ block[i];
}
if (mismatch != 0) {
@@ -624,6 +795,122 @@ int decryptFinal(byte[] in, int inOfs, int len,
return len;
}
+ // Note: In-place operations do not need an intermediary copy because
+ // the GHASH check was performed before the decryption.
+ int decryptFinal(ByteBuffer src, ByteBuffer dst)
+ throws IllegalBlockSizeException, AEADBadTagException,
+ ShortBufferException {
+
+ dst = overlapDetection(src, dst);
+ // Length of the input
+ ByteBuffer tag;
+ ByteBuffer ct = src.duplicate();
+
+ ByteBuffer buffer = ((ibuffer == null || ibuffer.size() == 0) ? null :
+ ByteBuffer.wrap(ibuffer.toByteArray()));
+ int len;
+
+ if (ct.remaining() >= tagLenBytes) {
+ tag = src.duplicate();
+ tag.position(ct.limit() - tagLenBytes);
+ ct.limit(ct.limit() - tagLenBytes);
+ len = ct.remaining();
+ if (buffer != null) {
+ len += buffer.remaining();
+ }
+ } else if (buffer != null && ct.remaining() < tagLenBytes) {
+ // It's unlikely the tag will be between the buffer and data
+ tag = ByteBuffer.allocate(tagLenBytes);
+ int limit = buffer.remaining() - (tagLenBytes - ct.remaining());
+ buffer.mark();
+ buffer.position(limit);
+ // Read from "new" limit to buffer's end
+ tag.put(buffer);
+ // reset buffer to data only
+ buffer.reset();
+ buffer.limit(limit);
+ tag.put(ct);
+ tag.flip();
+ // Limit is how much of the ibuffer has been chopped off.
+ len = buffer.remaining();
+ } else {
+ throw new AEADBadTagException("Input too short - need tag");
+ }
+
+ // 'len' contains the length in ibuffer and src
+ checkDataLength(len);
+
+ if (len > dst.remaining()) {
+ throw new ShortBufferException("Output buffer too small");
+ }
+
+ processAAD();
+ // Set the mark for a later reset. Either it will be zero, or the tag
+ // buffer creation above will have consume some or all of it.
+ ct.mark();
+
+ // If there is data stored in the buffer
+ if (buffer != null && buffer.remaining() > 0) {
+ ghashAllToS.update(buffer, buffer.remaining());
+ // Process the overage
+ if (buffer.remaining() > 0) {
+ // Fill out block between two buffers
+ if (ct.remaining() > 0) {
+ int over = buffer.remaining();
+ byte[] block = new byte[AES_BLOCK_SIZE];
+ // Copy the remainder of the buffer into the extra block
+ buffer.get(block, 0, over);
+
+ // Fill out block with what is in data
+ if (ct.remaining() > AES_BLOCK_SIZE - over) {
+ ct.get(block, over, AES_BLOCK_SIZE - over);
+ ghashAllToS.update(block, 0, AES_BLOCK_SIZE);
+ } else {
+ // If the remaining in buffer + data does not fill a
+ // block, complete the ghash operation
+ int l = ct.remaining();
+ ct.get(block, over, l);
+ ghashAllToS.doLastBlock(ByteBuffer.wrap(block), over + l);
+ }
+ } else {
+ // data is empty, so complete the ghash op with the
+ // remaining buffer
+ ghashAllToS.doLastBlock(buffer, buffer.remaining());
+ }
+ }
+ // Prepare buffer for decryption
+ buffer.flip();
+ }
+
+ if (ct.remaining() > 0) {
+ ghashAllToS.doLastBlock(ct, ct.remaining());
+ }
+ // Prepare buffer for decryption if available
+ ct.reset();
+
+ byte[] block = getLengthBlock(sizeOfAAD, len);
+ ghashAllToS.update(block);
+ block = ghashAllToS.digest();
+ GCTR gctrForSToTag = new GCTR(embeddedCipher, this.preCounterBlock);
+ gctrForSToTag.doFinal(block, 0, tagLenBytes, block, 0);
+
+ // check entire authentication tag for time-consistency
+ int mismatch = 0;
+ for (int i = 0; i < tagLenBytes; i++) {
+ mismatch |= tag.get() ^ block[i];
+ }
+
+ if (mismatch != 0) {
+ throw new AEADBadTagException("Tag mismatch!");
+ }
+
+ // Decrypt the all the input data and put it into dst
+ doLastBlock(buffer, ct, dst);
+ restoreDst(dst);
+ // 'processed' from the gctr decryption operation, not ghash
+ return processed;
+ }
+
// return tag length in bytes
int getTagLen() {
return this.tagLenBytes;
@@ -636,4 +923,94 @@ int getBufferedLength() {
return ibuffer.size();
}
}
+
+ /**
+ * Check for overlap. If the src and dst buffers are using shared data and
+ * if dst will overwrite src data before src can be processed. If so, make
+ * a copy to put the dst data in.
+ */
+ ByteBuffer overlapDetection(ByteBuffer src, ByteBuffer dst) {
+ if (src.isDirect() && dst.isDirect()) {
+ DirectBuffer dsrc = (DirectBuffer) src;
+ DirectBuffer ddst = (DirectBuffer) dst;
+
+ // Get the current memory address for the given ByteBuffers
+ long srcaddr = dsrc.address();
+ long dstaddr = ddst.address();
+
+ // Find the lowest attachment that is the base memory address of the
+ // shared memory for the src object
+ while (dsrc.attachment() != null) {
+ srcaddr = ((DirectBuffer) dsrc.attachment()).address();
+ dsrc = (DirectBuffer) dsrc.attachment();
+ }
+
+ // Find the lowest attachment that is the base memory address of the
+ // shared memory for the dst object
+ while (ddst.attachment() != null) {
+ dstaddr = ((DirectBuffer) ddst.attachment()).address();
+ ddst = (DirectBuffer) ddst.attachment();
+ }
+
+ // If the base addresses are not the same, there is no overlap
+ if (srcaddr != dstaddr) {
+ return dst;
+ }
+ // At this point we know these objects share the same memory.
+ // This checks the starting position of the src and dst address for
+ // overlap.
+ // It uses the base address minus the passed object's address to get
+ // the offset from the base address, then add the position() from
+ // the passed object. That gives up the true offset from the base
+ // address. As long as the src side is >= the dst side, we are not
+ // in overlap.
+ if (((DirectBuffer) src).address() - srcaddr + src.position() >=
+ ((DirectBuffer) dst).address() - dstaddr + dst.position()) {
+ return dst;
+ }
+
+ } else if (!src.isDirect() && !dst.isDirect()) {
+ if (!src.isReadOnly()) {
+ // If using the heap, check underlying byte[] address.
+ if (!src.array().equals(dst.array()) ) {
+ return dst;
+ }
+
+ // Position plus arrayOffset() will give us the true offset from
+ // the underlying byte[] address.
+ if (src.position() + src.arrayOffset() >=
+ dst.position() + dst.arrayOffset()) {
+ return dst;
+ }
+ }
+ } else {
+ // buffer types aren't the same
+ return dst;
+ }
+
+ // Create a copy
+ ByteBuffer tmp = dst.duplicate();
+ // We can use a heap buffer for internal use, save on alloc cost
+ ByteBuffer bb = ByteBuffer.allocate(dst.remaining());
+ tmp.limit(dst.limit());
+ tmp.position(dst.position());
+ bb.put(tmp);
+ bb.flip();
+ originalDst = dst;
+ return bb;
+ }
+
+ /**
+ * If originalDst exists, dst is an internal dst buffer, then copy the data
+ * into the original dst buffer
+ */
+ void restoreDst(ByteBuffer dst) {
+ if (originalDst == null) {
+ return;
+ }
+
+ dst.flip();
+ originalDst.put(dst);
+ originalDst = null;
+ }
}
diff --git a/test/jdk/com/sun/crypto/provider/Cipher/AEAD/GCMBufferTest.java b/test/jdk/com/sun/crypto/provider/Cipher/AEAD/GCMBufferTest.java
new file mode 100644
index 0000000000000..54d271d63ae9b
--- /dev/null
+++ b/test/jdk/com/sun/crypto/provider/Cipher/AEAD/GCMBufferTest.java
@@ -0,0 +1,851 @@
+/*
+ * Copyright (c) 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
+ * @summary Use Cipher update and doFinal with a mixture of byte[], bytebuffer,
+ * and offset while verifying return values. Also using different and
+ * in-place buffers.
+ *
+ * in-place is not tested with different buffer types as it is not a logical
+ * scenario and is complicated by getOutputSize calculations.
+ */
+
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.GCMParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import java.io.ByteArrayOutputStream;
+import java.math.BigInteger;
+import java.nio.ByteBuffer;
+import java.security.SecureRandom;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+
+public class GCMBufferTest implements Cloneable {
+
+ // Data type for the operation
+ enum dtype { BYTE, HEAP, DIRECT };
+ // Data map
+ static HashMap> datamap = new HashMap<>();
+ // List of enum values for order of operation
+ List ops;
+
+ static final int AESBLOCK = 16;
+ // The remaining input data length is inserted at the particular index
+ // in sizes[] during execution.
+ static final int REMAINDER = -1;
+
+ String algo;
+ boolean same = true;
+ int[] sizes;
+ boolean incremental = false;
+ // In some cases the theoretical check is too complicated to verify
+ boolean theoreticalCheck;
+ List dataSet;
+ int inOfs = 0, outOfs = 0;
+
+ static class Data {
+ int id;
+ SecretKey key;
+ byte[] iv;
+ byte[] pt;
+ byte[] aad;
+ byte[] ct;
+ byte[] tag;
+
+ Data(String keyalgo, int id, String key, String iv, byte[] pt, String aad,
+ String ct, String tag) {
+ this.id = id;
+ this.key = new SecretKeySpec(HexToBytes(key), keyalgo);
+ this.iv = HexToBytes(iv);
+ this.pt = pt;
+ this.aad = HexToBytes(aad);
+ this.ct = HexToBytes(ct);
+ this.tag = HexToBytes(tag);
+ }
+
+ Data(String keyalgo, int id, String key, String iv, String pt, String aad,
+ String ct, String tag) {
+ this(keyalgo, id, key, iv, HexToBytes(pt), aad, ct, tag);
+ }
+
+ Data(String keyalgo, int id, String key, int ptlen) {
+ this.id = id;
+ this.key = new SecretKeySpec(HexToBytes(key), keyalgo);
+ iv = new byte[16];
+ pt = new byte[ptlen];
+ tag = new byte[12];
+ aad = new byte[0];
+ byte[] tct = null;
+ try {
+ SecureRandom r = new SecureRandom();
+ r.nextBytes(iv);
+ r.nextBytes(pt);
+ Cipher c = Cipher.getInstance("AES/GCM/NoPadding");
+ c.init(Cipher.ENCRYPT_MODE, this.key,
+ new GCMParameterSpec(tag.length * 8, this.iv));
+ tct = c.doFinal(pt);
+ } catch (Exception e) {
+ System.out.println("Error in generating data for length " +
+ ptlen);
+ }
+ ct = new byte[ptlen];
+ System.arraycopy(tct, 0, ct, 0, ct.length);
+ System.arraycopy(tct, ct.length, tag, 0, tag.length);
+ }
+
+ }
+
+ /**
+ * Construct a test with an algorithm and a list of dtype.
+ * @param algo Algorithm string
+ * @param ops List of dtypes. If only one dtype is specified, only a
+ * doFinal operation will occur. If multiple dtypes are
+ * specified, the last is a doFinal, the others are updates.
+ */
+ GCMBufferTest(String algo, List ops) {
+ this.algo = algo;
+ this.ops = ops;
+ theoreticalCheck = true;
+ dataSet = datamap.get(algo);
+ }
+
+ public GCMBufferTest clone() throws CloneNotSupportedException{
+ return (GCMBufferTest)super.clone();
+ }
+
+ /**
+ * Define particular data sizes to be tested. "REMAINDER", which has a
+ * value of -1, can be used to insert the remaining input text length at
+ * that index during execution.
+ * @param sizes Data sizes for each dtype in the list.
+ */
+ GCMBufferTest dataSegments(int[] sizes) {
+ this.sizes = sizes;
+ return this;
+ }
+
+ /**
+ * Do not perform in-place operations
+ */
+ GCMBufferTest differentBufferOnly() {
+ this.same = false;
+ return this;
+ }
+
+ /**
+ * Enable incrementing through each data size available. This can only be
+ * used when the List has more than one dtype entry.
+ */
+ GCMBufferTest incrementalSegments() {
+ this.incremental = true;
+ return this;
+ }
+
+ /**
+ * Specify a particular test dataset.
+ *
+ * @param id id value for the test data to used in this test.
+ */
+ GCMBufferTest dataSet(int id) throws Exception {
+ for (Data d : datamap.get(algo)) {
+ if (d.id == id) {
+ dataSet = List.of(d);
+ return this;
+ }
+ }
+ throw new Exception("Unaeble to find dataSet id = " + id);
+ }
+
+ /**
+ * Set both input and output offsets to the same offset
+ * @param offset value for inOfs and outOfs
+ * @return
+ */
+ GCMBufferTest offset(int offset) {
+ this.inOfs = offset;
+ this.outOfs = offset;
+ return this;
+ }
+
+ /**
+ * Set the input offset
+ * @param offset value for input offset
+ * @return
+ */
+ GCMBufferTest inOfs(int offset) {
+ this.inOfs = offset;
+ return this;
+ }
+
+ /**
+ * Set the output offset
+ * @param offset value for output offset
+ * @return
+ */
+ GCMBufferTest outOfs(int offset) {
+ this.outOfs = offset;
+ return this;
+ }
+
+ /**
+ * Reverse recursive loop that starts at the end-1 index, going to 0, in
+ * the size array to calculate all the possible sizes.
+ * It returns the remaining data size not used in the loop. This remainder
+ * is used for the end index which is the doFinal op.
+ */
+ int inc(int index, int max, int total) {
+ if (sizes[index] == max - total) {
+ sizes[index + 1]++;
+ total++;
+ sizes[index] = 0;
+ } else if (index == 0) {
+ sizes[index]++;
+ }
+
+ total += sizes[index];
+ if (index > 0) {
+ return inc(index - 1, max, total);
+ }
+ return total;
+ }
+
+ // Call recursive loop and take returned remainder value for last index
+ boolean incrementSizes(int max) {
+ sizes[ops.size() - 1] = max - inc(ops.size() - 2, max, 0);
+ if (sizes[ops.size() - 2] == max) {
+ // We are at the end, exit test loop
+ return false;
+ }
+ return true;
+ }
+
+ void test() throws Exception {
+ int i = 1;
+ System.out.println("Algo: " + algo + " \tOps: " + ops.toString());
+ for (Data data : dataSet) {
+
+ // If incrementalSegments is enabled, run through that test only
+ if (incremental) {
+ if (ops.size() < 2) {
+ throw new Exception("To do incrementalSegments you must" +
+ "have more that 1 dtype in the list");
+ }
+ sizes = new int[ops.size()];
+
+ while (incrementSizes(data.pt.length)) {
+ System.out.print("Encrypt: Data Index: " + i + " \tSizes[ ");
+ for (int v : sizes) {
+ System.out.print(v + " ");
+ }
+ System.out.println("]");
+ encrypt(data);
+ }
+ Arrays.fill(sizes, 0);
+
+ while (incrementSizes(data.ct.length + data.tag.length)) {
+ System.out.print("Decrypt: Data Index: " + i + " \tSizes[ ");
+ for (int v : sizes) {
+ System.out.print(v + " ");
+ }
+ System.out.println("]");
+ decrypt(data);
+ }
+
+ } else {
+ // Default test of 0 and 2 offset doing in place and different
+ // i/o buffers
+ System.out.println("Encrypt: Data Index: " + i);
+ encrypt(data);
+
+ System.out.println("Decrypt: Data Index: " + i);
+ decrypt(data);
+ }
+ i++;
+ }
+ }
+
+ // Setup data for encryption
+ void encrypt(Data data) throws Exception {
+ byte[] input, output;
+
+ input = data.pt;
+ output = new byte[data.ct.length + data.tag.length];
+ System.arraycopy(data.ct, 0, output, 0, data.ct.length);
+ System.arraycopy(data.tag, 0, output, data.ct.length,
+ data.tag.length);
+
+ // Test different input/output buffers
+ System.out.println("\tinput len: " + input.length + " inOfs " +
+ inOfs + " outOfs " + outOfs + " in/out buffer: different");
+ crypto(true, data, input, output);
+
+ // Test with in-place buffers
+ if (same) {
+ System.out.println("\tinput len: " + input.length + " inOfs " +
+ inOfs + " outOfs " + outOfs + " in/out buffer: in-place");
+ cryptoSameBuffer(true, data, input, output);
+ }
+ }
+
+ // Setup data for decryption
+ void decrypt(Data data) throws Exception {
+ byte[] input, output;
+
+ input = new byte[data.ct.length + data.tag.length];
+ System.arraycopy(data.ct, 0, input, 0, data.ct.length);
+ System.arraycopy(data.tag, 0, input, data.ct.length, data.tag.length);
+ output = data.pt;
+
+ // Test different input/output buffers
+ System.out.println("\tinput len: " + input.length + " inOfs " +
+ inOfs + " outOfs " + outOfs + " in-place: different");
+ crypto(false, data, input, output);
+
+ // Test with in-place buffers
+ if (same) {
+ System.out.println("\tinput len: " + input.length + " inOfs " +
+ inOfs + " outOfs " + outOfs + " in-place: same");
+ cryptoSameBuffer(false, data, input, output);
+ }
+ }
+
+ /**
+ * Perform cipher operation using different input and output buffers.
+ * This method allows mixing of data types (byte, heap, direct).
+ */
+ void crypto(boolean encrypt, Data d, byte[] input, byte[] output)
+ throws Exception {
+ byte[] pt = new byte[input.length + inOfs];
+ System.arraycopy(input, 0, pt, inOfs, input.length);
+ byte[] expectedOut = new byte[output.length + outOfs];
+ System.arraycopy(output, 0, expectedOut, outOfs, output.length);
+ int plen = input.length / ops.size(); // partial input length
+ int theoreticallen;// expected output length
+ int dataoffset = 0; // offset of unconsumed data in pt
+ int index = 0; // index of which op we are on
+ int rlen; // result length
+ int pbuflen = 0; // plen remaining in the GCM internal buffers
+
+ Cipher cipher = Cipher.getInstance(algo);
+ cipher.init((encrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE),
+ d.key, new GCMParameterSpec(d.tag.length * 8, d.iv));
+ cipher.updateAAD(d.aad);
+
+ ByteArrayOutputStream ba = new ByteArrayOutputStream();
+ ba.write(new byte[outOfs], 0, outOfs);
+ for (dtype v : ops) {
+ if (index < ops.size() - 1) {
+ if (sizes != null && input.length > 0) {
+ if (sizes[index] == -1) {
+ plen = input.length - dataoffset;
+ } else {
+ if (sizes[index] > input.length) {
+ plen = input.length;
+ } else {
+ plen = sizes[index];
+ }
+ }
+ }
+
+ int olen = cipher.getOutputSize(plen) + outOfs;
+
+ /*
+ * The theoretical limit is the length of the data sent to
+ * update() + any data might be setting in CipherCore or GCM
+ * internal buffers % the block size.
+ */
+ theoreticallen = (plen + pbuflen) - ((plen + pbuflen) % AESBLOCK);
+
+ // Update operations
+ switch (v) {
+ case BYTE -> {
+ byte[] out = new byte[olen];
+ rlen = cipher.update(pt, dataoffset + inOfs, plen, out,
+ outOfs);
+ ba.write(out, outOfs, rlen);
+ }
+ case HEAP -> {
+ ByteBuffer b = ByteBuffer.allocate(plen + outOfs);
+ b.position(outOfs);
+ b.put(pt, dataoffset + inOfs, plen);
+ b.flip();
+ b.position(outOfs);
+ ByteBuffer out = ByteBuffer.allocate(olen);
+ out.position(outOfs);
+ rlen = cipher.update(b, out);
+ ba.write(out.array(), outOfs, rlen);
+ }
+ case DIRECT -> {
+ ByteBuffer b = ByteBuffer.allocateDirect(plen + outOfs);
+ b.position(outOfs);
+ b.put(pt, dataoffset + inOfs, plen);
+ b.flip();
+ b.position(outOfs);
+ ByteBuffer out = ByteBuffer.allocateDirect(olen);
+ out.position(outOfs);
+ rlen = cipher.update(b, out);
+ byte[] o = new byte[rlen];
+ out.flip();
+ out.position(outOfs);
+ out.get(o, 0, rlen);
+ ba.write(o);
+ }
+ default -> throw new Exception("Unknown op: " + v.name());
+ }
+
+ if (theoreticalCheck) {
+ pbuflen += plen - rlen;
+ if (encrypt && rlen != theoreticallen) {
+ throw new Exception("Wrong update return len (" +
+ v.name() + "): " + "rlen=" + rlen +
+ ", expected output len=" + theoreticallen);
+ }
+ }
+
+ dataoffset += plen;
+ index++;
+
+ } else {
+ // doFinal operation
+ plen = input.length - dataoffset;
+
+ int olen = cipher.getOutputSize(plen) + outOfs;
+ switch (v) {
+ case BYTE -> {
+ byte[] out = new byte[olen];
+ rlen = cipher.doFinal(pt, dataoffset + inOfs,
+ plen, out, outOfs);
+ ba.write(out, outOfs, rlen);
+ }
+ case HEAP -> {
+ ByteBuffer b = ByteBuffer.allocate(plen + inOfs);
+ b.limit(b.capacity());
+ b.position(inOfs);
+ b.put(pt, dataoffset + inOfs, plen);
+ b.flip();
+ b.position(inOfs);
+ ByteBuffer out = ByteBuffer.allocate(olen);
+ out.limit(out.capacity());
+ out.position(outOfs);
+ rlen = cipher.doFinal(b, out);
+ ba.write(out.array(), outOfs, rlen);
+ }
+ case DIRECT -> {
+ ByteBuffer b = ByteBuffer.allocateDirect(plen + inOfs);
+ b.limit(b.capacity());
+ b.position(inOfs);
+ b.put(pt, dataoffset + inOfs, plen);
+ b.flip();
+ b.position(inOfs);
+ ByteBuffer out = ByteBuffer.allocateDirect(olen);
+ out.limit(out.capacity());
+ out.position(outOfs);
+ rlen = cipher.doFinal(b, out);
+ byte[] o = new byte[rlen];
+ out.flip();
+ out.position(outOfs);
+ out.get(o, 0, rlen);
+ ba.write(o);
+ }
+ default -> throw new Exception("Unknown op: " + v.name());
+ }
+
+ if (theoreticalCheck && rlen != olen - outOfs) {
+ throw new Exception("Wrong doFinal return len (" +
+ v.name() + "): " + "rlen=" + rlen +
+ ", expected output len=" + (olen - outOfs));
+ }
+
+ // Verify results
+ byte[] ctresult = ba.toByteArray();
+ if (ctresult.length != expectedOut.length ||
+ Arrays.compare(ctresult, expectedOut) != 0) {
+ String s = "Ciphertext mismatch (" + v.name() +
+ "):\nresult (len=" + ctresult.length + "):" +
+ String.format("%0" + (ctresult.length << 1) + "x",
+ new BigInteger(1, ctresult)) +
+ "\nexpected (len=" + output.length + "):" +
+ String.format("%0" + (output.length << 1) + "x",
+ new BigInteger(1, output));
+ System.err.println(s);
+ throw new Exception(s);
+
+ }
+ }
+ }
+ }
+
+ /**
+ * Perform cipher operation using in-place buffers. This method does not
+ * allow mixing of data types (byte, heap, direct).
+ *
+ * Mixing data types makes no sense for in-place operations and would
+ * greatly complicate the test code.
+ */
+ void cryptoSameBuffer(boolean encrypt, Data d, byte[] input, byte[] output) throws Exception {
+
+ byte[] data, out;
+ if (encrypt) {
+ data = new byte[output.length + Math.max(inOfs, outOfs)];
+ } else {
+ data = new byte[input.length + Math.max(inOfs, outOfs)];
+ }
+
+ ByteBuffer bbin = null, bbout = null;
+ System.arraycopy(input, 0, data, inOfs, input.length);
+ byte[] expectedOut = new byte[output.length + outOfs];
+ System.arraycopy(output, 0, expectedOut, outOfs, output.length);
+ int plen = input.length / ops.size(); // partial input length
+ int theorticallen = plen - (plen % AESBLOCK); // output length
+ int dataoffset = 0;
+ int index = 0;
+ int rlen = 0; // result length
+ int len = 0;
+
+ Cipher cipher = Cipher.getInstance(algo);
+ cipher.init((encrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE),
+ d.key, new GCMParameterSpec(d.tag.length * 8, d.iv));
+ cipher.updateAAD(d.aad);
+
+ // Prepare data
+ switch (ops.get(0)) {
+ case HEAP -> {
+ bbin = ByteBuffer.wrap(data);
+ bbin.limit(input.length + inOfs);
+ bbout = bbin.duplicate();
+ }
+ case DIRECT -> {
+ bbin = ByteBuffer.allocateDirect(data.length);
+ bbout = bbin.duplicate();
+ bbin.put(data, 0, input.length + inOfs);
+ bbin.flip();
+ }
+ }
+
+ // Set data limits for bytebuffers
+ if (bbin != null) {
+ bbin.position(inOfs);
+ bbout.limit(output.length + outOfs);
+ bbout.position(outOfs);
+ }
+
+ // Iterate through each operation
+ for (dtype v : ops) {
+ if (index < ops.size() - 1) {
+ switch (v) {
+ case BYTE -> {
+ rlen = cipher.update(data, dataoffset + inOfs, plen,
+ data, len + outOfs);
+ }
+ case HEAP, DIRECT -> {
+ theorticallen = bbin.remaining() -
+ (bbin.remaining() % AESBLOCK);
+ rlen = cipher.update(bbin, bbout);
+ }
+ default -> throw new Exception("Unknown op: " + v.name());
+ }
+
+ // Check that the theoretical return value matches the actual.
+ if (theoreticalCheck && encrypt && rlen != theorticallen) {
+ throw new Exception("Wrong update return len (" +
+ v.name() + "): " + "rlen=" + rlen +
+ ", expected output len=" + theorticallen);
+ }
+
+ dataoffset += plen;
+ len += rlen;
+ index++;
+
+ } else {
+ // Run doFinal op
+ plen = input.length - dataoffset;
+
+ switch (v) {
+ case BYTE -> {
+ rlen = cipher.doFinal(data, dataoffset + inOfs,
+ plen, data, len + outOfs);
+ out = Arrays.copyOfRange(data, 0,len + rlen + outOfs);
+ }
+ case HEAP, DIRECT -> {
+ rlen = cipher.doFinal(bbin, bbout);
+ bbout.flip();
+ out = new byte[bbout.remaining()];
+ bbout.get(out);
+ }
+ default -> throw new Exception("Unknown op: " + v.name());
+ }
+ len += rlen;
+
+ // Verify results
+ if (len != output.length ||
+ Arrays.compare(out, 0, len, expectedOut, 0,
+ output.length) != 0) {
+ String s = "Ciphertext mismatch (" + v.name() +
+ "):\nresult (len=" + len + "):\n" +
+ byteToHex(out) +
+ "\nexpected (len=" + output.length + "):\n" +
+ String.format("%0" + (output.length << 1) + "x",
+ new BigInteger(1, output));
+ System.err.println(s);
+ throw new Exception(s);
+ }
+ }
+ }
+ }
+ static void offsetTests(GCMBufferTest t) throws Exception {
+ t.clone().offset(2).test();
+ t.clone().inOfs(2).test();
+ // Test not designed for overlap situations
+ t.clone().outOfs(2).differentBufferOnly().test();
+ }
+
+ public static void main(String args[]) throws Exception {
+ initTest();
+ // Test single byte array
+ new GCMBufferTest("AES/GCM/NoPadding", List.of(dtype.BYTE)).test();
+ offsetTests(new GCMBufferTest("AES/GCM/NoPadding", List.of(dtype.BYTE)));
+ // Test update-doFinal with byte arrays
+ new GCMBufferTest("AES/GCM/NoPadding", List.of(dtype.BYTE, dtype.BYTE)).test();
+ offsetTests(new GCMBufferTest("AES/GCM/NoPadding", List.of(dtype.BYTE, dtype.BYTE)));
+ // Test update-update-doFinal with byte arrays
+ new GCMBufferTest("AES/GCM/NoPadding",
+ List.of(dtype.BYTE, dtype.BYTE, dtype.BYTE)).test();
+ offsetTests(new GCMBufferTest("AES/GCM/NoPadding", List.of(dtype.BYTE, dtype.BYTE, dtype.BYTE)));
+
+ // Test single heap bytebuffer
+ new GCMBufferTest("AES/GCM/NoPadding", List.of(dtype.HEAP)).test();
+ offsetTests(new GCMBufferTest("AES/GCM/NoPadding", List.of(dtype.HEAP)));
+ // Test update-doFinal with heap bytebuffer
+ new GCMBufferTest("AES/GCM/NoPadding",
+ List.of(dtype.HEAP, dtype.HEAP)).test();
+ offsetTests(new GCMBufferTest("AES/GCM/NoPadding", List.of(dtype.HEAP, dtype.HEAP)));
+ // Test update-update-doFinal with heap bytebuffer
+ new GCMBufferTest("AES/GCM/NoPadding",
+ List.of(dtype.HEAP, dtype.HEAP, dtype.HEAP)).test();
+ offsetTests(new GCMBufferTest("AES/GCM/NoPadding", List.of(dtype.HEAP, dtype.HEAP, dtype.HEAP)));
+
+ // Test single direct bytebuffer
+ new GCMBufferTest("AES/GCM/NoPadding", List.of(dtype.DIRECT)).test();
+ offsetTests(new GCMBufferTest("AES/GCM/NoPadding", List.of(dtype.DIRECT)));
+ // Test update-doFinal with direct bytebuffer
+ new GCMBufferTest("AES/GCM/NoPadding",
+ List.of(dtype.DIRECT, dtype.DIRECT)).test();
+ offsetTests(new GCMBufferTest("AES/GCM/NoPadding",
+ List.of(dtype.DIRECT, dtype.DIRECT)));
+ // Test update-update-doFinal with direct bytebuffer
+ new GCMBufferTest("AES/GCM/NoPadding",
+ List.of(dtype.DIRECT, dtype.DIRECT, dtype.DIRECT)).test();
+ offsetTests(new GCMBufferTest("AES/GCM/NoPadding",
+ List.of(dtype.DIRECT, dtype.DIRECT, dtype.DIRECT)));
+
+ // Test update-update-doFinal with byte arrays and preset data sizes
+ GCMBufferTest t = new GCMBufferTest("AES/GCM/NoPadding",
+ List.of(dtype.BYTE, dtype.BYTE, dtype.BYTE)).dataSegments(
+ new int[] { 1, 1, GCMBufferTest.REMAINDER});
+ t.clone().test();
+ offsetTests(t.clone());
+
+ // Test update-doFinal with a byte array and a direct bytebuffer
+ t = new GCMBufferTest("AES/GCM/NoPadding",
+ List.of(dtype.BYTE, dtype.DIRECT)).differentBufferOnly();
+ t.clone().test();
+ offsetTests(t.clone());
+ // Test update-doFinal with a byte array and heap and direct bytebuffer
+ t = new GCMBufferTest("AES/GCM/NoPadding",
+ List.of(dtype.BYTE, dtype.HEAP, dtype.DIRECT)).differentBufferOnly();
+ t.clone().test();
+ offsetTests(t.clone());
+ // Test update-doFinal with a direct bytebuffer and a byte array.
+ t = new GCMBufferTest("AES/GCM/NoPadding",
+ List.of(dtype.DIRECT, dtype.BYTE)).differentBufferOnly();
+ t.clone().test();
+ offsetTests(t.clone());
+
+ // Test update-doFinal with a direct bytebuffer and a byte array with
+ // preset data sizes.
+ t = new GCMBufferTest("AES/GCM/NoPadding",
+ List.of(dtype.DIRECT, dtype.BYTE)).differentBufferOnly().
+ dataSegments(new int[] { 20, GCMBufferTest.REMAINDER });
+ t.clone().test();
+ offsetTests(t.clone());
+ // Test update-update-doFinal with a direct and heap bytebuffer and a
+ // byte array with preset data sizes.
+ t = new GCMBufferTest("AES/GCM/NoPadding",
+ List.of(dtype.DIRECT, dtype.BYTE, dtype.HEAP)).
+ differentBufferOnly().dataSet(5).
+ dataSegments(new int[] { 5000, 1000, GCMBufferTest.REMAINDER });
+ t.clone().test();
+ offsetTests(t.clone());
+
+ // Test update-update-doFinal with byte arrays, incrementing through
+ // every data size combination for the Data set 0
+ new GCMBufferTest("AES/GCM/NoPadding",
+ List.of(dtype.BYTE, dtype.BYTE, dtype.BYTE)).incrementalSegments().
+ dataSet(0).test();
+ // Test update-update-doFinal with direct bytebuffers, incrementing through
+ // every data size combination for the Data set 0
+ new GCMBufferTest("AES/GCM/NoPadding",
+ List.of(dtype.DIRECT, dtype.DIRECT, dtype.DIRECT)).
+ incrementalSegments().dataSet(0).test();
+ }
+
+ private static byte[] HexToBytes(String hexVal) {
+ if (hexVal == null) {
+ return new byte[0];
+ }
+ byte[] result = new byte[hexVal.length()/2];
+ for (int i = 0; i < result.length; i++) {
+ String byteVal = hexVal.substring(2*i, 2*i +2);
+ result[i] = Integer.valueOf(byteVal, 16).byteValue();
+ }
+ return result;
+ }
+
+ private static String byteToHex(byte[] barray) {
+ StringBuilder s = new StringBuilder();
+ for (byte b : barray) {
+ s.append(String.format("%02x", b));
+ }
+ return s.toString();
+ }
+
+ // Test data
+ static void initTest() {
+ datamap.put("AES/GCM/NoPadding", List.of(
+ // GCM KAT
+ new Data("AES", 0,
+ "141f1ce91989b07e7eb6ae1dbd81ea5e",
+ "49451da24bd6074509d3cebc2c0394c972e6934b45a1d91f3ce1d3ca69e19" +
+ "4aa1958a7c21b6f21d530ce6d2cc5256a3f846b6f9d2f38df0102c4791e5" +
+ "7df038f6e69085646007df999751e248e06c47245f4cd3b8004585a7470d" +
+ "ee1690e9d2d63169a58d243c0b57b3e5b4a481a3e4e8c60007094ef3adea" +
+ "2e8f05dd3a1396f",
+ "d384305af2388699aa302f510913fed0f2cb63ba42efa8c5c9de2922a2ec" +
+ "2fe87719dadf1eb0aef212b51e74c9c5b934104a43",
+ "630cf18a91cc5a6481ac9eefd65c24b1a3c93396bd7294d6b8ba3239517" +
+ "27666c947a21894a079ef061ee159c05beeb4",
+ "f4c34e5fbe74c0297313268296cd561d59ccc95bbfcdfcdc71b0097dbd83" +
+ "240446b28dc088abd42b0fc687f208190ff24c0548",
+ "dbb93bbb56d0439cd09f620a57687f5d"),
+ // GCM KAT
+ new Data("AES", 1, "11754cd72aec309bf52f7687212e8957",
+ "3c819d9a9bed087615030b65",
+ (String)null, null, null,
+ "250327c674aaf477aef2675748cf6971"),
+ // GCM KAT
+ new Data("AES", 2, "272f16edb81a7abbea887357a58c1917",
+ "794ec588176c703d3d2a7a07",
+ (String)null, null, null,
+ "b6e6f197168f5049aeda32dafbdaeb"),
+ // zero'd test data
+ new Data("AES", 3, "272f16edb81a7abbea887357a58c1917",
+ "794ec588176c703d3d2a7a07",
+ new byte[256], null,
+ "15b461672153270e8ba1e6789f7641c5411f3e642abda731b6086f535c216457" +
+ "e87305bc59a1ff1f7e1e0bbdf302b75549b136606c67d7e5f71277aeca4bc670" +
+ "07a98f78e0cfa002ed183e62f07893ad31fe67aad1bb37e15b957a14d145f14f" +
+ "7483d041f2c3612ad5033155984470bdfc64d18df73c2745d92f28461bb09832" +
+ "33524811321ba87d213692825815dd13f528dba601a3c319cac6be9b48686c23" +
+ "a0ce23d5062916ea8827bbb243f585e446131489e951354c8ab24661f625c02e" +
+ "15536c5bb602244e98993ff745f3e523399b2059f0e062d8933fad2366e7e147" +
+ "510a931282bb0e3f635efe7bf05b1dd715f95f5858261b00735224256b6b3e80",
+ "08b3593840d4ed005f5234ae062a5c"),
+ // Random test data
+ new Data("AES", 4, "272f16edb81a7abbea887357a58c1917",
+ "794ec588176c703d3d2a7a07",
+ new byte[2075], null,
+ "15b461672153270e8ba1e6789f7641c5411f3e642abda731b6086f535c216457" +
+ "e87305bc59a1ff1f7e1e0bbdf302b75549b136606c67d7e5f71277aeca4bc670" +
+ "07a98f78e0cfa002ed183e62f07893ad31fe67aad1bb37e15b957a14d145f14f" +
+ "7483d041f2c3612ad5033155984470bdfc64d18df73c2745d92f28461bb09832" +
+ "33524811321ba87d213692825815dd13f528dba601a3c319cac6be9b48686c23" +
+ "a0ce23d5062916ea8827bbb243f585e446131489e951354c8ab24661f625c02e" +
+ "15536c5bb602244e98993ff745f3e523399b2059f0e062d8933fad2366e7e147" +
+ "510a931282bb0e3f635efe7bf05b1dd715f95f5858261b00735224256b6b3e80" +
+ "7364cb53ff6d4e88f928cf67ac70da127718a8a35542efbae9dd7567c818a074" +
+ "9a0c74bd69014639f59768bc55056d1166ea5523e8c66f9d78d980beb8f0d83b" +
+ "a9e2c5544b94dc3a1a4b6f0f95f897b010150e89ebcacf0daee3c2793d6501a0" +
+ "b58b411de273dee987e8e8cf8bb29ef2e7f655b46b55fabf64c6a4295e0d080b" +
+ "6a570ace90eb0fe0f5b5d878bdd90eddaa1150e4d5a6505b350aac814fe99615" +
+ "317ecd0516a464c7904011ef5922409c0d65b1e43b69d7c3293a8f7d3e9fbee9" +
+ "eb91ec0007a7d6f72e64deb675d459c5ba07dcfd58d08e6820b100465e6e04f0" +
+ "663e310584a00d36d23699c1bffc6afa094c75184fc7cde7ad35909c0f49f2f3" +
+ "fe1e6d745ab628d74ea56b757047de57ce18b4b3c71e8af31a6fac16189cb0a3" +
+ "a97a1bea447042ce382fcf726560476d759c24d5c735525ea26a332c2094408e" +
+ "671c7deb81d5505bbfd178f866a6f3a011b3cfdbe089b4957a790688028dfdf7" +
+ "9a096b3853f9d0d6d3feef230c7f5f46ffbf7486ebdaca5804dc5bf9d202415e" +
+ "e0d67b365c2f92a17ea740807e4f0b198b42b54f15faa9dff2c7c35d2cf8d72e" +
+ "b8f8b18875a2e7b5c43d1e0aa5139c461e8153c7f632895aa46ffe2b134e6a0d" +
+ "dfbf6a336e709adfe951bd52c4dfc7b07a15fb3888fc35b7e758922f87a104c4" +
+ "563c5c7839cfe5a7edbdb97264a7c4ebc90367b10cbe09dbf2390767ad7afaa8" +
+ "8fb46b39d3f55f216d2104e5cf040bf3d39b758bea28e2dbce576c808d17a8eb" +
+ "e2fd183ef42a774e39119dff1f539efeb6ad15d889dfcb0d54d0d4d4cc03c8d9" +
+ "aa6c9ebd157f5e7170183298d6a30ada8792dcf793d931e2a1eafccbc63c11c0" +
+ "c5c5ed60837f30017d693ccb294df392a8066a0594a56954aea7b78a16e9a11f" +
+ "4a8bc2104070a7319f5fab0d2c4ccad8ec5cd8f47c839179bfd54a7bf225d502" +
+ "cd0a318752fe763e8c09eb88fa57fc5399ad1f797d0595c7b8afdd23f13603e9" +
+ "6802192bb51433b7723f4e512bd4f799feb94b458e7f9792f5f9bd6733828f70" +
+ "a6b7ffbbc0bb7575021f081ec2a0d37fecd7cda2daec9a3a9d9dfe1c8034cead" +
+ "e4b56b581cc82bd5b74b2b30817967d9da33850336f171a4c68e2438e03f4b11" +
+ "96da92f01b3b7aeab795180ccf40a4b090b1175a1fc0b67c95f93105c3aef00e" +
+ "13d76cc402539192274fee703730cd0d1c5635257719cc96cacdbad00c6255e2" +
+ "bd40c775b43ad09599e84f2c3205d75a6661ca3f151183be284b354ce21457d1" +
+ "3ba65b9b2cdb81874bd14469c2008b3ddec78f7225ecc710cc70de7912ca6a6d" +
+ "348168322ab59fdafcf5c833bfa0ad4046f4b6da90e9f263db7079af592eda07" +
+ "5bf16c6b1a8346da9c292a48bf660860a4fc89eaef40bc132779938eca294569" +
+ "787c740af2b5a8de7f5e10ac750d1e3d0ef3ed168ba408a676e10b8a20bd4be8" +
+ "3e8336b45e54481726d73e1bd19f165a98e242aca0d8387f2dd22d02d74e23db" +
+ "4cef9a523587413e0a44d7e3260019a34d3a6b38426ae9fa4655be338d721970" +
+ "cb9fe76c073f26f9303093a033022cd2c62b2790bce633ba9026a1c93b6535f1" +
+ "1882bf5880e511b9e1b0b7d8f23a993aae5fd275faac3a5b4ccaf7c06b0b266a" +
+ "ee970a1e3a4cd7a41094f516960630534e692545b25a347c30e3f328bba4825f" +
+ "ed754e5525d846131ecba7ca120a6aeabc7bab9f59c890c80b7e31f9bc741591" +
+ "55d292433ce9558e104102f2cc63ee267c1c8333e841522707ea6d595cb802b9" +
+ "61697da77bbc4cb404ea62570ab335ebffa2023730732ac5ddba1c3dbb5be408" +
+ "3c50aea462c1ffa166d7cc3db4b742b747e81b452db2363e91374dee8c6b40f0" +
+ "e7fbf50e60eaf5cc5649f6bb553aae772c185026ceb052af088c545330a1ffbf" +
+ "50615b8c7247c6cd386afd7440654f4e15bcfae0c45442ec814fe88433a9d616" +
+ "ee6cc3f163f0d3d325526d05f25d3b37ad5eeb3ca77248ad86c9042b16c65554" +
+ "aebb6ad3e17b981492b13f42c5a5dc088e991da303e5a273fdbb8601aece4267" +
+ "47b01f6cb972e6da1743a0d7866cf206e95f23c6f8e337c901b9cd34a9a1fbbe" +
+ "1694f2c26b00dfa4d02c0d54540163e798fbdc9c25f30d6406f5b4c13f7ed619" +
+ "34e350f4059c13aa5e973307a9e3058917cda96fdd082e9c629ccfb2a9f98d12" +
+ "5c6e4703a7b0f348f5cdeb63cef2133d1c6c1a087591e0a2bca29d09c6565e66" +
+ "e91042f83b0e74e60a5d57562c23e2fbcd6599c29d7c19e47cf625c2ce24bb8a" +
+ "13f8e54041498437eec2cedd1e3d8e57a051baa962c0a62d70264d99c5ee716d" +
+ "5c8b9078db08c8b2c5613f464198a7aff43f76c5b4612b46a4f1cd2a494386c5" +
+ "7fd28f3d199f0ba8d8e39116cc7db16ce6188205ee49a9dce3d4fa32ea394919" +
+ "f6e91ef58b84d00b99596b4306c2d9f432d917bb4ac73384c42ae12adb4920d8" +
+ "c33a816febcb299dcddf3ec7a8eb6e04cdc90891c6e145bd9fc5f41dc4061a46" +
+ "9feba38545b64ec8203f386ceef52785619e991d274ae80af7e54af535e0b011" +
+ "5effdf847472992875e09398457604d04e0bb965db692c0cdcf11a",
+ "687cc09c89298491deb51061d709af"),
+ // Randomly generated data at the time of execution.
+ new Data("AES", 5, "11754cd72aec309bf52f7687212e8957", 12345)
+ )
+ );
+ }
+}
diff --git a/test/jdk/com/sun/crypto/provider/Cipher/AEAD/GCMIncrementByte4.java b/test/jdk/com/sun/crypto/provider/Cipher/AEAD/GCMIncrementByte4.java
new file mode 100644
index 0000000000000..1a92e0f4249e1
--- /dev/null
+++ b/test/jdk/com/sun/crypto/provider/Cipher/AEAD/GCMIncrementByte4.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 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.
+ */
+
+import java.util.List;
+
+/*
+ * @test
+ * @summary Uses GCMBufferTest to run a long test with incrementing through
+ * each byte in each byte array
+ * @run main/manual GCMIncrementByte4
+ */
+
+public class GCMIncrementByte4 {
+
+ public static void main(String args[]) throws Exception {
+ GCMBufferTest.initTest();
+ new GCMBufferTest("AES/GCM/NoPadding",
+ List.of(GCMBufferTest.dtype.BYTE, GCMBufferTest.dtype.BYTE,
+ GCMBufferTest.dtype.BYTE)).incrementalSegments().dataSet(4).
+ test();
+
+ }
+}
diff --git a/test/jdk/com/sun/crypto/provider/Cipher/AEAD/GCMIncrementDirect4.java b/test/jdk/com/sun/crypto/provider/Cipher/AEAD/GCMIncrementDirect4.java
new file mode 100644
index 0000000000000..3372c7713a125
--- /dev/null
+++ b/test/jdk/com/sun/crypto/provider/Cipher/AEAD/GCMIncrementDirect4.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 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.
+ */
+
+import java.util.List;
+
+/*
+ * @test
+ * @summary Uses GCMBufferTest to run a long test with incrementing through
+ * each byte in each direct bytebuffer
+ * @run main/manual GCMIncrementDirect4
+ */
+
+public class GCMIncrementDirect4 {
+
+ public static void main(String args[]) throws Exception {
+ new GCMBufferTest("AES/GCM/NoPadding",
+ List.of(GCMBufferTest.dtype.DIRECT, GCMBufferTest.dtype.DIRECT,
+ GCMBufferTest.dtype.DIRECT)).incrementalSegments().dataSet(4).
+ test();
+ }
+}
diff --git a/test/jdk/com/sun/crypto/provider/Cipher/AEAD/OverlapByteBuffer.java b/test/jdk/com/sun/crypto/provider/Cipher/AEAD/OverlapByteBuffer.java
new file mode 100644
index 0000000000000..9e84887c9908d
--- /dev/null
+++ b/test/jdk/com/sun/crypto/provider/Cipher/AEAD/OverlapByteBuffer.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 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.
+ */
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.GCMParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import java.nio.ByteBuffer;
+
+/*
+ * @test
+ * @summary This tests overlapping buffers using ByteBuffer.slice() with
+ * array-backed ByteBuffer, read only array-backed, ByteBuffer, and direct
+ * ByteBuffer.
+ */
+
+/*
+ * This tests overlapping buffers created with ByteBuffer.slice(). That is
+ * when the input and output ByteBuffers have shared memory (use the same
+ * underlying buffer space, commonly used for in-place crypto). The
+ * complication is the Cipher object specifies that it must be copy-safe. That
+ * means the output buffer will not overwrite any input data that has not been
+ * processed. If the output buffer's position or offset is greater than the
+ * input's overwriting will occur.
+ */
+
+public class OverlapByteBuffer {
+
+ public static void main(String[] args) throws Exception {
+ byte[] baseBuf = new byte[8192];
+ ByteBuffer output, input, in;
+ // Output offset from the baseBuf
+ int outOfs;
+
+ for (int i = 0; i < 3; i++) {
+ for (outOfs = -1; outOfs <= 1; outOfs++) {
+
+ SecretKeySpec key = new SecretKeySpec(new byte[16], "AES");
+ GCMParameterSpec params =
+ new GCMParameterSpec(128, new byte[12]);
+ Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
+ cipher.init(Cipher.ENCRYPT_MODE, key, params);
+
+ // Offset on the particular ByteBuffer (aka position())
+ int inOfsInBuf = 1;
+ int outOfsInBuf = inOfsInBuf + outOfs;
+ int sliceLen = cipher.getOutputSize(baseBuf.length);
+ int bufferSize = sliceLen + Math.max(inOfsInBuf, outOfsInBuf);
+ byte[] buffer;
+ // Create overlapping input and output buffers
+ switch (i) {
+ case 0 -> {
+ buffer = new byte[bufferSize];
+ output = ByteBuffer.wrap(buffer, outOfsInBuf, sliceLen).
+ slice();
+ input = ByteBuffer.wrap(buffer, inOfsInBuf, sliceLen).
+ slice();
+ System.out.println("Using array-backed ByteBuffer");
+ in = input.duplicate();
+ }
+ case 1 -> {
+ buffer = new byte[bufferSize];
+ output = ByteBuffer.wrap(buffer, outOfsInBuf, sliceLen).
+ slice();
+ input = ByteBuffer.wrap(buffer, inOfsInBuf, sliceLen).
+ slice();
+
+ System.out.println("Using read-only array-backed " + "ByteBuffer");
+ in = input.asReadOnlyBuffer();
+ }
+ case 2 -> {
+ System.out.println("Using direct ByteBuffer");
+ ByteBuffer buf = ByteBuffer.allocateDirect(bufferSize);
+ output = buf.duplicate();
+ output.position(outOfsInBuf);
+ output.limit(sliceLen + outOfsInBuf);
+ output = output.slice();
+
+ input = buf.duplicate();
+ input.position(inOfsInBuf);
+ input.limit(sliceLen + inOfsInBuf);
+ input = input.slice();
+
+ in = input.duplicate();
+ }
+ default -> {
+ throw new Exception("Unknown index " + i);
+ }
+ }
+
+ // Copy data into shared buffer
+ input.put(baseBuf);
+ input.flip();
+ in.limit(input.limit());
+
+ try {
+ int ctSize = cipher.doFinal(in, output);
+
+ // Get ready to decrypt
+ byte[] tmp = new byte[ctSize];
+ output.flip();
+ output.get(tmp);
+ output.clear();
+
+ input.clear();
+ input.put(tmp);
+ input.flip();
+
+ in.clear();
+ in.limit(input.limit());
+
+ cipher.init(Cipher.DECRYPT_MODE, key, params);
+ cipher.doFinal(in, output);
+
+ output.flip();
+ System.out.println("inOfsInBuf = " + inOfsInBuf);
+ System.out.println("outOfsInBuf = " + outOfsInBuf);
+ ByteBuffer b = ByteBuffer.wrap(baseBuf);
+ if (b.compareTo(output) != 0) {
+ System.err.println(
+ "\nresult (" + output + "):\n" +
+ byteToHex(output) +
+ "\nexpected (" + b + "):\n" +
+ byteToHex(b));
+ throw new Exception("Mismatch");
+ }
+ } catch (Exception e) {
+ throw new Exception("Error with base offset " + outOfs, e);
+ }
+ }
+ }
+ }
+ private static String byteToHex(ByteBuffer bb) {
+ StringBuilder s = new StringBuilder();
+ while (bb.remaining() > 0) {
+ s.append(String.format("%02x", bb.get()));
+ }
+ return s.toString();
+ }
+}
diff --git a/test/jdk/com/sun/crypto/provider/Cipher/AEAD/SameBuffer.java b/test/jdk/com/sun/crypto/provider/Cipher/AEAD/SameBuffer.java
index 30afb8ee8ea67..574e87a579046 100644
--- a/test/jdk/com/sun/crypto/provider/Cipher/AEAD/SameBuffer.java
+++ b/test/jdk/com/sun/crypto/provider/Cipher/AEAD/SameBuffer.java
@@ -29,12 +29,14 @@
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.GCMParameterSpec;
+import jdk.test.lib.Convert;
/*
* @test
* @bug 8048596
* @summary Check if AEAD operations work correctly when buffers used
* for storing plain text and cipher text are overlapped or the same
+ * @library /test/lib
*/
public class SameBuffer {
@@ -255,6 +257,13 @@ private void runGCMWithSeparateArray(int mode, byte[] AAD, byte[] text,
// check if two resutls are equal
if (!isEqual(text, myoff, outputText, 0, outputText.length)) {
+ System.err.println(
+ "\noutputText: len = " + outputText.length + " txtOffset = " + txtOffset + "\n" +
+ jdk.test.lib.Convert.byteArrayToHexString(outputText) + "\n" +
+ "text: len = " + text.length + " myoff = " + myoff + "\n" +
+ jdk.test.lib.Convert.byteArrayToHexString(text) + "\n" +
+ "lenght " + lenght);
+ System.err.println("tlen = " + params.getParameterSpec(GCMParameterSpec.class).getTLen() / 8);
throw new RuntimeException("Two results not equal, mode:" + mode);
}
}
@@ -387,6 +396,8 @@ private boolean isEqual(byte[] A, int offsetA, byte[] B, int offsetB,
int setB = i + offsetB;
if (setA > A.length - 1 || setB > B.length - 1
|| A[setA] != B[setB]) {
+ System.err.println("i = " + i + " A[setA] = " + A[setA] +
+ " B[setB] = " + B[setB]);
return false;
}
}
diff --git a/test/jdk/com/sun/crypto/provider/Cipher/AES/TestKATForGCM.java b/test/jdk/com/sun/crypto/provider/Cipher/AES/TestKATForGCM.java
index 3595bbd22f1e0..bdcf465f854eb 100644
--- a/test/jdk/com/sun/crypto/provider/Cipher/AES/TestKATForGCM.java
+++ b/test/jdk/com/sun/crypto/provider/Cipher/AES/TestKATForGCM.java
@@ -33,6 +33,7 @@
*/
+import java.nio.ByteBuffer;
import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;
@@ -55,6 +56,7 @@ private static byte[] HexToBytes(String hexVal) {
}
private static class TestVector {
+ int id;
SecretKey key;
byte[] plainText;
byte[] aad;
@@ -63,23 +65,41 @@ private static class TestVector {
GCMParameterSpec spec;
String info;
- TestVector(String key, String iv, String pt, String aad,
+ TestVector(int id, String key, String iv, String pt, String aad,
String ct, String tag) {
+ this.id = id;
this.key = new SecretKeySpec(HexToBytes(key), "AES");
this.plainText = HexToBytes(pt);
this.aad = HexToBytes(aad);
this.cipherText = HexToBytes(ct);
this.tag = HexToBytes(tag);
this.spec = new GCMParameterSpec(this.tag.length * 8, HexToBytes(iv));
- this.info = "key=" + key + ", iv=" + iv + ", pt=" + pt +
+ this.info = "id = " + id + ", key=" + key + ", iv=" + iv + ", pt=" + pt +
",aad=" + aad + ", ct=" + ct + ", tag=" + tag;
}
+ TestVector() {};
+
+ TestVector duplicate() {
+ TestVector t = new TestVector();
+ t.id = id;
+ t.key = key;
+ t.plainText = plainText;
+ t.cipherText = cipherText;
+ t.aad = aad;
+ t.tag = tag;
+ t.spec = spec;
+ t.info = info;
+ return t;
+ }
+
public String toString() {
return info;
}
}
+ static boolean testFailed = false;
+
// These test vectors are found off NIST's CAVP page
// http://csrc.nist.gov/groups/STM/cavp/index.html
// inside the link named "GCM Test Vectors", i.e.
@@ -88,53 +108,53 @@ public String toString() {
private static TestVector[] testValues = {
// 96-bit iv w/ 128/120/112/104/96-bit tags
// no plain text, no aad
- new TestVector("11754cd72aec309bf52f7687212e8957",
+ new TestVector(1, "11754cd72aec309bf52f7687212e8957",
"3c819d9a9bed087615030b65",
null, null, null,
"250327c674aaf477aef2675748cf6971"),
- new TestVector("272f16edb81a7abbea887357a58c1917",
+ new TestVector(2, "272f16edb81a7abbea887357a58c1917",
"794ec588176c703d3d2a7a07",
null, null, null,
"b6e6f197168f5049aeda32dafbdaeb"),
- new TestVector("81b6844aab6a568c4556a2eb7eae752f",
+ new TestVector(3, "81b6844aab6a568c4556a2eb7eae752f",
"ce600f59618315a6829bef4d",
null, null, null,
"89b43e9dbc1b4f597dbbc7655bb5"),
- new TestVector("cde2f9a9b1a004165ef9dc981f18651b",
+ new TestVector(4, "cde2f9a9b1a004165ef9dc981f18651b",
"29512c29566c7322e1e33e8e",
null, null, null,
"2e58ce7dabd107c82759c66a75"),
- new TestVector("b01e45cc3088aaba9fa43d81d481823f",
+ new TestVector(5, "b01e45cc3088aaba9fa43d81d481823f",
"5a2c4a66468713456a4bd5e1",
null, null, null,
"014280f944f53c681164b2ff"),
// 96-bit iv w/ 128/120/112/104/96-bit tags
// no plain text, 16-byte aad
- new TestVector("77be63708971c4e240d1cb79e8d77feb",
+ new TestVector(6, "77be63708971c4e240d1cb79e8d77feb",
"e0e00f19fed7ba0136a797f3",
null,
"7a43ec1d9c0a5a78a0b16533a6213cab",
null,
"209fcc8d3675ed938e9c7166709dd946"),
- new TestVector("da0b615656135194ba6d3c851099bc48",
+ new TestVector(7, "da0b615656135194ba6d3c851099bc48",
"d39d4b4d3cc927885090e6c3",
null,
"e7e5e6f8dac913036cb2ff29e8625e0e",
null,
"ab967711a5770461724460b07237e2"),
- new TestVector("7e0986937a88eef894235aba4a2f43b2",
+ new TestVector(8, "7e0986937a88eef894235aba4a2f43b2",
"92c4a631695907166b422d60",
null,
"85c185f8518f9f2cd597a8f9208fc76b",
null,
"3bb916b728df94fe9d1916736be1"),
- new TestVector("c3db570d7f0c21e86b028f11465d1dc9",
+ new TestVector(9, "c3db570d7f0c21e86b028f11465d1dc9",
"f86970f58ceef89fc7cb679e",
null,
"c095240708c0f57c288d86090ae34ee1",
null,
"e043c52160d652e82c7262fcf4"),
- new TestVector("bea48ae4980d27f357611014d4486625",
+ new TestVector(10, "bea48ae4980d27f357611014d4486625",
"32bddb5c3aa998a08556454c",
null,
"8a50b0b8c7654bced884f7f3afda2ead",
@@ -142,56 +162,56 @@ public String toString() {
"8e0f6d8bf05ffebe6f500eb1"),
// 96-bit iv w/ 128/120/112/104/96-bit tags
// no plain text, 20-byte aad
- new TestVector("2fb45e5b8f993a2bfebc4b15b533e0b4",
+ new TestVector(11, "2fb45e5b8f993a2bfebc4b15b533e0b4",
"5b05755f984d2b90f94b8027",
null,
"e85491b2202caf1d7dce03b97e09331c32473941",
null,
"c75b7832b2a2d9bd827412b6ef5769db"),
- new TestVector("9bf406339fcef9675bbcf156aa1a0661",
+ new TestVector(12, "9bf406339fcef9675bbcf156aa1a0661",
"8be4a9543d40f542abacac95",
null,
"7167cbf56971793186333a6685bbd58d47d379b3",
null,
"5e7968d7bbd5ba58cfcc750e2ef8f1"),
- new TestVector("a2e962fff70fd0f4d63be728b80556fc",
+ new TestVector(13, "a2e962fff70fd0f4d63be728b80556fc",
"1fa7103483de43d09bc23db4",
null,
"2a58edf1d53f46e4e7ee5e77ee7aeb60fc360658",
null,
"fa37f2dbbefab1451eae1d0d74ca"),
- new TestVector("6bf4fdce82926dcdfc52616ed5f23695",
+ new TestVector(14, "6bf4fdce82926dcdfc52616ed5f23695",
"cc0f5899a10615567e1193ed",
null,
"3340655592374c1da2f05aac3ee111014986107f",
null,
"8ad3385cce3b5e7c985908192c"),
- new TestVector("4df7a13e43c3d7b66b1a72fac5ba398e",
+ new TestVector(15, "4df7a13e43c3d7b66b1a72fac5ba398e",
"97179a3a2d417908dcf0fb28",
null,
"cbb7fc0010c255661e23b07dbd804b1e06ae70ac",
null,
"37791edae6c137ea946cfb40"),
// 96-bit iv w/ 128-bit tags, 13/16/32/51-byte plain text, no aad
- new TestVector("fe9bb47deb3a61e423c2231841cfd1fb",
+ new TestVector(16, "fe9bb47deb3a61e423c2231841cfd1fb",
"4d328eb776f500a2f7fb47aa",
"f1cc3818e421876bb6b8bbd6c9",
null,
"b88c5c1977b35b517b0aeae967",
"43fd4727fe5cdb4b5b42818dea7ef8c9"),
- new TestVector("7fddb57453c241d03efbed3ac44e371c",
+ new TestVector(17, "7fddb57453c241d03efbed3ac44e371c",
"ee283a3fc75575e33efd4887",
"d5de42b461646c255c87bd2962d3b9a2",
null,
"2ccda4a5415cb91e135c2a0f78c9b2fd",
"b36d1df9b9d5e596f83e8b7f52971cb3"),
- new TestVector("9971071059abc009e4f2bd69869db338",
+ new TestVector(18, "9971071059abc009e4f2bd69869db338",
"07a9a95ea3821e9c13c63251",
"f54bc3501fed4f6f6dfb5ea80106df0bd836e6826225b75c0222f6e859b35983",
null,
"0556c159f84ef36cb1602b4526b12009c775611bffb64dc0d9ca9297cd2c6a01",
"7870d9117f54811a346970f1de090c41"),
- new TestVector("594157ec4693202b030f33798b07176d",
+ new TestVector(19, "594157ec4693202b030f33798b07176d",
"49b12054082660803a1df3df",
"3feef98a976a1bd634f364ac428bb59cd51fb159ec1789946918dbd50ea6c9d594a3a31a5269b0da6936c29d063a5fa2cc8a1c",
@@ -200,26 +220,26 @@ public String toString() {
"c1b7a46a335f23d65b8db4008a49796906e225474f4fe7d39e55bf2efd97fd82d4167de082ae30fa01e465a601235d8d68bc69",
"ba92d3661ce8b04687e8788d55417dc2"),
// 96-bit iv w/ 128-bit tags, 16-byte plain text, 16/20/48/90-byte aad
- new TestVector("c939cc13397c1d37de6ae0e1cb7c423c",
+ new TestVector(20, "c939cc13397c1d37de6ae0e1cb7c423c",
"b3d8cc017cbb89b39e0f67e2",
"c3b3c41f113a31b73d9a5cd432103069",
"24825602bd12a984e0092d3e448eda5f",
"93fe7d9e9bfd10348a5606e5cafa7354",
"0032a1dc85f1c9786925a2e71d8272dd"),
- new TestVector("d4a22488f8dd1d5c6c19a7d6ca17964c",
+ new TestVector(21, "d4a22488f8dd1d5c6c19a7d6ca17964c",
"f3d5837f22ac1a0425e0d1d5",
"7b43016a16896497fb457be6d2a54122",
"f1c5d424b83f96c6ad8cb28ca0d20e475e023b5a",
"c2bd67eef5e95cac27e3b06e3031d0a8",
"f23eacf9d1cdf8737726c58648826e9c"),
- new TestVector("89850dd398e1f1e28443a33d40162664",
+ new TestVector(22, "89850dd398e1f1e28443a33d40162664",
"e462c58482fe8264aeeb7231",
"2805cdefb3ef6cc35cd1f169f98da81a",
"d74e99d1bdaa712864eec422ac507bddbe2b0d4633cd3dff29ce5059b49fe868526c59a2a3a604457bc2afea866e7606",
"ba80e244b7fc9025cd031d0f63677e06",
"d84a8c3eac57d1bb0e890a8f461d1065"),
- new TestVector("bd7c5c63b7542b56a00ebe71336a1588",
+ new TestVector(23, "bd7c5c63b7542b56a00ebe71336a1588",
"87721f23ba9c3c8ea5571abc",
"de15ddbb1e202161e8a79af6a55ac6f3",
@@ -227,17 +247,17 @@ public String toString() {
"41eb28c0fee4d762de972361c863bc80",
"9cb567220d0b252eb97bff46e4b00ff8"),
// 8/1024-bit iv w/ 128-bit tag, no plain text, no aad
- new TestVector("1672c3537afa82004c6b8a46f6f0d026",
+ new TestVector(24, "1672c3537afa82004c6b8a46f6f0d026",
"05",
null, null, null,
"8e2ad721f9455f74d8b53d3141f27e8e"),
- new TestVector("d0f1f4defa1e8c08b4b26d576392027c",
+ new TestVector(25, "d0f1f4defa1e8c08b4b26d576392027c",
"42b4f01eb9f5a1ea5b1eb73b0fb0baed54f387ecaa0393c7d7dffc6af50146ecc021abf7eb9038d4303d91f8d741a11743166c0860208bcc02c6258fd9511a2fa626f96d60b72fcff773af4e88e7a923506e4916ecbd814651e9f445adef4ad6a6b6c7290cc13b956130eef5b837c939fcac0cbbcc9656cd75b13823ee5acdac",
null, null, null,
"7ab49b57ddf5f62c427950111c5c4f0d"),
// 8-bit iv w/ 128-bit tag, 13-byte plain text, 90-byte aad
- new TestVector("9f79239f0904eace50784b863e723f6b",
+ new TestVector(26, "9f79239f0904eace50784b863e723f6b",
"d9",
"bdb0bb10c87965acd34d146171",
@@ -245,7 +265,7 @@ public String toString() {
"7e5a7c8dadb3f0c7335b4d9d8d",
"6b6ef1f53723a89f3bb7c6d043840717"),
// 1024-bit iv w/ 128-bit tag, 51-byte plain text, 48-byte aad
- new TestVector("141f1ce91989b07e7eb6ae1dbd81ea5e",
+ new TestVector(27, "141f1ce91989b07e7eb6ae1dbd81ea5e",
"49451da24bd6074509d3cebc2c0394c972e6934b45a1d91f3ce1d3ca69e194aa1958a7c21b6f21d530ce6d2cc5256a3f846b6f9d2f38df0102c4791e57df038f6e69085646007df999751e248e06c47245f4cd3b8004585a7470dee1690e9d2d63169a58d243c0b57b3e5b4a481a3e4e8c60007094ef3adea2e8f05dd3a1396f",
@@ -257,56 +277,139 @@ public String toString() {
"dbb93bbb56d0439cd09f620a57687f5d"),
};
- public boolean execute(TestVector[] testValues) throws Exception {
- boolean testFailed = false;
+ void executeArray(TestVector tv) throws Exception {
Cipher c = Cipher.getInstance("AES/GCM/NoPadding", "SunJCE");
- for (int i = 0; i < testValues.length; i++) {
- try {
- c.init(Cipher.ENCRYPT_MODE, testValues[i].key, testValues[i].spec);
- c.updateAAD(testValues[i].aad);
- byte[] ctPlusTag = c.doFinal(testValues[i].plainText);
-
- c.init(Cipher.DECRYPT_MODE, testValues[i].key, testValues[i].spec);
- c.updateAAD(testValues[i].aad);
- byte[] pt = c.doFinal(ctPlusTag); // should fail if tag mismatched
-
- // check encryption/decryption results just to be sure
- if (!Arrays.equals(testValues[i].plainText, pt)) {
- System.out.println("PlainText diff failed for test# " + i);
- testFailed = true;
- }
- int ctLen = testValues[i].cipherText.length;
- if (!Arrays.equals(testValues[i].cipherText,
- Arrays.copyOf(ctPlusTag, ctLen))) {
- System.out.println("CipherText diff failed for test# " + i);
- testFailed = true;
- }
- int tagLen = testValues[i].tag.length;
- if (!Arrays.equals
- (testValues[i].tag,
- Arrays.copyOfRange(ctPlusTag, ctLen, ctLen+tagLen))) {
- System.out.println("Tag diff failed for test# " + i);
- testFailed = true;
- }
- } catch (Exception ex) {
- // continue testing other test vectors
- System.out.println("Failed Test Vector: " + testValues[i]);
- ex.printStackTrace();
+ try {
+ System.out.println("Test #" + tv.id + ": byte[].");
+
+ c.init(Cipher.ENCRYPT_MODE, tv.key, tv.spec);
+ c.updateAAD(tv.aad);
+ byte[] ctPlusTag = c.doFinal(tv.plainText);
+
+ c.init(Cipher.DECRYPT_MODE, tv.key, tv.spec);
+ c.updateAAD(tv.aad);
+ byte[] pt = c.doFinal(ctPlusTag); // should fail if tag mismatched
+
+ // check encryption/decryption results just to be sure
+ if (!Arrays.equals(tv.plainText, pt)) {
+ System.out.println("PlainText diff failed for test# " + tv.id);
testFailed = true;
- continue;
}
+ int ctLen = tv.cipherText.length;
+ if (!Arrays.equals(tv.cipherText,
+ Arrays.copyOf(ctPlusTag, ctLen))) {
+ System.out.println("CipherText diff failed for test# " + tv.id);
+ testFailed = true;
+ }
+ int tagLen = tv.tag.length;
+ if (!Arrays.equals
+ (tv.tag,
+ Arrays.copyOfRange(ctPlusTag, ctLen, ctLen+tagLen))) {
+ System.out.println("Tag diff failed for test# " + tv.id);
+ testFailed = true;
+ }
+ } catch (Exception ex) {
+ // continue testing other test vectors
+ System.out.println("Failed Test Vector: " + tv);
+ ex.printStackTrace();
+ testFailed = true;
}
if (testFailed) {
throw new Exception("Test Failed");
}
- // passed all tests...hooray!
- return true;
+ }
+
+ void executeByteBuffer(TestVector tv, boolean direct, int offset) throws Exception {
+ Cipher c = Cipher.getInstance("AES/GCM/NoPadding", "SunJCE");
+
+ ByteBuffer src;
+ ByteBuffer ctdst;
+ ByteBuffer ptdst;
+
+ if (direct) {
+ System.out.print("Test #" + tv.id + ": ByteBuffer Direct.");
+ src = ByteBuffer.allocateDirect(tv.plainText.length + offset);
+ ctdst = ByteBuffer.allocateDirect(tv.cipherText.length + tv.tag.length + offset);
+ ptdst = ByteBuffer.allocateDirect(tv.plainText.length + offset);
+ } else {
+ System.out.print("Test #" + tv.id + ": ByteBuffer Heap.");
+ src = ByteBuffer.allocate(tv.plainText.length + offset);
+ ctdst = ByteBuffer.allocate(tv.cipherText.length + tv.tag.length + offset);
+ ptdst = ByteBuffer.allocate(tv.plainText.length + offset);
+ }
+
+ byte[] plainText;
+
+ if (offset > 0) {
+ System.out.println(" offset = " + offset);
+ plainText = new byte[tv.plainText.length + offset];
+ System.arraycopy(tv.plainText, 0, plainText, offset,
+ tv.plainText.length);
+ } else {
+ System.out.println();
+ plainText = tv.plainText;
+ }
+
+ src.put(plainText);
+ src.position(offset);
+ ctdst.position(offset);
+ ctdst.mark();
+ ptdst.position(offset);
+ ptdst.mark();
+
+ try {
+ c.init(Cipher.ENCRYPT_MODE, tv.key, tv.spec);
+ c.updateAAD(tv.aad);
+ c.doFinal(src, ctdst);
+
+ ctdst.reset();
+ ByteBuffer tag = ctdst.duplicate();
+ tag.position(tag.limit() - tv.tag.length);
+
+ c.init(Cipher.DECRYPT_MODE, tv.key, tv.spec);
+ c.updateAAD(tv.aad);
+ c.doFinal(ctdst, ptdst); // should fail if tag mismatched
+
+ ptdst.reset();
+ // check encryption/decryption results just to be sure
+ if (ptdst.compareTo(ByteBuffer.wrap(tv.plainText)) != 0) {
+ System.out.println("\t PlainText diff failed for test# " + tv.id);
+ testFailed = true;
+ }
+
+ ctdst.reset();
+ ctdst.limit(ctdst.limit() - tv.tag.length);
+ if (ctdst.compareTo(ByteBuffer.wrap(tv.cipherText)) != 0) {
+ System.out.println("\t CipherText diff failed for test# " + tv.id);
+ testFailed = true;
+ }
+
+ int mismatch = 0;
+ for (int i = 0; i < tv.tag.length; i++) {
+ mismatch |= tag.get() ^ tv.tag[i];
+ }
+ if (mismatch != 0) {
+ System.out.println("\t Tag diff failed for test# " + tv.id);
+ testFailed = true;
+ }
+ } catch (Exception ex) {
+ // continue testing other test vectors
+ System.out.println("\t Failed Test Vector ( #" + tv.id + ") : " + tv);
+ ex.printStackTrace();
+ }
}
public static void main (String[] args) throws Exception {
TestKATForGCM test = new TestKATForGCM();
- if (test.execute(testValues)) {
- System.out.println("Test Passed!");
+ for (TestVector tv : testValues) {
+ test.executeArray(tv);
+ test.executeByteBuffer(tv, false, 0);
+ test.executeByteBuffer(tv, true, 0);
+ test.executeByteBuffer(tv, false, 2);
+ test.executeByteBuffer(tv, true, 2);
+ }
+ if (!testFailed) {
+ System.out.println("Tests passed");
}
}
}
diff --git a/test/jdk/com/sun/crypto/provider/Cipher/TextLength/SameBufferOverwrite.java b/test/jdk/com/sun/crypto/provider/Cipher/TextLength/SameBufferOverwrite.java
new file mode 100644
index 0000000000000..d110c05a339ef
--- /dev/null
+++ b/test/jdk/com/sun/crypto/provider/Cipher/TextLength/SameBufferOverwrite.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 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.
+ */
+
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import java.security.AlgorithmParameters;
+import java.util.Arrays;
+
+
+/*
+ * @test
+ * @summary Verify when decrypting over an existing buffer than padding does not
+ * overwrite past what the plaintext length is.
+ *
+ */
+
+public class SameBufferOverwrite {
+
+ private SecretKey skey;
+ private Cipher c;
+ private int start = 17, end = 17; // default
+
+ SameBufferOverwrite(String algo, String transformation)
+ throws Exception {
+
+ KeyGenerator kg = KeyGenerator.getInstance(algo, "SunJCE");
+ skey = kg.generateKey();
+ c = Cipher.getInstance(transformation, "SunJCE");
+ }
+
+ /*
+ * Run the test
+ */
+ void test() throws Exception {
+ byte[] in = new byte[end + (c.getBlockSize() - (end % c.getBlockSize()))];
+ Arrays.fill(in, (byte)8);
+ int len = start;
+ AlgorithmParameters params = null;
+
+ System.out.println("Testing transformation: " + c.getAlgorithm() +
+ ", byte length from " + start + " to " + end);
+ while (end >= len) {
+ // encrypt
+ c.init(Cipher.ENCRYPT_MODE, skey, params);
+ byte[] out = c.doFinal(in, 0, len);
+ System.out.println(" enc = " + byteToHex(out));
+ System.out.println(" => enc " + len + " bytes, ret " +
+ (out == null ? "null" : (out.length + " byte")));
+
+ // decrypt
+ params = c.getParameters();
+ c.init(Cipher.DECRYPT_MODE, skey, params);
+ int rLen = c.doFinal(out, 0, out.length, in);
+ System.out.println(" dec = " + byteToHex(in));
+ System.out.println(" => dec " + out.length + " bytes, ret " +
+ rLen + " byte");
+ // check if more than rLen bytes are written into 'in'
+ for (int j = rLen; j < in.length; j++) {
+ if (in[j] != (byte) 8) {
+ throw new Exception("Value check failed at index " + j);
+ }
+ }
+ System.out.println(" Test Passed: len = " + len);
+ len++;
+
+ // Because GCM doesn't allow params reuse
+ if (c.getAlgorithm().contains("GCM")) {
+ params = null;
+ }
+ }
+ }
+
+ /**
+ * Builder method for the test to run data lengths from the start value to
+ * the end value. To do one length, have start and end equal that number.
+ * @param start starting data length
+ * @param end ending data length
+ */
+ SameBufferOverwrite iterate(int start, int end) {
+ this.start = start;
+ this.end = end;
+ return this;
+ }
+
+ public static void main(String args[]) throws Exception {
+ new SameBufferOverwrite("AES", "AES/GCM/NoPadding").iterate(1, 25).
+ test();
+ new SameBufferOverwrite("AES", "AES/CTR/NoPadding").iterate(1, 25).
+ test();
+ new SameBufferOverwrite("AES", "AES/CBC/PKCS5Padding").iterate(1, 25).
+ test();
+ new SameBufferOverwrite("AES", "AES/ECB/PKCS5Padding").iterate(1, 25).
+ test();
+ new SameBufferOverwrite("DES", "DES/CBC/PKCS5Padding").iterate(1, 17).
+ test();
+ new SameBufferOverwrite("DESede", "DESede/CBC/PKCS5Padding").iterate(1, 17).
+ test();
+ }
+
+ private static String byteToHex(byte[] barray) {
+ StringBuilder s = new StringBuilder();
+ for (byte b : barray) {
+ s.append(String.format("%02x", b));
+ }
+ return s.toString();
+ }
+}
diff --git a/test/jdk/javax/crypto/CipherSpi/CipherByteBufferOverwriteTest.java b/test/jdk/javax/crypto/CipherSpi/CipherByteBufferOverwriteTest.java
index 2fdd4f05a6973..260d667714744 100644
--- a/test/jdk/javax/crypto/CipherSpi/CipherByteBufferOverwriteTest.java
+++ b/test/jdk/javax/crypto/CipherSpi/CipherByteBufferOverwriteTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 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
@@ -26,15 +26,21 @@
* @bug 8181386
* @summary CipherSpi ByteBuffer to byte array conversion fails for
* certain data overlap conditions
- * @run main CipherByteBufferOverwriteTest 0 false
- * @run main CipherByteBufferOverwriteTest 0 true
- * @run main CipherByteBufferOverwriteTest 4 false
- * @run main CipherByteBufferOverwriteTest 4 true
+ * @run main CipherByteBufferOverwriteTest AES/CBC/PKCS5Padding 0 false
+ * @run main CipherByteBufferOverwriteTest AES/CBC/PKCS5Padding 0 true
+ * @run main CipherByteBufferOverwriteTest AES/CBC/PKCS5Padding 4 false
+ * @run main CipherByteBufferOverwriteTest AES/CBC/PKCS5Padding 4 true
+ * @run main CipherByteBufferOverwriteTest AES/GCM/NoPadding 0 false
+ * @run main CipherByteBufferOverwriteTest AES/GCM/NoPadding 0 true
+ * @run main CipherByteBufferOverwriteTest AES/GCM/NoPadding 4 false
+ * @run main CipherByteBufferOverwriteTest AES/GCM/NoPadding 4 true
*/
+import java.math.BigInteger;
import java.security.spec.AlgorithmParameterSpec;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
+import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.ByteBuffer;
@@ -44,7 +50,7 @@ public class CipherByteBufferOverwriteTest {
private static final boolean DEBUG = false;
- private static final String TRANSFORMATION = "AES/CBC/PKCS5Padding";
+ private static String transformation;
// must be larger than the temp array size, i.e. 4096, hardcoded in
// javax.crypto.CipherSpi class
@@ -53,8 +59,7 @@ public class CipherByteBufferOverwriteTest {
private static final int CIPHERTEXT_BUFFER_SIZE = PLAINTEXT_SIZE + 32;
private static final SecretKey KEY = new SecretKeySpec(new byte[16], "AES");
- private static final AlgorithmParameterSpec PARAMS =
- new IvParameterSpec(new byte[16]);
+ private static AlgorithmParameterSpec params;
private static ByteBuffer inBuf;
private static ByteBuffer outBuf;
@@ -65,9 +70,15 @@ private enum BufferType {
public static void main(String[] args) throws Exception {
- int offset = Integer.parseInt(args[0]);
- boolean useRO = Boolean.parseBoolean(args[1]);
+ transformation = args[0];
+ int offset = Integer.parseInt(args[1]);
+ boolean useRO = Boolean.parseBoolean(args[2]);
+ if (transformation.equalsIgnoreCase("AES/GCM/NoPadding")) {
+ params = new GCMParameterSpec(16 * 8, new byte[16]);
+ } else {
+ params = new IvParameterSpec(new byte[16]);
+ }
// an all-zeros plaintext is the easiest way to demonstrate the issue,
// but it fails with any plaintext, of course
byte[] expectedPT = new byte[PLAINTEXT_SIZE];
@@ -75,8 +86,8 @@ public static void main(String[] args) throws Exception {
System.arraycopy(expectedPT, 0, buf, 0, PLAINTEXT_SIZE);
// generate expected cipher text using byte[] methods
- Cipher c = Cipher.getInstance(TRANSFORMATION);
- c.init(Cipher.ENCRYPT_MODE, KEY, PARAMS);
+ Cipher c = Cipher.getInstance(transformation);
+ c.init(Cipher.ENCRYPT_MODE, KEY, params);
byte[] expectedCT = c.doFinal(expectedPT);
// Test#1: against ByteBuffer generated with allocate(int) call
@@ -89,9 +100,9 @@ public static void main(String[] args) throws Exception {
// Test#2: against direct ByteBuffer
prepareBuffers(BufferType.DIRECT, useRO, buf.length,
buf, 0, PLAINTEXT_SIZE, offset);
- System.out.println("\tDIRECT: passed");
runTest(offset, expectedPT, expectedCT);
+ System.out.println("\tDIRECT: passed");
// Test#3: against ByteBuffer wrapping existing array
prepareBuffers(BufferType.WRAP, useRO, buf.length,
@@ -150,8 +161,8 @@ private static void prepareBuffers(BufferType type,
private static void runTest(int ofs, byte[] expectedPT, byte[] expectedCT)
throws Exception {
- Cipher c = Cipher.getInstance(TRANSFORMATION);
- c.init(Cipher.ENCRYPT_MODE, KEY, PARAMS);
+ Cipher c = Cipher.getInstance(transformation);
+ c.init(Cipher.ENCRYPT_MODE, KEY, params);
int ciphertextSize = c.doFinal(inBuf, outBuf);
// read out the encrypted result
@@ -166,14 +177,20 @@ private static void runTest(int ofs, byte[] expectedPT, byte[] expectedCT)
outBuf.get(finalCT);
if (!Arrays.equals(finalCT, expectedCT)) {
+ System.err.println("Ciphertext mismatch:" +
+ "\nresult (len=" + finalCT.length + "):\n" +
+ String.format("%0" + (finalCT.length << 1) + "x",
+ new BigInteger(1, finalCT)) +
+ "\nexpected (len=" + expectedCT.length + "):\n" +
+ String.format("%0" + (expectedCT.length << 1) + "x",
+ new BigInteger(1, expectedCT)));
throw new Exception("ERROR: Ciphertext does not match");
}
// now do decryption
outBuf.position(ofs);
outBuf.limit(ofs + ciphertextSize);
-
- c.init(Cipher.DECRYPT_MODE, KEY, PARAMS);
+ c.init(Cipher.DECRYPT_MODE, KEY, params);
ByteBuffer finalPTBuf = ByteBuffer.allocate(
c.getOutputSize(outBuf.remaining()));
c.doFinal(outBuf, finalPTBuf);
@@ -184,6 +201,13 @@ private static void runTest(int ofs, byte[] expectedPT, byte[] expectedCT)
finalPTBuf.get(finalPT);
if (!Arrays.equals(finalPT, expectedPT)) {
+ System.err.println("Ciphertext mismatch " +
+ "):\nresult (len=" + finalCT.length + "):\n" +
+ String.format("%0" + (finalCT.length << 1) + "x",
+ new BigInteger(1, finalCT)) +
+ "\nexpected (len=" + expectedCT.length + "):\n" +
+ String.format("%0" + (expectedCT.length << 1) + "x",
+ new BigInteger(1, expectedCT)));
throw new Exception("ERROR: Plaintext does not match");
}
}
diff --git a/test/jdk/javax/net/ssl/SSLSession/CheckSessionContext.java b/test/jdk/javax/net/ssl/SSLSession/CheckSessionContext.java
index b0d15afc53627..98c7afb2738f7 100644
--- a/test/jdk/javax/net/ssl/SSLSession/CheckSessionContext.java
+++ b/test/jdk/javax/net/ssl/SSLSession/CheckSessionContext.java
@@ -31,11 +31,21 @@
* @run main/othervm -Djdk.tls.client.protocols=TLSv1.2 -Djdk.tls.server.enableSessionTicketExtension=true -Djdk.tls.client.enableSessionTicketExtension=true CheckSessionContext
* @run main/othervm -Djdk.tls.client.protocols=TLSv1.3 -Djdk.tls.server.enableSessionTicketExtension=true -Djdk.tls.client.enableSessionTicketExtension=false CheckSessionContext
* @run main/othervm -Djdk.tls.client.protocols=TLSv1.3 -Djdk.tls.server.enableSessionTicketExtension=true -Djdk.tls.client.enableSessionTicketExtension=true CheckSessionContext
+ * @run main/othervm -Djdk.tls.client.protocols=TLSv1.3 -Djdk.tls.server.enableSessionTicketExtension=false -Djdk.tls.client.enableSessionTicketExtension=true CheckSessionContext
*
*/
+import javax.net.ssl.SSLSession;
+
public class CheckSessionContext {
+ static void toHex(byte[] id) {
+ for (byte b : id) {
+ System.out.printf("%02X ", b);
+ }
+ System.out.println();
+ }
+
public static void main(String[] args) throws Exception {
TLSBase.Server server = new TLSBase.Server();
@@ -46,6 +56,17 @@ public static void main(String[] args) throws Exception {
} else {
System.out.println("Context was found");
}
+ SSLSession ss = server.getSession(client1);
+ System.out.println(ss);
+ byte[] id = ss.getId();
+ System.out.print("id = ");
+ toHex(id);
+ System.out.println("ss.getSessionContext().getSession(id) = " + ss.getSessionContext().getSession(id));
+ if (ss.getSessionContext().getSession(id) != null) {
+ id = ss.getSessionContext().getSession(id).getId();
+ System.out.print("id = ");
+ toHex(id);
+ }
server.close(client1);
client1.close();
From 02a0a027f49765e6d9103ef3169008d33176edd9 Mon Sep 17 00:00:00 2001
From: Ioi Lam
Date: Thu, 3 Dec 2020 01:34:04 +0000
Subject: [PATCH 033/504] 8257563: Remove excessive include of klass.inline.hpp
Reviewed-by: dholmes, stuefe, stefank
---
.../arm/templateInterpreterGenerator_arm.cpp | 1 +
src/hotspot/cpu/arm/templateTable_arm.cpp | 1 +
.../ppc/templateInterpreterGenerator_ppc.cpp | 1 +
src/hotspot/cpu/s390/s390.ad | 2 +
.../templateInterpreterGenerator_s390.cpp | 1 +
src/hotspot/cpu/s390/templateTable_s390.cpp | 1 +
.../x86/templateInterpreterGenerator_x86.cpp | 1 +
.../cpu/zero/bytecodeInterpreter_zero.cpp | 1 +
src/hotspot/cpu/zero/methodHandles_zero.cpp | 2 +
src/hotspot/cpu/zero/zeroInterpreter_zero.cpp | 1 +
src/hotspot/share/c1/c1_Runtime1.cpp | 1 +
src/hotspot/share/ci/ciEnv.cpp | 1 +
src/hotspot/share/ci/ciField.cpp | 2 +
src/hotspot/share/ci/ciInstanceKlass.cpp | 3 +
src/hotspot/share/ci/ciKlass.cpp | 3 +-
src/hotspot/share/ci/ciReplay.cpp | 2 +
src/hotspot/share/classfile/altHashing.cpp | 1 +
.../share/classfile/classFileParser.cpp | 2 +-
src/hotspot/share/classfile/classLoader.cpp | 1 +
.../share/classfile/classLoaderData.cpp | 1 +
.../share/classfile/classLoaderExt.cpp | 1 +
.../share/classfile/fieldLayoutBuilder.cpp | 1 +
src/hotspot/share/classfile/javaClasses.cpp | 3 +-
.../classfile/systemDictionaryShared.cpp | 8 ++
.../classfile/systemDictionaryShared.hpp | 11 +--
src/hotspot/share/classfile/verifier.cpp | 3 +-
src/hotspot/share/classfile/vmSymbols.cpp | 1 +
src/hotspot/share/code/vtableStubs.cpp | 1 +
src/hotspot/share/compiler/compileBroker.cpp | 1 +
src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp | 1 +
.../gc/shared/modRefBarrierSet.inline.hpp | 5 +-
.../share/interpreter/interpreterRuntime.cpp | 3 +-
.../share/interpreter/linkResolver.cpp | 3 +-
.../interpreter/zero/bytecodeInterpreter.cpp | 3 +
.../jfrEventClassTransformer.cpp | 1 +
src/hotspot/share/jfr/jni/jfrJavaSupport.cpp | 1 +
.../recorder/checkpoint/types/jfrTypeSet.cpp | 2 +-
.../share/jfr/support/jfrJdkJfrEvent.cpp | 3 +-
.../share/jvmci/jvmciCodeInstaller.cpp | 1 +
src/hotspot/share/jvmci/jvmciCompilerToVM.cpp | 1 +
src/hotspot/share/jvmci/jvmciJavaClasses.cpp | 1 +
src/hotspot/share/jvmci/jvmciRuntime.cpp | 1 +
src/hotspot/share/memory/dynamicArchive.cpp | 1 +
src/hotspot/share/memory/metaspaceShared.cpp | 1 +
src/hotspot/share/memory/universe.cpp | 1 +
src/hotspot/share/oops/arrayKlass.cpp | 1 +
src/hotspot/share/oops/constantPool.cpp | 1 +
src/hotspot/share/oops/instanceKlass.hpp | 82 +++----------------
.../share/oops/instanceKlass.inline.hpp | 79 +++++++++++++++++-
src/hotspot/share/oops/klassVtable.cpp | 3 +-
src/hotspot/share/oops/method.cpp | 1 +
src/hotspot/share/oops/oop.inline.hpp | 1 -
src/hotspot/share/prims/jni.cpp | 1 +
src/hotspot/share/prims/jvm.cpp | 1 +
src/hotspot/share/prims/jvmtiEnv.cpp | 1 +
src/hotspot/share/prims/jvmtiEnvBase.cpp | 2 +
src/hotspot/share/prims/jvmtiExport.cpp | 1 +
.../share/prims/jvmtiGetLoadedClasses.cpp | 4 +-
src/hotspot/share/prims/jvmtiImpl.cpp | 2 +
.../share/prims/jvmtiRedefineClasses.cpp | 1 +
src/hotspot/share/prims/jvmtiTagMap.cpp | 1 +
src/hotspot/share/prims/methodHandles.cpp | 1 +
src/hotspot/share/prims/nativeLookup.cpp | 1 +
src/hotspot/share/prims/stackwalk.cpp | 1 +
.../share/prims/universalUpcallHandler.cpp | 1 +
src/hotspot/share/prims/unsafe.cpp | 1 +
src/hotspot/share/prims/vectorSupport.cpp | 1 +
src/hotspot/share/prims/whitebox.cpp | 1 +
src/hotspot/share/runtime/fieldDescriptor.cpp | 3 +-
src/hotspot/share/runtime/java.cpp | 1 +
src/hotspot/share/runtime/objectMonitor.cpp | 2 +
src/hotspot/share/runtime/reflection.cpp | 3 +-
src/hotspot/share/runtime/sharedRuntime.cpp | 1 +
src/hotspot/share/runtime/signature.cpp | 1 +
src/hotspot/share/runtime/statSampler.cpp | 3 +-
src/hotspot/share/runtime/thread.cpp | 2 +
.../share/services/diagnosticCommand.cpp | 1 +
src/hotspot/share/services/gcNotifier.cpp | 1 +
src/hotspot/share/services/heapDumper.cpp | 1 +
src/hotspot/share/services/management.cpp | 2 +
src/hotspot/share/services/memoryManager.cpp | 2 +
src/hotspot/share/services/memoryPool.cpp | 2 +
src/hotspot/share/services/threadService.cpp | 1 +
src/hotspot/share/utilities/debug.cpp | 1 +
src/hotspot/share/utilities/exceptions.cpp | 1 +
85 files changed, 209 insertions(+), 96 deletions(-)
diff --git a/src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp b/src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp
index 0af4a3e9ade76..aa9d1e117c349 100644
--- a/src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp
+++ b/src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp
@@ -25,6 +25,7 @@
#include "precompiled.hpp"
#include "asm/assembler.hpp"
#include "asm/macroAssembler.inline.hpp"
+#include "classfile/javaClasses.hpp"
#include "interpreter/bytecodeHistogram.hpp"
#include "interpreter/interp_masm.hpp"
#include "interpreter/interpreter.hpp"
diff --git a/src/hotspot/cpu/arm/templateTable_arm.cpp b/src/hotspot/cpu/arm/templateTable_arm.cpp
index 6ca5d10b23c31..ccfd7a6f166b2 100644
--- a/src/hotspot/cpu/arm/templateTable_arm.cpp
+++ b/src/hotspot/cpu/arm/templateTable_arm.cpp
@@ -31,6 +31,7 @@
#include "interpreter/templateTable.hpp"
#include "memory/universe.hpp"
#include "oops/cpCache.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/methodData.hpp"
#include "oops/objArrayKlass.hpp"
#include "oops/oop.inline.hpp"
diff --git a/src/hotspot/cpu/ppc/templateInterpreterGenerator_ppc.cpp b/src/hotspot/cpu/ppc/templateInterpreterGenerator_ppc.cpp
index a59265a714c83..59af7c64e3404 100644
--- a/src/hotspot/cpu/ppc/templateInterpreterGenerator_ppc.cpp
+++ b/src/hotspot/cpu/ppc/templateInterpreterGenerator_ppc.cpp
@@ -25,6 +25,7 @@
#include "precompiled.hpp"
#include "asm/macroAssembler.inline.hpp"
+#include "classfile/javaClasses.hpp"
#include "gc/shared/barrierSetAssembler.hpp"
#include "interpreter/bytecodeHistogram.hpp"
#include "interpreter/interpreter.hpp"
diff --git a/src/hotspot/cpu/s390/s390.ad b/src/hotspot/cpu/s390/s390.ad
index b924b74f1ee24..b05432d6dc036 100644
--- a/src/hotspot/cpu/s390/s390.ad
+++ b/src/hotspot/cpu/s390/s390.ad
@@ -1325,6 +1325,8 @@ source_hpp %{
// To keep related declarations/definitions/uses close together,
// we switch between source %{ }% and source_hpp %{ }% freely as needed.
+#include "oops/klass.inline.hpp"
+
//--------------------------------------------------------------
// Used for optimization in Compile::Shorten_branches
//--------------------------------------------------------------
diff --git a/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp b/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp
index e1862f11c493c..9014a3045ce83 100644
--- a/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp
+++ b/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp
@@ -25,6 +25,7 @@
#include "precompiled.hpp"
#include "asm/macroAssembler.inline.hpp"
+#include "classfile/javaClasses.hpp"
#include "gc/shared/barrierSetAssembler.hpp"
#include "interpreter/abstractInterpreter.hpp"
#include "interpreter/bytecodeHistogram.hpp"
diff --git a/src/hotspot/cpu/s390/templateTable_s390.cpp b/src/hotspot/cpu/s390/templateTable_s390.cpp
index daaacf27fb215..485d6d962e898 100644
--- a/src/hotspot/cpu/s390/templateTable_s390.cpp
+++ b/src/hotspot/cpu/s390/templateTable_s390.cpp
@@ -31,6 +31,7 @@
#include "interpreter/interp_masm.hpp"
#include "interpreter/templateTable.hpp"
#include "memory/universe.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/methodData.hpp"
#include "oops/objArrayKlass.hpp"
#include "oops/oop.inline.hpp"
diff --git a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp
index 072b3d144fa8d..2025f41ffb608 100644
--- a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp
+++ b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp
@@ -24,6 +24,7 @@
#include "precompiled.hpp"
#include "asm/macroAssembler.hpp"
+#include "classfile/javaClasses.hpp"
#include "compiler/disassembler.hpp"
#include "gc/shared/barrierSetAssembler.hpp"
#include "interpreter/bytecodeHistogram.hpp"
diff --git a/src/hotspot/cpu/zero/bytecodeInterpreter_zero.cpp b/src/hotspot/cpu/zero/bytecodeInterpreter_zero.cpp
index f165de3a086af..de44d3afb5842 100644
--- a/src/hotspot/cpu/zero/bytecodeInterpreter_zero.cpp
+++ b/src/hotspot/cpu/zero/bytecodeInterpreter_zero.cpp
@@ -28,6 +28,7 @@
#include "interpreter/interpreter.hpp"
#include "interpreter/interpreterRuntime.hpp"
#include "interpreter/zero/bytecodeInterpreter.inline.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/methodData.hpp"
#include "oops/method.hpp"
#include "oops/oop.inline.hpp"
diff --git a/src/hotspot/cpu/zero/methodHandles_zero.cpp b/src/hotspot/cpu/zero/methodHandles_zero.cpp
index 851be31fe3773..fa347e427cd3c 100644
--- a/src/hotspot/cpu/zero/methodHandles_zero.cpp
+++ b/src/hotspot/cpu/zero/methodHandles_zero.cpp
@@ -30,6 +30,8 @@
#include "interpreter/zero/zeroInterpreterGenerator.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp"
+#include "oops/instanceKlass.inline.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/method.inline.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/frame.inline.hpp"
diff --git a/src/hotspot/cpu/zero/zeroInterpreter_zero.cpp b/src/hotspot/cpu/zero/zeroInterpreter_zero.cpp
index 900e65b416a8c..9300338051b59 100644
--- a/src/hotspot/cpu/zero/zeroInterpreter_zero.cpp
+++ b/src/hotspot/cpu/zero/zeroInterpreter_zero.cpp
@@ -33,6 +33,7 @@
#include "interpreter/zero/zeroInterpreterGenerator.hpp"
#include "oops/access.inline.hpp"
#include "oops/cpCache.inline.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/methodData.hpp"
#include "oops/method.hpp"
#include "oops/oop.inline.hpp"
diff --git a/src/hotspot/share/c1/c1_Runtime1.cpp b/src/hotspot/share/c1/c1_Runtime1.cpp
index c06c5bca085e6..8045fbfaa59e6 100644
--- a/src/hotspot/share/c1/c1_Runtime1.cpp
+++ b/src/hotspot/share/c1/c1_Runtime1.cpp
@@ -52,6 +52,7 @@
#include "memory/resourceArea.hpp"
#include "memory/universe.hpp"
#include "oops/access.inline.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/objArrayOop.inline.hpp"
#include "oops/objArrayKlass.hpp"
#include "oops/oop.inline.hpp"
diff --git a/src/hotspot/share/ci/ciEnv.cpp b/src/hotspot/share/ci/ciEnv.cpp
index 04db31908d266..cb823998e309e 100644
--- a/src/hotspot/share/ci/ciEnv.cpp
+++ b/src/hotspot/share/ci/ciEnv.cpp
@@ -33,6 +33,7 @@
#include "ci/ciNullObject.hpp"
#include "ci/ciReplay.hpp"
#include "ci/ciUtilities.inline.hpp"
+#include "classfile/javaClasses.hpp"
#include "classfile/symbolTable.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
diff --git a/src/hotspot/share/ci/ciField.cpp b/src/hotspot/share/ci/ciField.cpp
index f5abad6bc1079..83af90fe51fa6 100644
--- a/src/hotspot/share/ci/ciField.cpp
+++ b/src/hotspot/share/ci/ciField.cpp
@@ -26,9 +26,11 @@
#include "ci/ciField.hpp"
#include "ci/ciInstanceKlass.hpp"
#include "ci/ciUtilities.inline.hpp"
+#include "classfile/javaClasses.hpp"
#include "classfile/systemDictionary.hpp"
#include "gc/shared/collectedHeap.inline.hpp"
#include "interpreter/linkResolver.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/fieldDescriptor.inline.hpp"
#include "runtime/handles.inline.hpp"
diff --git a/src/hotspot/share/ci/ciInstanceKlass.cpp b/src/hotspot/share/ci/ciInstanceKlass.cpp
index 4fb1be82e988f..85ab8d353401f 100644
--- a/src/hotspot/share/ci/ciInstanceKlass.cpp
+++ b/src/hotspot/share/ci/ciInstanceKlass.cpp
@@ -28,9 +28,12 @@
#include "ci/ciInstanceKlass.hpp"
#include "ci/ciUtilities.inline.hpp"
#include "classfile/systemDictionary.hpp"
+#include "classfile/javaClasses.hpp"
#include "memory/allocation.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp"
+#include "oops/instanceKlass.inline.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/oop.inline.hpp"
#include "oops/fieldStreams.inline.hpp"
#include "runtime/fieldDescriptor.inline.hpp"
diff --git a/src/hotspot/share/ci/ciKlass.cpp b/src/hotspot/share/ci/ciKlass.cpp
index 8ceb326dd69f0..c78a761bad501 100644
--- a/src/hotspot/share/ci/ciKlass.cpp
+++ b/src/hotspot/share/ci/ciKlass.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -26,6 +26,7 @@
#include "ci/ciKlass.hpp"
#include "ci/ciSymbol.hpp"
#include "ci/ciUtilities.inline.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/oop.inline.hpp"
// ciKlass
diff --git a/src/hotspot/share/ci/ciReplay.cpp b/src/hotspot/share/ci/ciReplay.cpp
index fc66729a3bb77..1395f24cff0d4 100644
--- a/src/hotspot/share/ci/ciReplay.cpp
+++ b/src/hotspot/share/ci/ciReplay.cpp
@@ -29,12 +29,14 @@
#include "ci/ciSymbol.hpp"
#include "ci/ciKlass.hpp"
#include "ci/ciUtilities.inline.hpp"
+#include "classfile/javaClasses.hpp"
#include "classfile/symbolTable.hpp"
#include "compiler/compileBroker.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/oopFactory.hpp"
#include "memory/resourceArea.hpp"
#include "oops/constantPool.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/method.inline.hpp"
#include "oops/oop.inline.hpp"
#include "prims/jvmtiExport.hpp"
diff --git a/src/hotspot/share/classfile/altHashing.cpp b/src/hotspot/share/classfile/altHashing.cpp
index a01e6e29fb73d..cf9b9cffcd7ae 100644
--- a/src/hotspot/share/classfile/altHashing.cpp
+++ b/src/hotspot/share/classfile/altHashing.cpp
@@ -43,6 +43,7 @@
#include "precompiled.hpp"
#include "classfile/altHashing.hpp"
#include "classfile/systemDictionary.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/markWord.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/os.hpp"
diff --git a/src/hotspot/share/classfile/classFileParser.cpp b/src/hotspot/share/classfile/classFileParser.cpp
index ecf83005854a4..f0463f2c3bbfb 100644
--- a/src/hotspot/share/classfile/classFileParser.cpp
+++ b/src/hotspot/share/classfile/classFileParser.cpp
@@ -50,7 +50,7 @@
#include "oops/annotations.hpp"
#include "oops/constantPool.inline.hpp"
#include "oops/fieldStreams.inline.hpp"
-#include "oops/instanceKlass.hpp"
+#include "oops/instanceKlass.inline.hpp"
#include "oops/instanceMirrorKlass.hpp"
#include "oops/klass.inline.hpp"
#include "oops/klassVtable.hpp"
diff --git a/src/hotspot/share/classfile/classLoader.cpp b/src/hotspot/share/classfile/classLoader.cpp
index 7b34ef939c5d4..8dcd7985a40f2 100644
--- a/src/hotspot/share/classfile/classLoader.cpp
+++ b/src/hotspot/share/classfile/classLoader.cpp
@@ -52,6 +52,7 @@
#include "memory/universe.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/instanceRefKlass.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/method.inline.hpp"
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
diff --git a/src/hotspot/share/classfile/classLoaderData.cpp b/src/hotspot/share/classfile/classLoaderData.cpp
index ac699ada874ba..35e6bad112a05 100644
--- a/src/hotspot/share/classfile/classLoaderData.cpp
+++ b/src/hotspot/share/classfile/classLoaderData.cpp
@@ -64,6 +64,7 @@
#include "memory/resourceArea.hpp"
#include "memory/universe.hpp"
#include "oops/access.inline.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/oop.inline.hpp"
#include "oops/oopHandle.inline.hpp"
#include "oops/weakHandle.inline.hpp"
diff --git a/src/hotspot/share/classfile/classLoaderExt.cpp b/src/hotspot/share/classfile/classLoaderExt.cpp
index 666b45404e03a..04a8923060e89 100644
--- a/src/hotspot/share/classfile/classLoaderExt.cpp
+++ b/src/hotspot/share/classfile/classLoaderExt.cpp
@@ -38,6 +38,7 @@
#include "memory/filemap.hpp"
#include "memory/resourceArea.hpp"
#include "oops/instanceKlass.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/oop.inline.hpp"
#include "oops/symbol.hpp"
#include "runtime/arguments.hpp"
diff --git a/src/hotspot/share/classfile/fieldLayoutBuilder.cpp b/src/hotspot/share/classfile/fieldLayoutBuilder.cpp
index 06907a56ba18a..0a5314d5ea3cd 100644
--- a/src/hotspot/share/classfile/fieldLayoutBuilder.cpp
+++ b/src/hotspot/share/classfile/fieldLayoutBuilder.cpp
@@ -30,6 +30,7 @@
#include "oops/array.hpp"
#include "oops/fieldStreams.inline.hpp"
#include "oops/instanceMirrorKlass.hpp"
+#include "oops/instanceKlass.inline.hpp"
#include "oops/klass.inline.hpp"
#include "runtime/fieldDescriptor.inline.hpp"
diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp
index b05215d907bd5..4e7e977712d21 100644
--- a/src/hotspot/share/classfile/javaClasses.cpp
+++ b/src/hotspot/share/classfile/javaClasses.cpp
@@ -44,9 +44,10 @@
#include "memory/resourceArea.hpp"
#include "memory/universe.hpp"
#include "oops/fieldStreams.inline.hpp"
-#include "oops/instanceKlass.hpp"
+#include "oops/instanceKlass.inline.hpp"
#include "oops/instanceMirrorKlass.hpp"
#include "oops/klass.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/method.inline.hpp"
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
diff --git a/src/hotspot/share/classfile/systemDictionaryShared.cpp b/src/hotspot/share/classfile/systemDictionaryShared.cpp
index 9c68e5f1fe7b9..063f780da51ff 100644
--- a/src/hotspot/share/classfile/systemDictionaryShared.cpp
+++ b/src/hotspot/share/classfile/systemDictionaryShared.cpp
@@ -56,6 +56,7 @@
#include "oops/klass.inline.hpp"
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
+#include "oops/oopHandle.inline.hpp"
#include "oops/typeArrayOop.inline.hpp"
#include "prims/jvmtiExport.hpp"
#include "runtime/handles.inline.hpp"
@@ -710,6 +711,13 @@ static RunTimeSharedDictionary _unregistered_dictionary;
static RunTimeSharedDictionary _dynamic_builtin_dictionary;
static RunTimeSharedDictionary _dynamic_unregistered_dictionary;
+void SystemDictionaryShared::atomic_set_array_index(OopHandle array, int index, oop o) {
+ // Benign race condition: array.obj_at(index) may already be filled in.
+ // The important thing here is that all threads pick up the same result.
+ // It doesn't matter which racing thread wins, as long as only one
+ // result is used by all threads, and all future queries.
+ ((objArrayOop)array.resolve())->atomic_compare_exchange_oop(index, o, NULL);
+}
Handle SystemDictionaryShared::create_jar_manifest(const char* manifest_chars, size_t size, TRAPS) {
typeArrayOop buf = oopFactory::new_byteArray((int)size, CHECK_NH);
diff --git a/src/hotspot/share/classfile/systemDictionaryShared.hpp b/src/hotspot/share/classfile/systemDictionaryShared.hpp
index 4da9beb834fb2..ffbe4f1596f3d 100644
--- a/src/hotspot/share/classfile/systemDictionaryShared.hpp
+++ b/src/hotspot/share/classfile/systemDictionaryShared.hpp
@@ -25,10 +25,11 @@
#ifndef SHARE_CLASSFILE_SYSTEMDICTIONARYSHARED_HPP
#define SHARE_CLASSFILE_SYSTEMDICTIONARYSHARED_HPP
-#include "oops/klass.hpp"
#include "classfile/packageEntry.hpp"
#include "classfile/systemDictionary.hpp"
#include "memory/filemap.hpp"
+#include "oops/klass.hpp"
+#include "oops/oopHandle.hpp"
/*===============================================================================
@@ -181,13 +182,7 @@ class SystemDictionaryShared: public SystemDictionary {
static Handle get_shared_protection_domain(Handle class_loader,
ModuleEntry* mod, TRAPS);
- static void atomic_set_array_index(OopHandle array, int index, oop o) {
- // Benign race condition: array.obj_at(index) may already be filled in.
- // The important thing here is that all threads pick up the same result.
- // It doesn't matter which racing thread wins, as long as only one
- // result is used by all threads, and all future queries.
- ((objArrayOop)array.resolve())->atomic_compare_exchange_oop(index, o, NULL);
- }
+ static void atomic_set_array_index(OopHandle array, int index, oop o);
static oop shared_protection_domain(int index);
static void atomic_set_shared_protection_domain(int index, oop pd) {
diff --git a/src/hotspot/share/classfile/verifier.cpp b/src/hotspot/share/classfile/verifier.cpp
index 25511485a6c48..6ea7440291adc 100644
--- a/src/hotspot/share/classfile/verifier.cpp
+++ b/src/hotspot/share/classfile/verifier.cpp
@@ -42,7 +42,8 @@
#include "memory/resourceArea.hpp"
#include "memory/universe.hpp"
#include "oops/constantPool.inline.hpp"
-#include "oops/instanceKlass.hpp"
+#include "oops/instanceKlass.inline.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/oop.inline.hpp"
#include "oops/typeArrayOop.hpp"
#include "runtime/arguments.hpp"
diff --git a/src/hotspot/share/classfile/vmSymbols.cpp b/src/hotspot/share/classfile/vmSymbols.cpp
index 4702fc95f4841..0c6c8a9897f4e 100644
--- a/src/hotspot/share/classfile/vmSymbols.cpp
+++ b/src/hotspot/share/classfile/vmSymbols.cpp
@@ -32,6 +32,7 @@
#include "memory/metaspaceClosure.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/handles.inline.hpp"
+#include "runtime/signature.hpp"
#include "utilities/tribool.hpp"
#include "utilities/xmlstream.hpp"
diff --git a/src/hotspot/share/code/vtableStubs.cpp b/src/hotspot/share/code/vtableStubs.cpp
index 9b6513a08d468..d490adb3eeff9 100644
--- a/src/hotspot/share/code/vtableStubs.cpp
+++ b/src/hotspot/share/code/vtableStubs.cpp
@@ -30,6 +30,7 @@
#include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp"
#include "oops/instanceKlass.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/klassVtable.hpp"
#include "oops/oop.inline.hpp"
#include "prims/forte.hpp"
diff --git a/src/hotspot/share/compiler/compileBroker.cpp b/src/hotspot/share/compiler/compileBroker.cpp
index 08f52c365c506..76b5b171379c0 100644
--- a/src/hotspot/share/compiler/compileBroker.cpp
+++ b/src/hotspot/share/compiler/compileBroker.cpp
@@ -24,6 +24,7 @@
#include "precompiled.hpp"
#include "jvm.h"
+#include "classfile/javaClasses.hpp"
#include "classfile/symbolTable.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
diff --git a/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp b/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp
index 59db5f680dc4a..9ff4d0887fed4 100644
--- a/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp
+++ b/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp
@@ -30,6 +30,7 @@
#include "gc/g1/g1ParScanThreadState.inline.hpp"
#include "gc/g1/g1StringDedup.hpp"
#include "gc/shared/gcTimer.hpp"
+#include "gc/shared/oopStorage.hpp"
#include "gc/shared/workerDataArray.inline.hpp"
#include "memory/resourceArea.hpp"
#include "logging/log.hpp"
diff --git a/src/hotspot/share/gc/shared/modRefBarrierSet.inline.hpp b/src/hotspot/share/gc/shared/modRefBarrierSet.inline.hpp
index fb8a380f172a6..94594b923bca8 100644
--- a/src/hotspot/share/gc/shared/modRefBarrierSet.inline.hpp
+++ b/src/hotspot/share/gc/shared/modRefBarrierSet.inline.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 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
@@ -28,10 +28,11 @@
#include "gc/shared/barrierSet.hpp"
#include "gc/shared/modRefBarrierSet.hpp"
#include "oops/compressedOops.inline.hpp"
-#include "oops/klass.inline.hpp"
#include "oops/objArrayOop.hpp"
#include "oops/oop.hpp"
+class Klass;
+
// count is number of array elements being written
void ModRefBarrierSet::write_ref_array(HeapWord* start, size_t count) {
HeapWord* end = (HeapWord*)((char*)start + (count*heapOopSize));
diff --git a/src/hotspot/share/interpreter/interpreterRuntime.cpp b/src/hotspot/share/interpreter/interpreterRuntime.cpp
index efe343bc00697..c5142cfc32e39 100644
--- a/src/hotspot/share/interpreter/interpreterRuntime.cpp
+++ b/src/hotspot/share/interpreter/interpreterRuntime.cpp
@@ -43,7 +43,8 @@
#include "memory/universe.hpp"
#include "oops/constantPool.hpp"
#include "oops/cpCache.inline.hpp"
-#include "oops/instanceKlass.hpp"
+#include "oops/instanceKlass.inline.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/methodData.hpp"
#include "oops/objArrayKlass.hpp"
#include "oops/objArrayOop.inline.hpp"
diff --git a/src/hotspot/share/interpreter/linkResolver.cpp b/src/hotspot/share/interpreter/linkResolver.cpp
index b96a326ad382b..bba22a037f776 100644
--- a/src/hotspot/share/interpreter/linkResolver.cpp
+++ b/src/hotspot/share/interpreter/linkResolver.cpp
@@ -43,7 +43,8 @@
#include "memory/resourceArea.hpp"
#include "oops/constantPool.hpp"
#include "oops/cpCache.inline.hpp"
-#include "oops/instanceKlass.hpp"
+#include "oops/instanceKlass.inline.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/method.hpp"
#include "oops/objArrayKlass.hpp"
#include "oops/objArrayOop.hpp"
diff --git a/src/hotspot/share/interpreter/zero/bytecodeInterpreter.cpp b/src/hotspot/share/interpreter/zero/bytecodeInterpreter.cpp
index fe46f0a2cc921..3f8f5299ad002 100644
--- a/src/hotspot/share/interpreter/zero/bytecodeInterpreter.cpp
+++ b/src/hotspot/share/interpreter/zero/bytecodeInterpreter.cpp
@@ -23,6 +23,7 @@
*/
// no precompiled headers
+#include "classfile/javaClasses.hpp"
#include "classfile/vmSymbols.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "gc/shared/threadLocalAllocBuffer.inline.hpp"
@@ -35,6 +36,8 @@
#include "memory/universe.hpp"
#include "oops/constantPool.inline.hpp"
#include "oops/cpCache.inline.hpp"
+#include "oops/instanceKlass.inline.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/method.inline.hpp"
#include "oops/methodCounters.hpp"
#include "oops/objArrayKlass.hpp"
diff --git a/src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.cpp b/src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.cpp
index 56e44608bcdc4..72963943a12cb 100644
--- a/src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.cpp
+++ b/src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.cpp
@@ -47,6 +47,7 @@
#include "memory/resourceArea.hpp"
#include "oops/array.hpp"
#include "oops/instanceKlass.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/method.hpp"
#include "prims/jvmtiRedefineClasses.hpp"
#include "runtime/handles.inline.hpp"
diff --git a/src/hotspot/share/jfr/jni/jfrJavaSupport.cpp b/src/hotspot/share/jfr/jni/jfrJavaSupport.cpp
index c7c38378b1fe2..7c03bbe5214ee 100644
--- a/src/hotspot/share/jfr/jni/jfrJavaSupport.cpp
+++ b/src/hotspot/share/jfr/jni/jfrJavaSupport.cpp
@@ -34,6 +34,7 @@
#include "logging/log.hpp"
#include "memory/resourceArea.hpp"
#include "oops/instanceOop.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/oop.inline.hpp"
#include "oops/objArrayKlass.hpp"
#include "oops/objArrayOop.inline.hpp"
diff --git a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp
index 1792602489c1a..6193c2109c9cf 100644
--- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp
+++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp
@@ -40,7 +40,7 @@
#include "jfr/writers/jfrTypeWriterHost.hpp"
#include "memory/iterator.hpp"
#include "memory/resourceArea.hpp"
-#include "oops/instanceKlass.hpp"
+#include "oops/instanceKlass.inline.hpp"
#include "oops/objArrayKlass.hpp"
#include "oops/oop.inline.hpp"
#include "utilities/accessFlags.hpp"
diff --git a/src/hotspot/share/jfr/support/jfrJdkJfrEvent.cpp b/src/hotspot/share/jfr/support/jfrJdkJfrEvent.cpp
index efc55c08bad8c..dfcbda88fc8b4 100644
--- a/src/hotspot/share/jfr/support/jfrJdkJfrEvent.cpp
+++ b/src/hotspot/share/jfr/support/jfrJdkJfrEvent.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -31,6 +31,7 @@
#include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp"
#include "oops/instanceKlass.hpp"
+#include "oops/klass.inline.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/thread.inline.hpp"
#include "utilities/stack.inline.hpp"
diff --git a/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp b/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp
index 058fa06872a68..e5025b9b37edf 100644
--- a/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp
+++ b/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp
@@ -30,6 +30,7 @@
#include "jvmci/jvmciRuntime.hpp"
#include "memory/universe.hpp"
#include "oops/compressedOops.inline.hpp"
+#include "oops/klass.inline.hpp"
#include "prims/jvmtiExport.hpp"
#include "prims/methodHandles.hpp"
#include "runtime/interfaceSupport.inline.hpp"
diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp
index be021285601fb..4e6cf58f0d3bf 100644
--- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp
+++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp
@@ -41,6 +41,7 @@
#include "memory/oopFactory.hpp"
#include "memory/universe.hpp"
#include "oops/constantPool.inline.hpp"
+#include "oops/instanceKlass.inline.hpp"
#include "oops/method.inline.hpp"
#include "oops/typeArrayOop.inline.hpp"
#include "prims/jvmtiExport.hpp"
diff --git a/src/hotspot/share/jvmci/jvmciJavaClasses.cpp b/src/hotspot/share/jvmci/jvmciJavaClasses.cpp
index 66782af564dd4..0e75127da3b68 100644
--- a/src/hotspot/share/jvmci/jvmciJavaClasses.cpp
+++ b/src/hotspot/share/jvmci/jvmciJavaClasses.cpp
@@ -28,6 +28,7 @@
#include "jvmci/jvmciJavaClasses.hpp"
#include "jvmci/jvmciRuntime.hpp"
#include "memory/resourceArea.hpp"
+#include "oops/instanceKlass.inline.hpp"
#include "runtime/fieldDescriptor.inline.hpp"
#include "runtime/jniHandles.inline.hpp"
#include "runtime/java.hpp"
diff --git a/src/hotspot/share/jvmci/jvmciRuntime.cpp b/src/hotspot/share/jvmci/jvmciRuntime.cpp
index 58081a3c284fd..c7ed875f85444 100644
--- a/src/hotspot/share/jvmci/jvmciRuntime.cpp
+++ b/src/hotspot/share/jvmci/jvmciRuntime.cpp
@@ -34,6 +34,7 @@
#include "memory/oopFactory.hpp"
#include "memory/universe.hpp"
#include "oops/constantPool.inline.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/method.inline.hpp"
#include "oops/objArrayKlass.hpp"
#include "oops/oop.inline.hpp"
diff --git a/src/hotspot/share/memory/dynamicArchive.cpp b/src/hotspot/share/memory/dynamicArchive.cpp
index 5cb889f60cf21..fcaf1c38e57cb 100644
--- a/src/hotspot/share/memory/dynamicArchive.cpp
+++ b/src/hotspot/share/memory/dynamicArchive.cpp
@@ -34,6 +34,7 @@
#include "memory/metaspaceClosure.hpp"
#include "memory/metaspaceShared.hpp"
#include "memory/resourceArea.hpp"
+#include "oops/klass.inline.hpp"
#include "runtime/os.inline.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/vmThread.hpp"
diff --git a/src/hotspot/share/memory/metaspaceShared.cpp b/src/hotspot/share/memory/metaspaceShared.cpp
index 410b25a51b43b..c5dca41b9c814 100644
--- a/src/hotspot/share/memory/metaspaceShared.cpp
+++ b/src/hotspot/share/memory/metaspaceShared.cpp
@@ -56,6 +56,7 @@
#include "memory/universe.hpp"
#include "oops/compressedOops.inline.hpp"
#include "oops/instanceMirrorKlass.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/objArrayOop.hpp"
#include "oops/oop.inline.hpp"
#include "oops/oopHandle.hpp"
diff --git a/src/hotspot/share/memory/universe.cpp b/src/hotspot/share/memory/universe.cpp
index 637fd23387153..855b1cf9931f5 100644
--- a/src/hotspot/share/memory/universe.cpp
+++ b/src/hotspot/share/memory/universe.cpp
@@ -52,6 +52,7 @@
#include "oops/compressedOops.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/instanceMirrorKlass.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
#include "oops/oopHandle.inline.hpp"
diff --git a/src/hotspot/share/oops/arrayKlass.cpp b/src/hotspot/share/oops/arrayKlass.cpp
index 1fdcd17519893..c86f5c097d23f 100644
--- a/src/hotspot/share/oops/arrayKlass.cpp
+++ b/src/hotspot/share/oops/arrayKlass.cpp
@@ -35,6 +35,7 @@
#include "oops/arrayKlass.hpp"
#include "oops/arrayOop.hpp"
#include "oops/instanceKlass.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/objArrayOop.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/handles.inline.hpp"
diff --git a/src/hotspot/share/oops/constantPool.cpp b/src/hotspot/share/oops/constantPool.cpp
index 1761efa7ac075..8ae78664ab372 100644
--- a/src/hotspot/share/oops/constantPool.cpp
+++ b/src/hotspot/share/oops/constantPool.cpp
@@ -46,6 +46,7 @@
#include "oops/constantPool.inline.hpp"
#include "oops/cpCache.inline.hpp"
#include "oops/instanceKlass.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/objArrayKlass.hpp"
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
diff --git a/src/hotspot/share/oops/instanceKlass.hpp b/src/hotspot/share/oops/instanceKlass.hpp
index 8b37a0781d58b..5e1da7c4f95f5 100644
--- a/src/hotspot/share/oops/instanceKlass.hpp
+++ b/src/hotspot/share/oops/instanceKlass.hpp
@@ -688,25 +688,8 @@ class InstanceKlass: public Klass {
objArrayOop signers() const;
// host class
- InstanceKlass* unsafe_anonymous_host() const {
- InstanceKlass** hk = adr_unsafe_anonymous_host();
- if (hk == NULL) {
- assert(!is_unsafe_anonymous(), "Unsafe anonymous classes have host klasses");
- return NULL;
- } else {
- assert(*hk != NULL, "host klass should always be set if the address is not null");
- assert(is_unsafe_anonymous(), "Only unsafe anonymous classes have host klasses");
- return *hk;
- }
- }
- void set_unsafe_anonymous_host(const InstanceKlass* host) {
- assert(is_unsafe_anonymous(), "not unsafe anonymous");
- const InstanceKlass** addr = (const InstanceKlass **)adr_unsafe_anonymous_host();
- assert(addr != NULL, "no reversed space");
- if (addr != NULL) {
- *addr = host;
- }
- }
+ inline InstanceKlass* unsafe_anonymous_host() const;
+ inline void set_unsafe_anonymous_host(const InstanceKlass* host);
bool is_unsafe_anonymous() const {
return (_misc_flags & _misc_is_unsafe_anonymous) != 0;
}
@@ -1097,60 +1080,17 @@ class InstanceKlass: public Klass {
has_stored_fingerprint());
}
- intptr_t* start_of_itable() const { return (intptr_t*)start_of_vtable() + vtable_length(); }
- intptr_t* end_of_itable() const { return start_of_itable() + itable_length(); }
-
- int itable_offset_in_words() const { return start_of_itable() - (intptr_t*)this; }
-
- oop static_field_base_raw() { return java_mirror(); }
-
- OopMapBlock* start_of_nonstatic_oop_maps() const {
- return (OopMapBlock*)(start_of_itable() + itable_length());
- }
-
- Klass** end_of_nonstatic_oop_maps() const {
- return (Klass**)(start_of_nonstatic_oop_maps() +
- nonstatic_oop_map_count());
- }
-
- Klass* volatile* adr_implementor() const {
- if (is_interface()) {
- return (Klass* volatile*)end_of_nonstatic_oop_maps();
- } else {
- return NULL;
- }
- };
-
- InstanceKlass** adr_unsafe_anonymous_host() const {
- if (is_unsafe_anonymous()) {
- InstanceKlass** adr_impl = (InstanceKlass**)adr_implementor();
- if (adr_impl != NULL) {
- return adr_impl + 1;
- } else {
- return (InstanceKlass **)end_of_nonstatic_oop_maps();
- }
- } else {
- return NULL;
- }
- }
-
- address adr_fingerprint() const {
- if (has_stored_fingerprint()) {
- InstanceKlass** adr_host = adr_unsafe_anonymous_host();
- if (adr_host != NULL) {
- return (address)(adr_host + 1);
- }
+ inline intptr_t* start_of_itable() const;
+ inline intptr_t* end_of_itable() const;
+ inline int itable_offset_in_words() const;
+ inline oop static_field_base_raw();
- Klass* volatile* adr_impl = adr_implementor();
- if (adr_impl != NULL) {
- return (address)(adr_impl + 1);
- }
+ inline OopMapBlock* start_of_nonstatic_oop_maps() const;
+ inline Klass** end_of_nonstatic_oop_maps() const;
- return (address)end_of_nonstatic_oop_maps();
- } else {
- return NULL;
- }
- }
+ inline Klass* volatile* adr_implementor() const;
+ inline InstanceKlass** adr_unsafe_anonymous_host() const;
+ inline address adr_fingerprint() const;
// Use this to return the size of an instance in heap words:
int size_helper() const {
diff --git a/src/hotspot/share/oops/instanceKlass.inline.hpp b/src/hotspot/share/oops/instanceKlass.inline.hpp
index a8bdf3c20ce5d..a1e40852a8e3e 100644
--- a/src/hotspot/share/oops/instanceKlass.inline.hpp
+++ b/src/hotspot/share/oops/instanceKlass.inline.hpp
@@ -25,17 +25,94 @@
#ifndef SHARE_OOPS_INSTANCEKLASS_INLINE_HPP
#define SHARE_OOPS_INSTANCEKLASS_INLINE_HPP
+#include "classfile/javaClasses.hpp"
#include "classfile/vmSymbols.hpp"
#include "memory/iterator.hpp"
#include "memory/resourceArea.hpp"
#include "oops/instanceKlass.hpp"
-#include "oops/klass.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/atomic.hpp"
#include "utilities/debug.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/macros.hpp"
+inline InstanceKlass* InstanceKlass::unsafe_anonymous_host() const {
+ InstanceKlass** hk = adr_unsafe_anonymous_host();
+ if (hk == NULL) {
+ assert(!is_unsafe_anonymous(), "Unsafe anonymous classes have host klasses");
+ return NULL;
+ } else {
+ assert(*hk != NULL, "host klass should always be set if the address is not null");
+ assert(is_unsafe_anonymous(), "Only unsafe anonymous classes have host klasses");
+ return *hk;
+ }
+}
+
+inline void InstanceKlass::set_unsafe_anonymous_host(const InstanceKlass* host) {
+ assert(is_unsafe_anonymous(), "not unsafe anonymous");
+ const InstanceKlass** addr = (const InstanceKlass **)adr_unsafe_anonymous_host();
+ assert(addr != NULL, "no reversed space");
+ if (addr != NULL) {
+ *addr = host;
+ }
+}
+
+inline intptr_t* InstanceKlass::start_of_itable() const { return (intptr_t*)start_of_vtable() + vtable_length(); }
+inline intptr_t* InstanceKlass::end_of_itable() const { return start_of_itable() + itable_length(); }
+
+inline int InstanceKlass::itable_offset_in_words() const { return start_of_itable() - (intptr_t*)this; }
+
+inline oop InstanceKlass::static_field_base_raw() { return java_mirror(); }
+
+inline OopMapBlock* InstanceKlass::start_of_nonstatic_oop_maps() const {
+ return (OopMapBlock*)(start_of_itable() + itable_length());
+}
+
+inline Klass** InstanceKlass::end_of_nonstatic_oop_maps() const {
+ return (Klass**)(start_of_nonstatic_oop_maps() +
+ nonstatic_oop_map_count());
+}
+
+inline Klass* volatile* InstanceKlass::adr_implementor() const {
+ if (is_interface()) {
+ return (Klass* volatile*)end_of_nonstatic_oop_maps();
+ } else {
+ return NULL;
+ }
+}
+
+inline InstanceKlass** InstanceKlass::adr_unsafe_anonymous_host() const {
+ if (is_unsafe_anonymous()) {
+ InstanceKlass** adr_impl = (InstanceKlass**)adr_implementor();
+ if (adr_impl != NULL) {
+ return adr_impl + 1;
+ } else {
+ return (InstanceKlass **)end_of_nonstatic_oop_maps();
+ }
+ } else {
+ return NULL;
+ }
+}
+
+inline address InstanceKlass::adr_fingerprint() const {
+ if (has_stored_fingerprint()) {
+ InstanceKlass** adr_host = adr_unsafe_anonymous_host();
+ if (adr_host != NULL) {
+ return (address)(adr_host + 1);
+ }
+
+ Klass* volatile* adr_impl = adr_implementor();
+ if (adr_impl != NULL) {
+ return (address)(adr_impl + 1);
+ }
+
+ return (address)end_of_nonstatic_oop_maps();
+ } else {
+ return NULL;
+ }
+}
+
inline ObjArrayKlass* InstanceKlass::array_klasses_acquire() const {
return Atomic::load_acquire(&_array_klasses);
}
diff --git a/src/hotspot/share/oops/klassVtable.cpp b/src/hotspot/share/oops/klassVtable.cpp
index 84e4592b6b9e4..4ead0c71ae90f 100644
--- a/src/hotspot/share/oops/klassVtable.cpp
+++ b/src/hotspot/share/oops/klassVtable.cpp
@@ -34,7 +34,8 @@
#include "memory/metaspaceShared.hpp"
#include "memory/resourceArea.hpp"
#include "memory/universe.hpp"
-#include "oops/instanceKlass.hpp"
+#include "oops/instanceKlass.inline.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/klassVtable.hpp"
#include "oops/method.hpp"
#include "oops/objArrayOop.hpp"
diff --git a/src/hotspot/share/oops/method.cpp b/src/hotspot/share/oops/method.cpp
index 4c9d025fdf04d..75983a402a5c0 100644
--- a/src/hotspot/share/oops/method.cpp
+++ b/src/hotspot/share/oops/method.cpp
@@ -49,6 +49,7 @@
#include "memory/universe.hpp"
#include "oops/constMethod.hpp"
#include "oops/constantPool.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/method.inline.hpp"
#include "oops/methodData.hpp"
#include "oops/objArrayKlass.hpp"
diff --git a/src/hotspot/share/oops/oop.inline.hpp b/src/hotspot/share/oops/oop.inline.hpp
index 7cccf0db0b2c9..da8421f34406f 100644
--- a/src/hotspot/share/oops/oop.inline.hpp
+++ b/src/hotspot/share/oops/oop.inline.hpp
@@ -31,7 +31,6 @@
#include "oops/arrayKlass.hpp"
#include "oops/arrayOop.hpp"
#include "oops/compressedOops.inline.hpp"
-#include "oops/klass.inline.hpp"
#include "oops/markWord.inline.hpp"
#include "oops/oop.hpp"
#include "runtime/atomic.hpp"
diff --git a/src/hotspot/share/prims/jni.cpp b/src/hotspot/share/prims/jni.cpp
index e251b48f2e139..c400456f2efd5 100644
--- a/src/hotspot/share/prims/jni.cpp
+++ b/src/hotspot/share/prims/jni.cpp
@@ -52,6 +52,7 @@
#include "oops/arrayOop.inline.hpp"
#include "oops/instanceKlass.inline.hpp"
#include "oops/instanceOop.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/markWord.hpp"
#include "oops/method.hpp"
#include "oops/objArrayKlass.hpp"
diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp
index 5c237dd6f243e..909961a17c92b 100644
--- a/src/hotspot/share/prims/jvm.cpp
+++ b/src/hotspot/share/prims/jvm.cpp
@@ -55,6 +55,7 @@
#include "oops/constantPool.hpp"
#include "oops/fieldStreams.inline.hpp"
#include "oops/instanceKlass.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/method.hpp"
#include "oops/recordComponent.hpp"
#include "oops/objArrayKlass.hpp"
diff --git a/src/hotspot/share/prims/jvmtiEnv.cpp b/src/hotspot/share/prims/jvmtiEnv.cpp
index 85dfd4066223f..4559f9d279d1f 100644
--- a/src/hotspot/share/prims/jvmtiEnv.cpp
+++ b/src/hotspot/share/prims/jvmtiEnv.cpp
@@ -38,6 +38,7 @@
#include "memory/resourceArea.hpp"
#include "memory/universe.hpp"
#include "oops/instanceKlass.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
#include "prims/jniCheck.hpp"
diff --git a/src/hotspot/share/prims/jvmtiEnvBase.cpp b/src/hotspot/share/prims/jvmtiEnvBase.cpp
index 55ac65b614fa7..51a540c0277ed 100644
--- a/src/hotspot/share/prims/jvmtiEnvBase.cpp
+++ b/src/hotspot/share/prims/jvmtiEnvBase.cpp
@@ -24,11 +24,13 @@
#include "precompiled.hpp"
#include "classfile/classLoaderDataGraph.hpp"
+#include "classfile/javaClasses.hpp"
#include "classfile/moduleEntry.hpp"
#include "classfile/systemDictionary.hpp"
#include "jvmtifiles/jvmtiEnv.hpp"
#include "memory/iterator.hpp"
#include "memory/resourceArea.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/objArrayKlass.hpp"
#include "oops/objArrayOop.hpp"
#include "oops/oop.inline.hpp"
diff --git a/src/hotspot/share/prims/jvmtiExport.cpp b/src/hotspot/share/prims/jvmtiExport.cpp
index 3fdf6d9ee8a23..c25781da310b5 100644
--- a/src/hotspot/share/prims/jvmtiExport.cpp
+++ b/src/hotspot/share/prims/jvmtiExport.cpp
@@ -37,6 +37,7 @@
#include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp"
#include "memory/universe.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/objArrayKlass.hpp"
#include "oops/objArrayOop.hpp"
#include "oops/oop.inline.hpp"
diff --git a/src/hotspot/share/prims/jvmtiGetLoadedClasses.cpp b/src/hotspot/share/prims/jvmtiGetLoadedClasses.cpp
index 4918d90212fde..e05877a6d9f2e 100644
--- a/src/hotspot/share/prims/jvmtiGetLoadedClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiGetLoadedClasses.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -25,9 +25,11 @@
#include "precompiled.hpp"
#include "classfile/classLoaderDataGraph.hpp"
#include "classfile/dictionary.hpp"
+#include "classfile/javaClasses.hpp"
#include "classfile/systemDictionary.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "memory/universe.hpp"
+#include "oops/klass.inline.hpp"
#include "prims/jvmtiGetLoadedClasses.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/jniHandles.inline.hpp"
diff --git a/src/hotspot/share/prims/jvmtiImpl.cpp b/src/hotspot/share/prims/jvmtiImpl.cpp
index 1617db70a8d62..d7b31721f3f07 100644
--- a/src/hotspot/share/prims/jvmtiImpl.cpp
+++ b/src/hotspot/share/prims/jvmtiImpl.cpp
@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
+#include "classfile/javaClasses.hpp"
#include "classfile/symbolTable.hpp"
#include "classfile/systemDictionary.hpp"
#include "code/nmethod.hpp"
@@ -35,6 +36,7 @@
#include "memory/resourceArea.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/oop.inline.hpp"
+#include "oops/oopHandle.inline.hpp"
#include "prims/jvmtiAgentThread.hpp"
#include "prims/jvmtiEventController.inline.hpp"
#include "prims/jvmtiImpl.hpp"
diff --git a/src/hotspot/share/prims/jvmtiRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiRedefineClasses.cpp
index 277af0e98f17d..ed77f7db2e75a 100644
--- a/src/hotspot/share/prims/jvmtiRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiRedefineClasses.cpp
@@ -45,6 +45,7 @@
#include "oops/annotations.hpp"
#include "oops/constantPool.hpp"
#include "oops/fieldStreams.inline.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/klassVtable.hpp"
#include "oops/oop.inline.hpp"
#include "oops/recordComponent.hpp"
diff --git a/src/hotspot/share/prims/jvmtiTagMap.cpp b/src/hotspot/share/prims/jvmtiTagMap.cpp
index a20ad93fbb73f..07da8e3159686 100644
--- a/src/hotspot/share/prims/jvmtiTagMap.cpp
+++ b/src/hotspot/share/prims/jvmtiTagMap.cpp
@@ -37,6 +37,7 @@
#include "oops/arrayOop.inline.hpp"
#include "oops/constantPool.inline.hpp"
#include "oops/instanceMirrorKlass.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/objArrayKlass.hpp"
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
diff --git a/src/hotspot/share/prims/methodHandles.cpp b/src/hotspot/share/prims/methodHandles.cpp
index addee7e7168a5..5a8bdd9ba0cb1 100644
--- a/src/hotspot/share/prims/methodHandles.cpp
+++ b/src/hotspot/share/prims/methodHandles.cpp
@@ -38,6 +38,7 @@
#include "memory/oopFactory.hpp"
#include "memory/resourceArea.hpp"
#include "memory/universe.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/objArrayKlass.hpp"
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
diff --git a/src/hotspot/share/prims/nativeLookup.cpp b/src/hotspot/share/prims/nativeLookup.cpp
index 0c863eddde406..9641d9242d139 100644
--- a/src/hotspot/share/prims/nativeLookup.cpp
+++ b/src/hotspot/share/prims/nativeLookup.cpp
@@ -32,6 +32,7 @@
#include "memory/oopFactory.hpp"
#include "memory/resourceArea.hpp"
#include "oops/instanceKlass.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/method.hpp"
#include "oops/oop.inline.hpp"
#include "oops/symbol.hpp"
diff --git a/src/hotspot/share/prims/stackwalk.cpp b/src/hotspot/share/prims/stackwalk.cpp
index 07ede2efaa346..45a1af82a9a35 100644
--- a/src/hotspot/share/prims/stackwalk.cpp
+++ b/src/hotspot/share/prims/stackwalk.cpp
@@ -30,6 +30,7 @@
#include "logging/logStream.hpp"
#include "memory/oopFactory.hpp"
#include "memory/universe.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/oop.inline.hpp"
#include "oops/objArrayOop.inline.hpp"
#include "prims/stackwalk.hpp"
diff --git a/src/hotspot/share/prims/universalUpcallHandler.cpp b/src/hotspot/share/prims/universalUpcallHandler.cpp
index 9eff9f53c3fc0..66cd4dbfb2909 100644
--- a/src/hotspot/share/prims/universalUpcallHandler.cpp
+++ b/src/hotspot/share/prims/universalUpcallHandler.cpp
@@ -23,6 +23,7 @@
#include "precompiled.hpp"
#include "classfile/symbolTable.hpp"
+#include "classfile/systemDictionary.hpp"
#include "memory/resourceArea.hpp"
#include "prims/universalUpcallHandler.hpp"
#include "runtime/interfaceSupport.inline.hpp"
diff --git a/src/hotspot/share/prims/unsafe.cpp b/src/hotspot/share/prims/unsafe.cpp
index fc8ea88313061..0df435b0fd651 100644
--- a/src/hotspot/share/prims/unsafe.cpp
+++ b/src/hotspot/share/prims/unsafe.cpp
@@ -36,6 +36,7 @@
#include "oops/access.inline.hpp"
#include "oops/fieldStreams.inline.hpp"
#include "oops/instanceKlass.inline.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
#include "oops/typeArrayOop.inline.hpp"
diff --git a/src/hotspot/share/prims/vectorSupport.cpp b/src/hotspot/share/prims/vectorSupport.cpp
index f6d1306ce89fc..be3bb27177e77 100644
--- a/src/hotspot/share/prims/vectorSupport.cpp
+++ b/src/hotspot/share/prims/vectorSupport.cpp
@@ -28,6 +28,7 @@
#include "classfile/javaClasses.inline.hpp"
#include "classfile/vmSymbols.hpp"
#include "code/location.hpp"
+#include "oops/klass.inline.hpp"
#include "prims/vectorSupport.hpp"
#include "runtime/fieldDescriptor.inline.hpp"
#include "runtime/handles.inline.hpp"
diff --git a/src/hotspot/share/prims/whitebox.cpp b/src/hotspot/share/prims/whitebox.cpp
index 28a5162abd0ac..9640c9e04a7f5 100644
--- a/src/hotspot/share/prims/whitebox.cpp
+++ b/src/hotspot/share/prims/whitebox.cpp
@@ -54,6 +54,7 @@
#include "oops/array.hpp"
#include "oops/compressedOops.hpp"
#include "oops/constantPool.inline.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/method.inline.hpp"
#include "oops/objArrayKlass.hpp"
#include "oops/objArrayOop.inline.hpp"
diff --git a/src/hotspot/share/runtime/fieldDescriptor.cpp b/src/hotspot/share/runtime/fieldDescriptor.cpp
index e3be65c6ccae2..d1a913a28dfd9 100644
--- a/src/hotspot/share/runtime/fieldDescriptor.cpp
+++ b/src/hotspot/share/runtime/fieldDescriptor.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -29,6 +29,7 @@
#include "oops/annotations.hpp"
#include "oops/constantPool.hpp"
#include "oops/instanceKlass.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/oop.inline.hpp"
#include "oops/fieldStreams.inline.hpp"
#include "runtime/fieldDescriptor.inline.hpp"
diff --git a/src/hotspot/share/runtime/java.cpp b/src/hotspot/share/runtime/java.cpp
index c7726fd538809..d82cfe59c99d3 100644
--- a/src/hotspot/share/runtime/java.cpp
+++ b/src/hotspot/share/runtime/java.cpp
@@ -27,6 +27,7 @@
#include "aot/aotLoader.hpp"
#include "classfile/classLoader.hpp"
#include "classfile/classLoaderDataGraph.hpp"
+#include "classfile/javaClasses.hpp"
#include "classfile/stringTable.hpp"
#include "classfile/symbolTable.hpp"
#include "classfile/systemDictionary.hpp"
diff --git a/src/hotspot/share/runtime/objectMonitor.cpp b/src/hotspot/share/runtime/objectMonitor.cpp
index 15870dc9a2aab..242eb2feb9923 100644
--- a/src/hotspot/share/runtime/objectMonitor.cpp
+++ b/src/hotspot/share/runtime/objectMonitor.cpp
@@ -34,6 +34,8 @@
#include "memory/resourceArea.hpp"
#include "oops/markWord.hpp"
#include "oops/oop.inline.hpp"
+#include "oops/oopHandle.inline.hpp"
+#include "oops/weakHandle.inline.hpp"
#include "prims/jvmtiDeferredUpdates.hpp"
#include "prims/jvmtiExport.hpp"
#include "runtime/atomic.hpp"
diff --git a/src/hotspot/share/runtime/reflection.cpp b/src/hotspot/share/runtime/reflection.cpp
index 50bb12861fe06..fd5451089c743 100644
--- a/src/hotspot/share/runtime/reflection.cpp
+++ b/src/hotspot/share/runtime/reflection.cpp
@@ -36,7 +36,8 @@
#include "memory/oopFactory.hpp"
#include "memory/resourceArea.hpp"
#include "memory/universe.hpp"
-#include "oops/instanceKlass.hpp"
+#include "oops/instanceKlass.inline.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/objArrayKlass.hpp"
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
diff --git a/src/hotspot/share/runtime/sharedRuntime.cpp b/src/hotspot/share/runtime/sharedRuntime.cpp
index ef2b688c7f129..80a84ccbf9aac 100644
--- a/src/hotspot/share/runtime/sharedRuntime.cpp
+++ b/src/hotspot/share/runtime/sharedRuntime.cpp
@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
+#include "classfile/javaClasses.hpp"
#include "jvm.h"
#include "aot/aotLoader.hpp"
#include "classfile/stringTable.hpp"
diff --git a/src/hotspot/share/runtime/signature.cpp b/src/hotspot/share/runtime/signature.cpp
index 44c1480339fc9..3fd5811e551a0 100644
--- a/src/hotspot/share/runtime/signature.cpp
+++ b/src/hotspot/share/runtime/signature.cpp
@@ -30,6 +30,7 @@
#include "memory/resourceArea.hpp"
#include "memory/universe.hpp"
#include "oops/instanceKlass.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/oop.inline.hpp"
#include "oops/symbol.hpp"
#include "oops/typeArrayKlass.hpp"
diff --git a/src/hotspot/share/runtime/statSampler.cpp b/src/hotspot/share/runtime/statSampler.cpp
index 471e9577a0f00..ed0060a09652c 100644
--- a/src/hotspot/share/runtime/statSampler.cpp
+++ b/src/hotspot/share/runtime/statSampler.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
+#include "classfile/javaClasses.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
#include "memory/allocation.inline.hpp"
diff --git a/src/hotspot/share/runtime/thread.cpp b/src/hotspot/share/runtime/thread.cpp
index e75160c145703..fa0f0841a9eae 100644
--- a/src/hotspot/share/runtime/thread.cpp
+++ b/src/hotspot/share/runtime/thread.cpp
@@ -57,8 +57,10 @@
#include "memory/universe.hpp"
#include "oops/access.inline.hpp"
#include "oops/instanceKlass.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/objArrayOop.hpp"
#include "oops/oop.inline.hpp"
+#include "oops/oopHandle.inline.hpp"
#include "oops/symbol.hpp"
#include "oops/typeArrayOop.inline.hpp"
#include "oops/verifyOopClosure.hpp"
diff --git a/src/hotspot/share/services/diagnosticCommand.cpp b/src/hotspot/share/services/diagnosticCommand.cpp
index 451c94d045841..45984a3d8fad7 100644
--- a/src/hotspot/share/services/diagnosticCommand.cpp
+++ b/src/hotspot/share/services/diagnosticCommand.cpp
@@ -26,6 +26,7 @@
#include "jvm.h"
#include "classfile/classLoaderHierarchyDCmd.hpp"
#include "classfile/classLoaderStats.hpp"
+#include "classfile/javaClasses.hpp"
#include "code/codeCache.hpp"
#include "compiler/compileBroker.hpp"
#include "compiler/directivesParser.hpp"
diff --git a/src/hotspot/share/services/gcNotifier.cpp b/src/hotspot/share/services/gcNotifier.cpp
index b9a1e9b5852fe..dd50fc8b0711e 100644
--- a/src/hotspot/share/services/gcNotifier.cpp
+++ b/src/hotspot/share/services/gcNotifier.cpp
@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
+#include "classfile/javaClasses.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
#include "oops/objArrayOop.inline.hpp"
diff --git a/src/hotspot/share/services/heapDumper.cpp b/src/hotspot/share/services/heapDumper.cpp
index b1489e8499069..7059f3ab17a7f 100644
--- a/src/hotspot/share/services/heapDumper.cpp
+++ b/src/hotspot/share/services/heapDumper.cpp
@@ -37,6 +37,7 @@
#include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp"
#include "memory/universe.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/objArrayKlass.hpp"
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
diff --git a/src/hotspot/share/services/management.cpp b/src/hotspot/share/services/management.cpp
index 7b22e7b4e50d3..e5fed2c7c2448 100644
--- a/src/hotspot/share/services/management.cpp
+++ b/src/hotspot/share/services/management.cpp
@@ -33,9 +33,11 @@
#include "memory/resourceArea.hpp"
#include "memory/universe.hpp"
#include "oops/klass.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/objArrayKlass.hpp"
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
+#include "oops/oopHandle.inline.hpp"
#include "oops/typeArrayOop.inline.hpp"
#include "runtime/arguments.hpp"
#include "runtime/flags/jvmFlag.hpp"
diff --git a/src/hotspot/share/services/memoryManager.cpp b/src/hotspot/share/services/memoryManager.cpp
index 2ed0be7e0b89a..36d298dac9edb 100644
--- a/src/hotspot/share/services/memoryManager.cpp
+++ b/src/hotspot/share/services/memoryManager.cpp
@@ -23,11 +23,13 @@
*/
#include "precompiled.hpp"
+#include "classfile/javaClasses.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/universe.hpp"
#include "oops/oop.inline.hpp"
+#include "oops/oopHandle.inline.hpp"
#include "runtime/atomic.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/javaCalls.hpp"
diff --git a/src/hotspot/share/services/memoryPool.cpp b/src/hotspot/share/services/memoryPool.cpp
index e2159a1258383..f7ed91ba19f9f 100644
--- a/src/hotspot/share/services/memoryPool.cpp
+++ b/src/hotspot/share/services/memoryPool.cpp
@@ -23,11 +23,13 @@
*/
#include "precompiled.hpp"
+#include "classfile/javaClasses.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
#include "memory/metaspace.hpp"
#include "memory/universe.hpp"
#include "oops/oop.inline.hpp"
+#include "oops/oopHandle.inline.hpp"
#include "runtime/atomic.hpp"
#include "runtime/globals_extension.hpp"
#include "runtime/handles.inline.hpp"
diff --git a/src/hotspot/share/services/threadService.cpp b/src/hotspot/share/services/threadService.cpp
index 8f1ef6f05554b..b447a85d7c119 100644
--- a/src/hotspot/share/services/threadService.cpp
+++ b/src/hotspot/share/services/threadService.cpp
@@ -34,6 +34,7 @@
#include "oops/objArrayKlass.hpp"
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
+#include "oops/oopHandle.inline.hpp"
#include "prims/jvmtiRawMonitor.hpp"
#include "runtime/atomic.hpp"
#include "runtime/handles.inline.hpp"
diff --git a/src/hotspot/share/utilities/debug.cpp b/src/hotspot/share/utilities/debug.cpp
index b9ff0d6a4f8eb..9b970be5e6db3 100644
--- a/src/hotspot/share/utilities/debug.cpp
+++ b/src/hotspot/share/utilities/debug.cpp
@@ -37,6 +37,7 @@
#include "memory/allocation.hpp"
#include "memory/resourceArea.hpp"
#include "memory/universe.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/arguments.hpp"
#include "runtime/atomic.hpp"
diff --git a/src/hotspot/share/utilities/exceptions.cpp b/src/hotspot/share/utilities/exceptions.cpp
index 0fd035a7619ac..590540bab3d9e 100644
--- a/src/hotspot/share/utilities/exceptions.cpp
+++ b/src/hotspot/share/utilities/exceptions.cpp
@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
+#include "classfile/javaClasses.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
#include "compiler/compileBroker.hpp"
From 39325272882e863df8d20e192321d0a2318cf03d Mon Sep 17 00:00:00 2001
From: Kim Barrett
Date: Thu, 3 Dec 2020 04:26:23 +0000
Subject: [PATCH 034/504] 8257466: Improve enum iteration
Improve support for iteration on enums that are just range of values, without named enumerators.
Reviewed-by: iklam, lfoltan
---
src/hotspot/share/utilities/enumIterator.hpp | 89 ++++++++++----
.../gtest/utilities/test_enumIterator.cpp | 112 ++++++++++++++++++
2 files changed, 179 insertions(+), 22 deletions(-)
create mode 100644 test/hotspot/gtest/utilities/test_enumIterator.cpp
diff --git a/src/hotspot/share/utilities/enumIterator.hpp b/src/hotspot/share/utilities/enumIterator.hpp
index 45a1a0fe08285..aadae51b803f5 100644
--- a/src/hotspot/share/utilities/enumIterator.hpp
+++ b/src/hotspot/share/utilities/enumIterator.hpp
@@ -28,6 +28,7 @@
#include
#include
#include "memory/allStatic.hpp"
+#include "metaprogramming/enableIf.hpp"
#include "utilities/debug.hpp"
// Iteration support for enums.
@@ -73,21 +74,52 @@
// }
// EnumeratorRange is a traits type supporting iteration over the enumerators of T.
-// Specializations must provide static const data members named
-// "_first" and "_last", whose values are the smallest / largest
-// (resp.) enumerator values for T. For iteration, the enumerators of
-// T must have sequential values in that range.
+// Specializations must provide static const data members named "_start" and "_end".
+// The type of _start and _end must be the underlying type of T.
+// _start is the inclusive lower bound of values in the range.
+// _end is the exclusive upper bound of values in the range.
+// The enumerators of T must have sequential values in that range.
template struct EnumeratorRange;
-// Specialize EnumeratorRange.
-#define ENUMERATOR_RANGE(T, First, Last) \
- template<> struct EnumeratorRange { \
- static constexpr T _first = First; \
- static constexpr T _last = Last; \
+// Helper class for ENUMERATOR_RANGE and ENUMERATOR_VALUE_RANGE.
+struct EnumeratorRangeImpl : AllStatic {
+ template using Underlying = std::underlying_type_t;
+
+ // T not deduced to verify argument is of expected type.
+ template::value)>
+ static constexpr Underlying start_value(U first) {
+ return static_cast>(first);
+ }
+
+ // T not deduced to verify argument is of expected type.
+ template::value)>
+ static constexpr Underlying end_value(U last) {
+ Underlying value = static_cast>(last);
+ assert(value < std::numeric_limits>::max(), "end value overflow");
+ return static_cast>(value + 1);
+ }
+};
+
+// Specialize EnumeratorRange. Start and End must be constant expressions
+// whose value is convertible to the underlying type of T. They provide the
+// values of the required _start and _end members respectively.
+#define ENUMERATOR_VALUE_RANGE(T, Start, End) \
+ template<> struct EnumeratorRange { \
+ static constexpr EnumeratorRangeImpl::Underlying _start{Start}; \
+ static constexpr EnumeratorRangeImpl::Underlying _end{End}; \
};
-// A helper class for EnumIterator, computing some additional information the
-// iterator uses, based on T and EnumeratorRange.
+// Specialize EnumeratorRange. First and Last must be constant expressions
+// of type T. They determine the values of the required _start and _end members
+// respectively. _start is the underlying value of First. _end is the underlying
+// value of Last, plus one.
+#define ENUMERATOR_RANGE(T, First, Last) \
+ ENUMERATOR_VALUE_RANGE(T, \
+ EnumeratorRangeImpl::start_value(First), \
+ EnumeratorRangeImpl::end_value(Last));
+
+// A helper class for EnumRange and EnumIterator, computing some
+// additional information based on T and EnumeratorRange.
template
class EnumIterationTraits : AllStatic {
using RangeType = EnumeratorRange;
@@ -96,21 +128,20 @@ class EnumIterationTraits : AllStatic {
// The underlying type for T.
using Underlying = std::underlying_type_t;
- // The first enumerator of T.
- static constexpr T _first = RangeType::_first;
+ // The value of the first enumerator of T.
+ static constexpr Underlying _start = RangeType::_start;
- // The last enumerator of T.
- static constexpr T _last = RangeType::_last;
+ // The one-past-the-end value for T.
+ static constexpr Underlying _end = RangeType::_end;
- static_assert(static_cast(_last) <
- std::numeric_limits::max(),
- "No one-past-the-end value for enum");
+ // The first enumerator of T.
+ static constexpr T _first = static_cast(_start);
- // The value of the first enumerator of T.
- static constexpr Underlying _start = static_cast(_first);
+ // The last enumerator of T.
+ static constexpr T _last = static_cast(_end - 1);
- // The one-past-the-end value for T.
- static constexpr Underlying _end = static_cast(_last) + 1;
+ static_assert(_start != _end, "empty range");
+ static_assert(_start <= _end, "invalid range"); // <= so only one failure when ==.
};
template
@@ -125,6 +156,8 @@ class EnumIterator {
}
public:
+ using EnumType = T;
+
// Return a beyond-the-end iterator.
constexpr EnumIterator() : _value(Traits::_end) {}
@@ -180,6 +213,7 @@ class EnumRange {
Underlying _end;
public:
+ using EnumType = T;
using Iterator = EnumIterator;
// Default constructor gives the full range.
@@ -214,6 +248,17 @@ class EnumRange {
constexpr size_t size() const {
return static_cast(_end - _start); // _end is exclusive
}
+
+ constexpr T first() const { return static_cast(_start); }
+ constexpr T last() const { return static_cast(_end - 1); }
+
+ // Convert value to a zero-based index into the range [first(), last()].
+ // precondition: first() <= value && value <= last()
+ constexpr size_t index(T value) const {
+ assert(first() <= value, "out of bounds");
+ assert(value <= last(), "out of bounds");
+ return static_cast(static_cast(value) - _start);
+ }
};
#endif // SHARE_UTILITIES_ENUMITERATOR_HPP
diff --git a/test/hotspot/gtest/utilities/test_enumIterator.cpp b/test/hotspot/gtest/utilities/test_enumIterator.cpp
new file mode 100644
index 0000000000000..f1bf16f1a76b3
--- /dev/null
+++ b/test/hotspot/gtest/utilities/test_enumIterator.cpp
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 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.
+ */
+
+#include "precompiled.hpp"
+#include "utilities/enumIterator.hpp"
+#include
+#include "unittest.hpp"
+
+enum class ExplicitTest : int { value1, value2, value3 };
+ENUMERATOR_RANGE(ExplicitTest, ExplicitTest::value1, ExplicitTest::value3);
+constexpr int explicit_start = 0;
+constexpr int explicit_end = 3;
+
+enum class ImplicitTest : int {};
+ENUMERATOR_VALUE_RANGE(ImplicitTest, 5, 10);
+constexpr int implicit_start = 5;
+constexpr int implicit_end = 10;
+
+TEST(TestEnumIterator, explicit_full_range) {
+ using Range = EnumRange;
+ constexpr Range range{};
+ EXPECT_TRUE((std::is_same::value));
+ EXPECT_EQ(size_t(explicit_end - explicit_start), range.size());
+ EXPECT_EQ(ExplicitTest::value1, range.first());
+ EXPECT_EQ(ExplicitTest::value3, range.last());
+ EXPECT_EQ(size_t(1), range.index(ExplicitTest::value2));
+}
+
+TEST(TestEnumIterator, explicit_partial_range) {
+ using Range = EnumRange;
+ constexpr Range range{ExplicitTest::value2};
+ EXPECT_TRUE((std::is_same::value));
+ EXPECT_EQ(size_t(explicit_end - (explicit_start + 1)), range.size());
+ EXPECT_EQ(ExplicitTest::value2, range.first());
+ EXPECT_EQ(ExplicitTest::value3, range.last());
+ EXPECT_EQ(size_t(0), range.index(ExplicitTest::value2));
+}
+
+TEST(TestEnumIterator, implicit_full_range) {
+ using Range = EnumRange;
+ constexpr Range range{};
+ EXPECT_TRUE((std::is_same::value));
+ EXPECT_EQ(size_t(implicit_end - implicit_start), range.size());
+ EXPECT_EQ(static_cast(implicit_start), range.first());
+ EXPECT_EQ(static_cast(implicit_end - 1), range.last());
+ EXPECT_EQ(size_t(2), range.index(static_cast(implicit_start + 2)));
+}
+
+TEST(TestEnumIterator, implicit_partial_range) {
+ using Range = EnumRange;
+ constexpr Range range{static_cast(implicit_start + 2)};
+ EXPECT_TRUE((std::is_same::value));
+ EXPECT_EQ(size_t(implicit_end - (implicit_start + 2)), range.size());
+ EXPECT_EQ(static_cast(implicit_start + 2), range.first());
+ EXPECT_EQ(static_cast(implicit_end - 1), range.last());
+ EXPECT_EQ(size_t(1), range.index(static_cast(implicit_start + 3)));
+}
+
+TEST(TestEnumIterator, explict_iterator) {
+ using Range = EnumRange;
+ using Iterator = EnumIterator;
+ constexpr Range range{};
+ EXPECT_EQ(range.first(), *range.begin());
+ EXPECT_EQ(Iterator(range.first()), range.begin());
+ EnumIterator it = range.begin();
+ ++it;
+ EXPECT_EQ(ExplicitTest::value2, *it);
+ it = range.begin();
+ for (int i = explicit_start; i < explicit_end; ++i, ++it) {
+ ExplicitTest value = static_cast(i);
+ EXPECT_EQ(value, *it);
+ EXPECT_EQ(Iterator(value), it);
+ EXPECT_EQ(size_t(i - explicit_start), range.index(value));
+ }
+ EXPECT_EQ(it, range.end());
+}
+
+TEST(TestEnumIterator, implicit_iterator) {
+ using Range = EnumRange;
+ using Iterator = EnumIterator;
+ constexpr Range range{};
+ EXPECT_EQ(range.first(), *range.begin());
+ EXPECT_EQ(Iterator(range.first()), range.begin());
+ EnumIterator it = range.begin();
+ for (int i = implicit_start; i < implicit_end; ++i, ++it) {
+ ImplicitTest value = static_cast(i);
+ EXPECT_EQ(value, *it);
+ EXPECT_EQ(Iterator(value), it);
+ EXPECT_EQ(size_t(i - implicit_start), range.index(value));
+ }
+ EXPECT_EQ(it, range.end());
+}
From d80ae05f617b35bd327e03869284de0c41adb94d Mon Sep 17 00:00:00 2001
From: Jamil Nimeh
Date: Thu, 3 Dec 2020 06:12:07 +0000
Subject: [PATCH 035/504] 8166596: TLS support for the EdDSA signature
algorithm
Reviewed-by: xuelei
---
.../sun/security/ssl/CertificateRequest.java | 19 +-
.../sun/security/ssl/CertificateVerify.java | 3 +
.../security/ssl/ECDHServerKeyExchange.java | 3 +
.../classes/sun/security/ssl/JsseJce.java | 5 +
.../sun/security/ssl/SSLExtension.java | 4 +-
.../sun/security/ssl/SSLKeyExchange.java | 84 +-
.../sun/security/ssl/SignatureScheme.java | 26 +-
.../sun/security/ssl/X509Authentication.java | 5 +-
.../javax/net/ssl/TLSCommon/TLSWithEdDSA.java | 736 ++++++++++++++++++
9 files changed, 825 insertions(+), 60 deletions(-)
create mode 100644 test/jdk/javax/net/ssl/TLSCommon/TLSWithEdDSA.java
diff --git a/src/java.base/share/classes/sun/security/ssl/CertificateRequest.java b/src/java.base/share/classes/sun/security/ssl/CertificateRequest.java
index 9356894b7fd5f..1512b52800368 100644
--- a/src/java.base/share/classes/sun/security/ssl/CertificateRequest.java
+++ b/src/java.base/share/classes/sun/security/ssl/CertificateRequest.java
@@ -67,8 +67,8 @@ final class CertificateRequest {
// TLS 1.2 and prior versions
private static enum ClientCertificateType {
// RFC 2246
- RSA_SIGN ((byte)0x01, "rsa_sign", "RSA", true),
- DSS_SIGN ((byte)0x02, "dss_sign", "DSA", true),
+ RSA_SIGN ((byte)0x01, "rsa_sign", List.of("RSA"), true),
+ DSS_SIGN ((byte)0x02, "dss_sign", List.of("DSA"), true),
RSA_FIXED_DH ((byte)0x03, "rsa_fixed_dh"),
DSS_FIXED_DH ((byte)0x04, "dss_fixed_dh"),
@@ -77,9 +77,10 @@ private static enum ClientCertificateType {
DSS_EPHEMERAL_DH ((byte)0x06, "dss_ephemeral_dh"),
FORTEZZA_DMS ((byte)0x14, "fortezza_dms"),
- // RFC 4492
+ // RFC 4492 and 8442
ECDSA_SIGN ((byte)0x40, "ecdsa_sign",
- "EC", JsseJce.isEcAvailable()),
+ List.of("EC", "EdDSA"),
+ JsseJce.isEcAvailable()),
RSA_FIXED_ECDH ((byte)0x41, "rsa_fixed_ecdh"),
ECDSA_FIXED_ECDH ((byte)0x42, "ecdsa_fixed_ecdh");
@@ -95,7 +96,7 @@ private static enum ClientCertificateType {
final byte id;
final String name;
- final String keyAlgorithm;
+ final List keyAlgorithm;
final boolean isAvailable;
private ClientCertificateType(byte id, String name) {
@@ -103,7 +104,7 @@ private ClientCertificateType(byte id, String name) {
}
private ClientCertificateType(byte id, String name,
- String keyAlgorithm, boolean isAvailable) {
+ List keyAlgorithm, boolean isAvailable) {
this.id = id;
this.name = name;
this.keyAlgorithm = keyAlgorithm;
@@ -134,7 +135,11 @@ private static String[] getKeyTypes(byte[] ids) {
for (byte id : ids) {
ClientCertificateType cct = ClientCertificateType.valueOf(id);
if (cct.isAvailable) {
- keyTypes.add(cct.keyAlgorithm);
+ cct.keyAlgorithm.forEach(key -> {
+ if (!keyTypes.contains(key)) {
+ keyTypes.add(key);
+ }
+ });
}
}
diff --git a/src/java.base/share/classes/sun/security/ssl/CertificateVerify.java b/src/java.base/share/classes/sun/security/ssl/CertificateVerify.java
index da9b1d8303de7..1aea41525665e 100644
--- a/src/java.base/share/classes/sun/security/ssl/CertificateVerify.java
+++ b/src/java.base/share/classes/sun/security/ssl/CertificateVerify.java
@@ -459,6 +459,9 @@ private static Signature getSignature(String algorithm,
case "EC":
signer = Signature.getInstance(JsseJce.SIGNATURE_RAWECDSA);
break;
+ case "EdDSA":
+ signer = Signature.getInstance(JsseJce.SIGNATURE_EDDSA);
+ break;
default:
throw new SignatureException("Unrecognized algorithm: "
+ algorithm);
diff --git a/src/java.base/share/classes/sun/security/ssl/ECDHServerKeyExchange.java b/src/java.base/share/classes/sun/security/ssl/ECDHServerKeyExchange.java
index b96a7bf572c70..d3d30f7cecaa5 100644
--- a/src/java.base/share/classes/sun/security/ssl/ECDHServerKeyExchange.java
+++ b/src/java.base/share/classes/sun/security/ssl/ECDHServerKeyExchange.java
@@ -424,6 +424,9 @@ private static Signature getSignature(String keyAlgorithm,
case "EC":
signer = Signature.getInstance(JsseJce.SIGNATURE_ECDSA);
break;
+ case "EdDSA":
+ signer = Signature.getInstance(JsseJce.SIGNATURE_EDDSA);
+ break;
case "RSA":
signer = RSASignature.getInstance();
break;
diff --git a/src/java.base/share/classes/sun/security/ssl/JsseJce.java b/src/java.base/share/classes/sun/security/ssl/JsseJce.java
index c6ca4977d0a29..eefaaf2b79aff 100644
--- a/src/java.base/share/classes/sun/security/ssl/JsseJce.java
+++ b/src/java.base/share/classes/sun/security/ssl/JsseJce.java
@@ -90,6 +90,11 @@ final class JsseJce {
*/
static final String SIGNATURE_ECDSA = "SHA1withECDSA";
+ /**
+ * JCA identifier for EdDSA signatures.
+ */
+ static final String SIGNATURE_EDDSA = "EdDSA";
+
/**
* JCA identifier string for Raw DSA, i.e. a DSA signature without
* hashing where the application provides the SHA-1 hash of the data.
diff --git a/src/java.base/share/classes/sun/security/ssl/SSLExtension.java b/src/java.base/share/classes/sun/security/ssl/SSLExtension.java
index c46786b3deade..05ee5ff399fbf 100644
--- a/src/java.base/share/classes/sun/security/ssl/SSLExtension.java
+++ b/src/java.base/share/classes/sun/security/ssl/SSLExtension.java
@@ -274,11 +274,11 @@ enum SSLExtension implements SSLStringizer {
SIGNED_CERT_TIMESTAMP (0x0012, "signed_certificate_timestamp"),
// extensions defined in RFC 7250
- CLIENT_CERT_TYPE (0x0013, "padding"),
+ CLIENT_CERT_TYPE (0x0013, "client_certificate_type"),
SERVER_CERT_TYPE (0x0014, "server_certificate_type"),
// extensions defined in RFC 7685
- PADDING (0x0015, "client_certificate_type"),
+ PADDING (0x0015, "padding"),
// extensions defined in RFC 7366
ENCRYPT_THEN_MAC (0x0016, "encrypt_then_mac"),
diff --git a/src/java.base/share/classes/sun/security/ssl/SSLKeyExchange.java b/src/java.base/share/classes/sun/security/ssl/SSLKeyExchange.java
index 846f7a84f3dbc..e9657de057eb7 100644
--- a/src/java.base/share/classes/sun/security/ssl/SSLKeyExchange.java
+++ b/src/java.base/share/classes/sun/security/ssl/SSLKeyExchange.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -29,18 +29,23 @@
import java.util.AbstractMap.SimpleImmutableEntry;
import java.util.Arrays;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import sun.security.ssl.SupportedGroupsExtension.SupportedGroups;
import sun.security.ssl.X509Authentication.X509Possession;
final class SSLKeyExchange implements SSLKeyAgreementGenerator,
SSLHandshakeBinding {
- private final SSLAuthentication authentication;
+ private final List authentication;
private final SSLKeyAgreement keyAgreement;
- SSLKeyExchange(X509Authentication authentication,
+ SSLKeyExchange(List authentication,
SSLKeyAgreement keyAgreement) {
- this.authentication = authentication;
+ if (authentication != null) {
+ this.authentication = List.copyOf(authentication);
+ } else {
+ this.authentication = null;
+ }
this.keyAgreement = keyAgreement;
}
@@ -48,7 +53,15 @@ SSLPossession[] createPossessions(HandshakeContext context) {
// authentication
SSLPossession authPossession = null;
if (authentication != null) {
- authPossession = authentication.createPossession(context);
+ // Loop through potential authentication types and end at
+ // the first non-null possession.
+ for (SSLAuthentication authType : authentication) {
+ if ((authPossession = authType.createPossession(context))
+ != null) {
+ break;
+ }
+ }
+
if (authPossession == null) {
return new SSLPossession[0];
} else if (context instanceof ServerHandshakeContext) {
@@ -109,12 +122,14 @@ public SSLKeyDerivation createKeyDerivation(
@Override
public SSLHandshake[] getRelatedHandshakers(
HandshakeContext handshakeContext) {
- SSLHandshake[] auHandshakes;
+ SSLHandshake[] auHandshakes = null;
if (authentication != null) {
- auHandshakes =
- authentication.getRelatedHandshakers(handshakeContext);
- } else {
- auHandshakes = null;
+ for (SSLAuthentication authType : authentication) {
+ auHandshakes = authType.getRelatedHandshakers(handshakeContext);
+ if (auHandshakes != null && auHandshakes.length > 0) {
+ break;
+ }
+ }
}
SSLHandshake[] kaHandshakes =
@@ -136,12 +151,14 @@ public SSLHandshake[] getRelatedHandshakers(
@Override
public Map.Entry[] getHandshakeProducers(
HandshakeContext handshakeContext) {
- Map.Entry[] auProducers;
+ Map.Entry[] auProducers = null;
if (authentication != null) {
- auProducers =
- authentication.getHandshakeProducers(handshakeContext);
- } else {
- auProducers = null;
+ for (SSLAuthentication authType : authentication) {
+ auProducers = authType.getHandshakeProducers(handshakeContext);
+ if (auProducers != null && auProducers.length > 0) {
+ break;
+ }
+ }
}
Map.Entry[] kaProducers =
@@ -163,12 +180,14 @@ public Map.Entry[] getHandshakeProducers(
@Override
public Map.Entry[] getHandshakeConsumers(
HandshakeContext handshakeContext) {
- Map.Entry[] auConsumers;
+ Map.Entry[] auConsumers = null;
if (authentication != null) {
- auConsumers =
- authentication.getHandshakeConsumers(handshakeContext);
- } else {
- auConsumers = null;
+ for (SSLAuthentication authType : authentication) {
+ auConsumers = authType.getHandshakeConsumers(handshakeContext);
+ if (auConsumers != null && auConsumers.length > 0) {
+ break;
+ }
+ }
}
Map.Entry[] kaConsumers =
@@ -247,37 +266,37 @@ static SSLKeyExchange valueOf(NamedGroup namedGroup) {
private static class SSLKeyExRSA {
private static SSLKeyExchange KE = new SSLKeyExchange(
- X509Authentication.RSA, T12KeyAgreement.RSA);
+ List.of(X509Authentication.RSA), T12KeyAgreement.RSA);
}
private static class SSLKeyExRSAExport {
private static SSLKeyExchange KE = new SSLKeyExchange(
- X509Authentication.RSA, T12KeyAgreement.RSA_EXPORT);
+ List.of(X509Authentication.RSA), T12KeyAgreement.RSA_EXPORT);
}
private static class SSLKeyExDHEDSS {
private static SSLKeyExchange KE = new SSLKeyExchange(
- X509Authentication.DSA, T12KeyAgreement.DHE);
+ List.of(X509Authentication.DSA), T12KeyAgreement.DHE);
}
private static class SSLKeyExDHEDSSExport {
private static SSLKeyExchange KE = new SSLKeyExchange(
- X509Authentication.DSA, T12KeyAgreement.DHE_EXPORT);
+ List.of(X509Authentication.DSA), T12KeyAgreement.DHE_EXPORT);
}
private static class SSLKeyExDHERSA {
private static SSLKeyExchange KE = new SSLKeyExchange(
- X509Authentication.RSA, T12KeyAgreement.DHE);
+ List.of(X509Authentication.RSA), T12KeyAgreement.DHE);
}
private static class SSLKeyExDHERSAOrPSS {
private static SSLKeyExchange KE = new SSLKeyExchange(
- X509Authentication.RSA_OR_PSS, T12KeyAgreement.DHE);
+ List.of(X509Authentication.RSA_OR_PSS), T12KeyAgreement.DHE);
}
private static class SSLKeyExDHERSAExport {
private static SSLKeyExchange KE = new SSLKeyExchange(
- X509Authentication.RSA, T12KeyAgreement.DHE_EXPORT);
+ List.of(X509Authentication.RSA), T12KeyAgreement.DHE_EXPORT);
}
private static class SSLKeyExDHANON {
@@ -292,27 +311,28 @@ private static class SSLKeyExDHANONExport {
private static class SSLKeyExECDHECDSA {
private static SSLKeyExchange KE = new SSLKeyExchange(
- X509Authentication.EC, T12KeyAgreement.ECDH);
+ List.of(X509Authentication.EC), T12KeyAgreement.ECDH);
}
private static class SSLKeyExECDHRSA {
private static SSLKeyExchange KE = new SSLKeyExchange(
- X509Authentication.EC, T12KeyAgreement.ECDH);
+ List.of(X509Authentication.EC), T12KeyAgreement.ECDH);
}
private static class SSLKeyExECDHEECDSA {
private static SSLKeyExchange KE = new SSLKeyExchange(
- X509Authentication.EC, T12KeyAgreement.ECDHE);
+ List.of(X509Authentication.EC, X509Authentication.EDDSA),
+ T12KeyAgreement.ECDHE);
}
private static class SSLKeyExECDHERSA {
private static SSLKeyExchange KE = new SSLKeyExchange(
- X509Authentication.RSA, T12KeyAgreement.ECDHE);
+ List.of(X509Authentication.RSA), T12KeyAgreement.ECDHE);
}
private static class SSLKeyExECDHERSAOrPSS {
private static SSLKeyExchange KE = new SSLKeyExchange(
- X509Authentication.RSA_OR_PSS, T12KeyAgreement.ECDHE);
+ List.of(X509Authentication.RSA_OR_PSS), T12KeyAgreement.ECDHE);
}
private static class SSLKeyExECDHANON {
diff --git a/src/java.base/share/classes/sun/security/ssl/SignatureScheme.java b/src/java.base/share/classes/sun/security/ssl/SignatureScheme.java
index 539ce3141f119..fe089b1403a9a 100644
--- a/src/java.base/share/classes/sun/security/ssl/SignatureScheme.java
+++ b/src/java.base/share/classes/sun/security/ssl/SignatureScheme.java
@@ -47,14 +47,6 @@
import sun.security.util.SignatureUtil;
enum SignatureScheme {
- // EdDSA algorithms
- ED25519 (0x0807, "ed25519", "ed25519",
- "ed25519",
- ProtocolVersion.PROTOCOLS_OF_13),
- ED448 (0x0808, "ed448", "ed448",
- "ed448",
- ProtocolVersion.PROTOCOLS_OF_13),
-
// ECDSA algorithms
ECDSA_SECP256R1_SHA256 (0x0403, "ecdsa_secp256r1_sha256",
"SHA256withECDSA",
@@ -72,6 +64,14 @@ enum SignatureScheme {
NamedGroup.SECP521_R1,
ProtocolVersion.PROTOCOLS_TO_13),
+ // EdDSA algorithms
+ ED25519 (0x0807, "ed25519", "Ed25519",
+ "EdDSA",
+ ProtocolVersion.PROTOCOLS_12_13),
+ ED448 (0x0808, "ed448", "Ed448",
+ "EdDSA",
+ ProtocolVersion.PROTOCOLS_12_13),
+
// RSASSA-PSS algorithms with public key OID rsaEncryption
//
// The minimalKeySize is calculated as (See RFC 8017 for details):
@@ -275,16 +275,6 @@ private SignatureScheme(int id, String name,
boolean mediator = true;
- // Disable EdDSA algorithms for TLS. Remove this when support is added.
- if (id == 0x0807 || id == 0x0808) {
- mediator = false;
- if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
- SSLLogger.warning(
- "Signature algorithm, " + algorithm +
- ", not supported by JSSE");
- }
- }
-
// An EC provider, for example the SunEC provider, may support
// AlgorithmParameters but not KeyPairGenerator or Signature.
//
diff --git a/src/java.base/share/classes/sun/security/ssl/X509Authentication.java b/src/java.base/share/classes/sun/security/ssl/X509Authentication.java
index 5810a7e0132d6..7962ffa161cb8 100644
--- a/src/java.base/share/classes/sun/security/ssl/X509Authentication.java
+++ b/src/java.base/share/classes/sun/security/ssl/X509Authentication.java
@@ -64,7 +64,10 @@ enum X509Authentication implements SSLAuthentication {
// Require EC public key
EC ("EC", new X509PossessionGenerator(
- new String[] {"EC"}));
+ new String[] {"EC"})),
+ // Edwards-Curve key
+ EDDSA ("EdDSA", new X509PossessionGenerator(
+ new String[] {"EdDSA"}));
final String keyType;
final SSLPossessionGenerator possessionGenerator;
diff --git a/test/jdk/javax/net/ssl/TLSCommon/TLSWithEdDSA.java b/test/jdk/javax/net/ssl/TLSCommon/TLSWithEdDSA.java
new file mode 100644
index 0000000000000..3fabc5bd73c88
--- /dev/null
+++ b/test/jdk/javax/net/ssl/TLSCommon/TLSWithEdDSA.java
@@ -0,0 +1,736 @@
+/*
+ * Copyright (c) 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.
+ */
+
+/*
+ * SunJSSE does not support dynamic system properties, no way to re-use
+ * system properties in samevm/agentvm mode.
+ * For extra debugging output, add -Djavax.net.debug=ssl:handshake into the
+ * run directive below.
+ */
+
+/*
+ * @test
+ * @bug 8166596
+ * @summary TLS support for the EdDSA signature algorithm
+ * @library /javax/net/ssl/templates /test/lib
+ * @run main/othervm TLSWithEdDSA
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.net.SocketException;
+import java.nio.charset.Charset;
+import java.security.GeneralSecurityException;
+import java.security.KeyFactory;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.Principal;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.PKIXBuilderParameters;
+import java.security.cert.X509CertSelector;
+import java.security.cert.X509Certificate;
+import java.security.interfaces.ECKey;
+import java.security.interfaces.EdECKey;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.util.*;
+import javax.net.ssl.CertPathTrustManagerParameters;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509ExtendedKeyManager;
+import javax.net.ssl.X509KeyManager;
+import jdk.test.lib.security.SecurityUtils;
+
+public class TLSWithEdDSA extends SSLSocketTemplate {
+ private static final String PASSWD = "passphrase";
+ private static final String DEF_TRUST_ANCHORS = "CA_DSA_1024:CA_DSA_2048:" +
+ "CA_ECDSA_SECP256R1:CA_ECDSA_SECP384R1:CA_ECDSA_SECP521R1:" +
+ "CA_ED25519:CA_ED448:CA_RSA_2048";
+ private static final String DEF_ALL_EE = "EE_ECDSA_SECP256R1:" +
+ "EE_ECDSA_SECP384R1:EE_ECDSA_SECP521R1:EE_RSA_2048:" +
+ "EE_EC_RSA_SECP256R1:EE_DSA_2048:EE_DSA_1024:EE_ED25519:EE_ED448";
+ private static final List TEST_PROTOS = List.of(
+ "TLSv1.3", "TLSv1.2", "TLSv1.1", "TLSv1");
+
+ private static CertificateFactory certFac;
+ private static final Map clientParameters =
+ new HashMap<>();
+ private static final Map serverParameters =
+ new HashMap<>();
+
+ private final SessionChecker clientChecker;
+ private final SessionChecker serverChecker;
+ private final Class extends Throwable> clientException;
+ private final Class extends Throwable> serverException;
+
+ interface SessionChecker {
+ public void check(SSLSocket socket);
+ }
+
+ /**
+ * Checks to make sure the end-entity certificate presented by the
+ * peer uses and Ed25519 key.
+ */
+ final static SessionChecker isPeerEd25519 = new SessionChecker() {
+ @Override
+ public void check(SSLSocket sock) {
+ try {
+ SSLSession session = sock.getSession();
+ System.out.println("Peer certificate check for Ed25519:\n" +
+ sessionDump(session));
+ Certificate[] serverCertChain = session.getPeerCertificates();
+ X509Certificate tlsCert = (X509Certificate)serverCertChain[0];
+ keyCheck(tlsCert.getPublicKey(), "EdDSA", "Ed25519");
+ } catch (SSLPeerUnverifiedException sslpe) {
+ throw new RuntimeException(sslpe);
+ }
+ }
+ };
+
+ /**
+ * Checks to make sure the end-entity certificate presented by the
+ * peer uses and Ed448 key.
+ */
+ final static SessionChecker isPeerEd448 = new SessionChecker() {
+ @Override
+ public void check(SSLSocket sock) {
+ try {
+ SSLSession session = sock.getSession();
+ System.out.println("Peer certificate check for Ed448:\n" +
+ sessionDump(session));
+ Certificate[] serverCertChain = session.getPeerCertificates();
+ X509Certificate tlsCert = (X509Certificate)serverCertChain[0];
+ keyCheck(tlsCert.getPublicKey(), "EdDSA", "Ed448");
+ } catch (SSLPeerUnverifiedException sslpe) {
+ throw new RuntimeException(sslpe);
+ }
+ }
+ };
+
+ /**
+ * Checks to make sure the end-entity certificate presented by the
+ * peer uses an EC secp521r1 key.
+ */
+ final static SessionChecker isPeerP521 = new SessionChecker() {
+ @Override
+ public void check(SSLSocket sock) {
+ try {
+ SSLSession session = sock.getSession();
+ System.out.println("Peer certificate check for secp521r1:\n" +
+ sessionDump(session));
+ Certificate[] serverCertChain = session.getPeerCertificates();
+ X509Certificate tlsCert = (X509Certificate)serverCertChain[0];
+ keyCheck(tlsCert.getPublicKey(), "EC", "secp521r1");
+ } catch (SSLPeerUnverifiedException sslpe) {
+ throw new RuntimeException(sslpe);
+ }
+ }
+ };
+
+ /**
+ * Returns a String summary of an SSLSession object
+ *
+ * @param sess the SSLSession object to be dumped
+ *
+ * @return a String representation of the test-relevant portions of the
+ * SSLSession object.
+ */
+ private static String sessionDump(SSLSession sess) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("----- Session Info -----\n");
+ sb.append("Protocol: ").append(sess.getProtocol()).append("\n");
+ sb.append("Cipher Suite: ").append(sess.getCipherSuite());
+ Certificate[] localCerts = sess.getLocalCertificates();
+ if (localCerts != null) {
+ sb.append("\nLocal Certs:");
+ int i = 0;
+ for (Certificate cert : localCerts) {
+ sb.append(String.format("\n [%d]: %s", i++,
+ ((X509Certificate)cert).getSubjectX500Principal()));
+ }
+ }
+ try {
+ Certificate[] peerCerts = sess.getPeerCertificates();
+ if (peerCerts != null) {
+ sb.append("\nPeer Certs:");
+ int i = 0;
+ for (Certificate cert : peerCerts) {
+ sb.append(String.format("\n [%d]: %s", i++,
+ ((X509Certificate)cert).getSubjectX500Principal()));
+ }
+ }
+ } catch (SSLPeerUnverifiedException sslex) {
+ throw new RuntimeException(sslex);
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * Checks to make sure the public key conforms to the expected key type
+ * and (where applicable) curve.
+ *
+ * @param pubKey the public key to be checked
+ * @param expPkType the expected key type (RSA/DSA/EC/EdDSA)
+ * @param expCurveName if an EC/EdDSA key, the expected curve
+ */
+ private static void keyCheck(PublicKey pubKey, String expPkType,
+ String expCurveName) {
+ String curveName = null;
+ String pubKeyAlg = pubKey.getAlgorithm();
+ if (!expPkType.equalsIgnoreCase(pubKeyAlg)) {
+ throw new RuntimeException("Expected " + expPkType + " key, got " +
+ pubKeyAlg);
+ }
+
+ // Check the curve type
+ if (expCurveName != null) {
+ switch (pubKeyAlg) {
+ case "EdDSA":
+ curveName = ((EdECKey)pubKey).getParams().getName().
+ toLowerCase();
+ if (!expCurveName.equalsIgnoreCase(curveName)) {
+ throw new RuntimeException("Expected " + expCurveName +
+ " curve, " + "got " + curveName);
+ }
+ break;
+ case "EC":
+ curveName = ((ECKey)pubKey).getParams().toString().
+ toLowerCase();
+ if (!curveName.contains(expCurveName.toLowerCase())) {
+ throw new RuntimeException("Expected " + expCurveName +
+ " curve, " + "got " + curveName);
+ }
+ break;
+ default:
+ throw new IllegalArgumentException(
+ "Unsupported key type: " + pubKeyAlg);
+ }
+ }
+ System.out.format("Found key: %s / %s\n", pubKeyAlg,
+ curveName != null ? curveName : "");
+ }
+
+ TLSWithEdDSA(SessionChecker cliChk, Class extends Throwable> cliExpExc,
+ SessionChecker servChk, Class extends Throwable> servExpExc) {
+ super();
+ clientChecker = cliChk;
+ clientException = cliExpExc;
+ serverChecker = servChk;
+ serverException = servExpExc;
+ }
+
+ /**
+ * Creates an SSLContext for use with the client side of this test. This
+ * uses parameters held in the static client parameters map.
+ *
+ * @return an initialized SSLContext for use with the client.
+ *
+ * @throws Exception if any downstream errors occur during key store
+ * creation, key/trust manager factory creation or context
+ * initialization.
+ */
+ @Override
+ protected SSLContext createClientSSLContext() throws Exception {
+ KeyStore clientKeyStore = createKeyStore(
+ clientParameters.getOrDefault(ParamType.KSENTRIES, ""),
+ PASSWD.toCharArray());
+ KeyStore clientTrustStore = createTrustStore(
+ clientParameters.getOrDefault(ParamType.TSENTRIES,
+ DEF_TRUST_ANCHORS));
+ return createCtxCommon(clientKeyStore,
+ clientParameters.get(ParamType.CERTALIAS), PASSWD.toCharArray(),
+ clientTrustStore, "jdk.tls.client.SignatureSchemes",
+ clientParameters.get(ParamType.SIGALGS));
+ }
+
+ /**
+ * Creates an SSLContext for use with the server side of this test. This
+ * uses parameters held in the static server parameters map.
+ *
+ * @return an initialized SSLContext for use with the server.
+ *
+ * @throws Exception if any downstream errors occur during key store
+ * creation, key/trust manager factory creation or context
+ * initialization.
+ */
+ @Override
+ protected SSLContext createServerSSLContext() throws Exception {
+ KeyStore serverKeyStore = createKeyStore(
+ serverParameters.getOrDefault(ParamType.KSENTRIES, ""),
+ PASSWD.toCharArray());
+ KeyStore serverTrustStore = createTrustStore(
+ serverParameters.getOrDefault(ParamType.TSENTRIES,
+ DEF_TRUST_ANCHORS));
+ return createCtxCommon(serverKeyStore,
+ serverParameters.get(ParamType.CERTALIAS), PASSWD.toCharArray(),
+ serverTrustStore, "jdk.tls.server.SignatureSchemes",
+ serverParameters.get(ParamType.SIGALGS));
+ }
+
+ /**
+ * Create a trust store containing any CA certificates designated as
+ * trust anchors.
+ *
+ * @return the trust store populated with the root CA certificate.
+ *
+ * @throws GeneralSecurityException if any certificates cannot be added to
+ * the key store.
+ */
+ private static KeyStore createTrustStore(String certEnumNames)
+ throws GeneralSecurityException {
+ KeyStore.Builder keyStoreBuilder =
+ KeyStore.Builder.newInstance("PKCS12", null,
+ new KeyStore.PasswordProtection(PASSWD.toCharArray()));
+ KeyStore ks = keyStoreBuilder.getKeyStore();
+ for (String certName : certEnumNames.split(":")) {
+ try {
+ SSLSocketTemplate.Cert cert =
+ SSLSocketTemplate.Cert.valueOf(certName);
+ ks.setCertificateEntry(certName, pem2Cert(cert.certStr));
+ } catch (IllegalArgumentException iae) {
+ System.out.println("Unable to find Cert enum entry for " +
+ certName + ", skipping");
+ }
+ }
+ return ks;
+ }
+
+ /**
+ * Create a key store containing any end-entity private keys/certs
+ * specified in the parameters.
+ *
+ * @param certEnumNames a colon-delimited list of String values that are
+ * the names of the SSLSocketTemplate.Cert enumeration entries.
+ * @param pass the desired password for the resulting KeyStore object.
+ *
+ * @return a populated, loaded KeyStore ready for use.
+ *
+ * @throws GeneralSecurityException if any issues occur while setting
+ * the private key or certificate entries.
+ */
+ private static KeyStore createKeyStore(String certEnumNames, char[] pass)
+ throws GeneralSecurityException {
+ KeyStore.Builder keyStoreBuilder =
+ KeyStore.Builder.newInstance("PKCS12", null,
+ new KeyStore.PasswordProtection(pass));
+ KeyStore ks = keyStoreBuilder.getKeyStore();
+ if (certEnumNames != null && !certEnumNames.isEmpty()) {
+ for (String certName : certEnumNames.split(":")) {
+ try {
+ SSLSocketTemplate.Cert cert =
+ SSLSocketTemplate.Cert.valueOf(certName);
+ ks.setKeyEntry(certName,
+ pem2PrivKey(cert.privKeyStr, cert.keyAlgo), pass,
+ new Certificate[] { pem2Cert(cert.certStr) });
+ } catch (IllegalArgumentException iae) {
+ System.out.println("Unable to find Cert enum entry for " +
+ certName + ", skipping");
+ }
+ }
+ }
+
+ return ks;
+ }
+
+ /**
+ * Covert a PEM-encoded certificate into a X509Certificate object.
+ *
+ * @param certPem the PEM encoding for the certificate.
+ *
+ * @return the corresponding X509Certificate object for the provided PEM.
+ *
+ * @throws CertificateException if any decoding errors occur.
+ */
+ private static X509Certificate pem2Cert(String certPem)
+ throws CertificateException {
+ return (X509Certificate)certFac.generateCertificate(
+ new ByteArrayInputStream(certPem.getBytes(
+ Charset.forName("UTF-8"))));
+ }
+
+ /**
+ * Covert a PEM-encoded PKCS8 private key into a PrivateKey object.
+ *
+ * @param keyPem the PEM encoding for the certificate.
+ * @param keyAlg the algorithm for the private key contained in the PKCS8
+ * ` encoding.
+ *
+ * @return the corresponding PrivateKey object for the provided PEM.
+ *
+ * @throws GeneralSecurityException if any decoding errors occur.
+ */
+ private static PrivateKey pem2PrivKey(String keyPem, String keyAlg)
+ throws GeneralSecurityException {
+ PKCS8EncodedKeySpec p8Spec = new PKCS8EncodedKeySpec(
+ Base64.getMimeDecoder().decode(keyPem));
+ KeyFactory keyFac = KeyFactory.getInstance(keyAlg);
+ return keyFac.generatePrivate(p8Spec);
+ }
+
+ /**
+ * Create an SSLContext for use with the client or server sides of this
+ * test.
+ *
+ * @param keys the key store object for this SSLContext.
+ * @param alias optional alias specifier to exclusively use that alias for
+ * TLS connections.
+ * @param pass the key store password
+ * @param trust the trust store object
+ * @param sigAlgProp the signature algorithm property name to set
+ * (reserved for future use pending the fix for JDK-8255867)
+ * @param sigAlgVal the property value to be applied.
+ *
+ * @return an initialized SSLContext object.
+ *
+ * @throws IOException if any IOExceptions during manager factory creation
+ * take place
+ * @throws GeneralSecurityException any other failure during SSLContext
+ * creation/initialization
+ */
+ private static SSLContext createCtxCommon(KeyStore keys, String alias,
+ char[] pass, KeyStore trust, String sigAlgProp, String sigAlgVal)
+ throws IOException, GeneralSecurityException {
+ SSLContext ctx;
+ if (sigAlgVal != null && !sigAlgVal.isEmpty()) {
+ System.setProperty(sigAlgProp, sigAlgVal);
+ }
+
+ // If an alias is specified use our local AliasKeyManager
+ KeyManager[] kms = (alias != null && !alias.isEmpty()) ?
+ new KeyManager[] { new AliasKeyManager(keys, pass, alias) } :
+ createKeyManagerFactory(keys, pass).getKeyManagers();
+
+ ctx = SSLContext.getInstance("TLS");
+ ctx.init(kms, createTrustManagerFactory(trust).getTrustManagers(),
+ null);
+ return ctx;
+ }
+
+ /**
+ * Creates a KeyManagerFactory for use during SSLContext initialization.
+ *
+ * @param ks the KeyStore forming the base of the KeyManagerFactory
+ * @param passwd the password to use for the key store
+ *
+ * @return the initialized KeyManagerFactory
+ *
+ * @throws IOException any IOExceptions during key manager factory
+ * initialization.
+ * @throws GeneralSecurityException if any failures during instantiation
+ * take place.
+ */
+ private static KeyManagerFactory createKeyManagerFactory(KeyStore ks,
+ char[] passwd) throws IOException, GeneralSecurityException {
+ KeyManagerFactory kmf;
+ kmf = KeyManagerFactory.getInstance("SunX509");
+ kmf.init(ks, passwd);
+
+ KeyManager[] kmgrs = kmf.getKeyManagers();
+ X509ExtendedKeyManager xkm = (X509ExtendedKeyManager)kmgrs[0];
+ return kmf;
+ }
+
+ /**
+ * Creates a TrustManagerFactory for use during SSLContext initialization.
+ *
+ * @param trustStrore the KeyStore forming the base of the
+ * TrustManagerFactory
+ *
+ * @return the initialized TrustManagerFactory
+ *
+ * @throws IOException any IOExceptions during trust manager factory
+ * initialization.
+ * @throws GeneralSecurityException if any failures during instantiation
+ * take place.
+ */
+ private static TrustManagerFactory createTrustManagerFactory(
+ KeyStore trustStore) throws IOException, GeneralSecurityException {
+ TrustManagerFactory tmf;
+ PKIXBuilderParameters pkixParams =
+ new PKIXBuilderParameters(trustStore, new X509CertSelector());
+ pkixParams.setRevocationEnabled(false);
+ tmf = TrustManagerFactory.getInstance("PKIX");
+ tmf.init(new CertPathTrustManagerParameters(pkixParams));
+ return tmf;
+ }
+
+ /*
+ * Configure the client side socket.
+ */
+ @Override
+ protected void configureClientSocket(SSLSocket socket) {
+ String pVal;
+ if ((pVal = clientParameters.get(ParamType.PROTOS)) != null) {
+ socket.setEnabledProtocols(pVal.split(":"));
+ }
+
+ if ((pVal = clientParameters.get(ParamType.CIPHERS)) != null) {
+ socket.setEnabledCipherSuites(pVal.split(":"));
+ }
+ }
+
+ /*
+ * Configure the server side socket.
+ */
+ @Override
+ protected void configureServerSocket(SSLServerSocket socket) {
+ String pVal;
+ try {
+ socket.setReuseAddress(true);
+ if ((pVal = serverParameters.get(ParamType.PROTOS)) != null) {
+ socket.setEnabledProtocols(pVal.split(":"));
+ }
+
+ if ((pVal = serverParameters.get(ParamType.CIPHERS)) != null) {
+ socket.setEnabledCipherSuites(pVal.split(":"));
+ }
+
+ pVal = serverParameters.get(ParamType.CLIAUTH);
+ socket.setWantClientAuth("WANT".equalsIgnoreCase(pVal));
+ socket.setNeedClientAuth("NEED".equalsIgnoreCase(pVal));
+ } catch (SocketException se) {
+ throw new RuntimeException(se);
+ }
+ }
+
+
+ @Override
+ protected void runServerApplication(SSLSocket socket) throws Exception {
+ InputStream sslIS = socket.getInputStream();
+ OutputStream sslOS = socket.getOutputStream();
+
+ sslIS.read();
+ sslOS.write(85);
+ sslOS.flush();
+
+ if (serverChecker != null) {
+ serverChecker.check(socket);
+ }
+ }
+
+ @Override
+ protected void runClientApplication(SSLSocket socket) throws Exception {
+ InputStream sslIS = socket.getInputStream();
+ OutputStream sslOS = socket.getOutputStream();
+
+ sslOS.write(280);
+ sslOS.flush();
+ sslIS.read();
+
+ if (clientChecker != null) {
+ clientChecker.check(socket);
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ SecurityUtils.removeFromDisabledTlsAlgs("TLSv1.1", "TLSv1");
+ certFac = CertificateFactory.getInstance("X.509");
+ String testFormat;
+
+ System.out.println("===== Test KeyManager alias retrieval =====");
+ testKeyManager(DEF_ALL_EE, "EdDSA",
+ new String[] {"ee_ed25519", "ee_ed448"});
+
+ testFormat =
+ "===== Basic Ed25519 Server-side Authentication: %s =====\n";
+ serverParameters.put(ParamType.KSENTRIES, "EE_ED25519:EE_RSA_2048");
+ runtest(testFormat, isPeerEd25519, null, null, null);
+
+ testFormat =
+ "===== Basic Ed448 Server-side Authentication: %s =====\n";
+ serverParameters.put(ParamType.KSENTRIES, "EE_ED448:EE_RSA_2048");
+ runtest(testFormat, isPeerEd448, null, null, null);
+
+ testFormat = "===== EC favored over EdDSA by default: %s =====\n";
+ serverParameters.put(ParamType.KSENTRIES,
+ "EE_ED25519:EE_ECDSA_SECP521R1");
+ runtest(testFormat, isPeerP521, null, null, null);
+
+ testFormat = "===== Override EC favoring by alias: %s =====\n";
+ serverParameters.put(ParamType.CERTALIAS, "EE_ED25519");
+ runtest(testFormat, isPeerEd25519, null, null, null);
+ serverParameters.remove(ParamType.CERTALIAS);
+
+ testFormat = "===== EdDSA Client Authentication: %s =====\n";
+ serverParameters.put(ParamType.KSENTRIES, "EE_RSA_2048");
+ serverParameters.put(ParamType.CLIAUTH, "NEED");
+ clientParameters.put(ParamType.KSENTRIES, "EE_ED25519");
+ runtest(testFormat, null, null, isPeerEd25519, null);
+ }
+
+ private static void testKeyManager(String keyStoreSpec, String keyType,
+ String[] expAliases)
+ throws GeneralSecurityException, IOException {
+ char[] passChar = PASSWD.toCharArray();
+
+ // Create the KeyManager factory and resulting KeyManager
+ KeyManagerFactory kmf = createKeyManagerFactory(
+ createKeyStore(keyStoreSpec, passChar), passChar);
+ KeyManager[] kMgrs = kmf.getKeyManagers();
+ X509KeyManager xkm = (X509KeyManager)kMgrs[0];
+
+ String[] cliEdDSAAlises = xkm.getClientAliases(keyType, null);
+ System.out.format("Client Aliases (%s): ", keyType);
+ for (String alias : cliEdDSAAlises) {
+ System.out.print(alias + " ");
+ }
+ System.out.println();
+
+ String[] servEdDSAAliases = xkm.getServerAliases(keyType, null);
+ System.out.format("Server Aliases (%s): ", keyType);
+ for (String alias : servEdDSAAliases) {
+ System.out.print(alias + " ");
+ }
+ System.out.println();
+
+ if (!Arrays.equals(cliEdDSAAlises, expAliases)) {
+ throw new RuntimeException("Client alias mismatch");
+ } else if (!Arrays.equals(servEdDSAAliases, expAliases)) {
+ throw new RuntimeException("Server alias mismatch");
+ }
+ }
+
+ private static void runtest(String testNameFmt, SessionChecker cliChk,
+ Class extends Throwable> cliExpExc, SessionChecker servChk,
+ Class extends Throwable> servExpExc) {
+ TEST_PROTOS.forEach(protocol -> {
+ clientParameters.put(ParamType.PROTOS, protocol);
+ TLSWithEdDSA testObj = new TLSWithEdDSA(cliChk, cliExpExc, servChk,
+ servExpExc);
+ System.out.format(testNameFmt, protocol);
+ try {
+ testObj.run();
+ if (testObj.clientException != null ||
+ testObj.serverException != null) {
+ throw new RuntimeException("Expected exception from " +
+ "either client or server but was missed");
+ }
+ } catch (Exception exc) {
+ if (testObj.clientException == null &&
+ testObj.serverException == null) {
+ throw new RuntimeException(
+ "Expected test failure did not occur");
+ } else if (testObj.clientException != null &&
+ !testObj.clientException.isAssignableFrom(exc.getClass())) {
+ throw new RuntimeException("Unexpected client exception " +
+ "detected: Expected " +
+ testObj.clientException.getName() +
+ ", got " + exc.getClass().getName());
+
+ } else if (testObj.serverException != null &&
+ !testObj.serverException.isAssignableFrom(exc.getClass())) {
+ throw new RuntimeException("Unexpected client exception " +
+ "detected: Expected " +
+ testObj.serverException.getName() +
+ ", got " + exc.getClass().getName());
+ }
+ }
+ System.out.println();
+ });
+ }
+
+ /**
+ * A Custom KeyManager that allows the user to specify a key/certificate
+ * by alias to be used for any TLS authentication actions.
+ */
+ static class AliasKeyManager implements X509KeyManager {
+ private final String alias;
+ private final KeyStore keystore;
+ private final char[] pass;
+
+ public AliasKeyManager(KeyStore keystore, char[] pass, String alias) {
+ this.keystore = Objects.requireNonNull(keystore);
+ this.alias = Objects.requireNonNull(alias);
+ this.pass = Objects.requireNonNull(pass);
+ }
+
+ @Override
+ public PrivateKey getPrivateKey(String alias) {
+ try {
+ return (PrivateKey)keystore.getKey(alias, pass);
+ } catch (GeneralSecurityException exc) {
+ throw new RuntimeException(exc);
+ }
+ }
+
+ @Override
+ public X509Certificate[] getCertificateChain(String alias) {
+ try {
+ Certificate[] certAr = keystore.getCertificateChain(alias);
+ return (certAr != null) ? Arrays.copyOf(certAr, certAr.length,
+ X509Certificate[].class) : null;
+ } catch (KeyStoreException ke) {
+ throw new RuntimeException(ke);
+ }
+ }
+
+ @Override
+ public String chooseClientAlias(String[] keyType, Principal[] issuers,
+ Socket socket) {
+ // Blindly return the one selected alias.
+ return alias;
+ }
+
+ @Override
+ public String chooseServerAlias(String keyType, Principal[] issuers,
+ Socket socket) {
+ // Blindly return the one selected alias.
+ return alias;
+ }
+
+ @Override
+ public String[] getClientAliases(String keyType, Principal[] issuers) {
+ // There can be only one!
+ return new String[] { alias };
+ }
+
+ @Override
+ public String[] getServerAliases(String keyType, Principal[] issuers) {
+ // There can be only one!
+ return new String[] { alias };
+ }
+ }
+
+ static enum ParamType {
+ PROTOS,
+ CIPHERS,
+ SIGALGS,
+ CLIAUTH,
+ KSENTRIES,
+ TSENTRIES,
+ CERTALIAS
+ }
+}
\ No newline at end of file
From a5a034b72f2babf87d4981ebd90b18b1baa4e793 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?=
Date: Thu, 3 Dec 2020 07:12:25 +0000
Subject: [PATCH 036/504] 8257617: TestLinkPlatform fails with new Java source
version
Reviewed-by: darcy
---
.../testLinkPlatform/TestLinkPlatform.java | 23 +++++++++++++++----
.../testLinkPlatform/linkplatform.properties | 10 --------
2 files changed, 18 insertions(+), 15 deletions(-)
delete mode 100644 test/langtools/jdk/javadoc/doclet/testLinkPlatform/linkplatform.properties
diff --git a/test/langtools/jdk/javadoc/doclet/testLinkPlatform/TestLinkPlatform.java b/test/langtools/jdk/javadoc/doclet/testLinkPlatform/TestLinkPlatform.java
index d036b9046a6af..76bc7dc94da31 100644
--- a/test/langtools/jdk/javadoc/doclet/testLinkPlatform/TestLinkPlatform.java
+++ b/test/langtools/jdk/javadoc/doclet/testLinkPlatform/TestLinkPlatform.java
@@ -30,7 +30,7 @@
* jdk.javadoc/jdk.javadoc.internal.tool
* jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
- * @build javadoc.tester.*
+ * @build toolbox.ToolBox javadoc.tester.*
* @run main TestLinkPlatform
*/
@@ -55,8 +55,8 @@ public class TestLinkPlatform extends JavadocTester {
final static String NEW_PLATFORM_URL = "https://docs.oracle.com/en/java/javase/%d/docs/api/java.base/java/lang/Object.html";
final static String PRE_PLATFORM_URL = "https://download.java.net/java/early_access/jdk%d/docs/api/java.base/java/lang/Object.html";
- final static String NON_MODULAR_CUSTOM_PLATFORM_URL = "https://some.domain/docs/%d/api/java/lang/Object.html";
- final static String MODULAR_CUSTOM_PLATFORM_URL = "https://some.domain/docs/%d/api/java.base/java/lang/Object.html";
+ final static String NON_MODULAR_CUSTOM_PLATFORM_URL = "https://example.com/%d/api/java/lang/Object.html";
+ final static String MODULAR_CUSTOM_PLATFORM_URL = "https://example.com/%d/api/java.base/java/lang/Object.html";
final static int EARLIEST_VERSION = 7;
final static int LATEST_VERSION = Integer.parseInt(SourceVersion.latest().name().substring(8));
@@ -113,13 +113,14 @@ private void testPlatformLinkWithSupportedVersions(Path base, String versionOpti
@Test
public void testPlatformLinkWithCustomPropertyURL(Path base) throws Exception {
+ Path customProps = writeCustomProperties(base);
for (int version = EARLIEST_VERSION; version <= LATEST_VERSION; version++) {
Path out = base.resolve("out_" + version);
javadoc("-d", out.toString(),
"-sourcepath", packageSrc.toString(),
"--release", Integer.toString(version),
- "--link-platform-properties", "file:" + testSrc("linkplatform.properties"),
+ "--link-platform-properties", customProps.toUri().toString(),
"p.q");
checkExit(Exit.OK);
@@ -134,13 +135,14 @@ public void testPlatformLinkWithCustomPropertyURL(Path base) throws Exception {
@Test
public void testPlatformLinkWithCustomPropertyFile(Path base) throws Exception {
+ Path customProps = writeCustomProperties(base);
for (int version = EARLIEST_VERSION; version <= LATEST_VERSION; version++) {
Path out = base.resolve("out_" + version);
javadoc("-d", out.toString(),
"-sourcepath", packageSrc.toString(),
"--release", Integer.toString(version),
- "--link-platform-properties", testSrc("linkplatform.properties"),
+ "--link-platform-properties", customProps.toString(),
"p.q");
checkExit(Exit.OK);
@@ -153,6 +155,17 @@ public void testPlatformLinkWithCustomPropertyFile(Path base) throws Exception {
}
}
+ private Path writeCustomProperties(Path base) throws IOException {
+ ToolBox tb = new ToolBox();
+ StringBuilder sb = new StringBuilder();
+ for (int version = EARLIEST_VERSION; version <= LATEST_VERSION; version++) {
+ sb.append(String.format("doclet.platform.docs.%1$d= https://example.com/%1$d/api/\n", version));
+ }
+ Path path = base.resolve("linkplatform.properties");
+ tb.writeFile(path, sb.toString());
+ return path;
+ }
+
@Test
public void testPlatformLinkWithInvalidPropertyFile(Path base) throws Exception {
for (int version = EARLIEST_VERSION; version <= LATEST_VERSION; version++) {
diff --git a/test/langtools/jdk/javadoc/doclet/testLinkPlatform/linkplatform.properties b/test/langtools/jdk/javadoc/doclet/testLinkPlatform/linkplatform.properties
deleted file mode 100644
index e77d2ffb11bff..0000000000000
--- a/test/langtools/jdk/javadoc/doclet/testLinkPlatform/linkplatform.properties
+++ /dev/null
@@ -1,10 +0,0 @@
-doclet.platform.docs.7= https://some.domain/docs/7/api/
-doclet.platform.docs.8= https://some.domain/docs/8/api/
-doclet.platform.docs.9= https://some.domain/docs/9/api/
-doclet.platform.docs.10=https://some.domain/docs/10/api/
-doclet.platform.docs.11=https://some.domain/docs/11/api/
-doclet.platform.docs.12=https://some.domain/docs/12/api/
-doclet.platform.docs.13=https://some.domain/docs/13/api/
-doclet.platform.docs.14=https://some.domain/docs/14/api/
-doclet.platform.docs.15=https://some.domain/docs/15/api/
-doclet.platform.docs.16=https://some.domain/docs/16/api/
From 4169d96e249bee6e9c467d4f1d27da533321a8d9 Mon Sep 17 00:00:00 2001
From: Nick Gasson
Date: Thu, 3 Dec 2020 07:26:10 +0000
Subject: [PATCH 037/504] 8257143: Enable JVMCI code installation tests on
AArch64
Reviewed-by: burban, kvn
---
src/hotspot/cpu/aarch64/relocInfo_aarch64.hpp | 6 +-
.../vm/ci/code/test/CodeInstallationTest.java | 12 +
.../jdk/vm/ci/code/test/DataPatchTest.java | 5 +-
.../code/test/InterpreterFrameSizeTest.java | 5 +-
.../code/test/MaxOopMapStackOffsetTest.java | 5 +-
.../jdk/vm/ci/code/test/NativeCallTest.java | 5 +-
.../code/test/SimpleCodeInstallationTest.java | 5 +-
.../vm/ci/code/test/SimpleDebugInfoTest.java | 5 +-
.../code/test/VirtualObjectDebugInfoTest.java | 5 +-
.../test/aarch64/AArch64TestAssembler.java | 537 ++++++++++++++++++
10 files changed, 573 insertions(+), 17 deletions(-)
create mode 100644 test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/aarch64/AArch64TestAssembler.java
diff --git a/src/hotspot/cpu/aarch64/relocInfo_aarch64.hpp b/src/hotspot/cpu/aarch64/relocInfo_aarch64.hpp
index 13375e739d005..7708b4423e048 100644
--- a/src/hotspot/cpu/aarch64/relocInfo_aarch64.hpp
+++ b/src/hotspot/cpu/aarch64/relocInfo_aarch64.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2020, 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.
*
@@ -31,8 +31,8 @@
enum {
// Relocations are byte-aligned.
offset_unit = 1,
- // We don't use format().
- format_width = 0
+ // Must be at least 1 for RelocInfo::narrow_oop_in_const.
+ format_width = 1
};
public:
diff --git a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/CodeInstallationTest.java b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/CodeInstallationTest.java
index 5af14226e525f..d7ecc7c04ef06 100644
--- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/CodeInstallationTest.java
+++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/CodeInstallationTest.java
@@ -22,12 +22,15 @@
*/
package jdk.vm.ci.code.test;
+import jdk.vm.ci.aarch64.AArch64;
import jdk.vm.ci.amd64.AMD64;
import jdk.vm.ci.code.Architecture;
import jdk.vm.ci.code.CodeCacheProvider;
import jdk.vm.ci.code.InstalledCode;
import jdk.vm.ci.code.TargetDescription;
+import jdk.vm.ci.code.test.aarch64.AArch64TestAssembler;
import jdk.vm.ci.code.test.amd64.AMD64TestAssembler;
+import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider;
import jdk.vm.ci.hotspot.HotSpotCompiledCode;
import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
@@ -44,6 +47,8 @@
*/
public class CodeInstallationTest {
+ private static final boolean DEBUG = false;
+
protected final MetaAccessProvider metaAccess;
protected final CodeCacheProvider codeCache;
protected final TargetDescription target;
@@ -68,6 +73,8 @@ private TestAssembler createAssembler() {
Architecture arch = codeCache.getTarget().arch;
if (arch instanceof AMD64) {
return new AMD64TestAssembler(codeCache, config);
+ } else if (arch instanceof AArch64) {
+ return new AArch64TestAssembler(codeCache, config);
} else {
Assert.fail("unsupported architecture");
return null;
@@ -95,6 +102,11 @@ protected void test(TestCompiler compiler, Method method, Object... args) {
HotSpotCompiledCode code = asm.finish(resolvedMethod);
InstalledCode installed = codeCache.addCode(resolvedMethod, code, null, null);
+ if (DEBUG) {
+ String str = ((HotSpotCodeCacheProvider) codeCache).disassemble(installed);
+ System.out.println(str);
+ }
+
Object expected = method.invoke(null, args);
Object actual = installed.executeVarargs(args);
Assert.assertEquals(expected, actual);
diff --git a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/DataPatchTest.java b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/DataPatchTest.java
index c9710a11811c9..2e3f90368b10e 100644
--- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/DataPatchTest.java
+++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/DataPatchTest.java
@@ -24,15 +24,16 @@
/**
* @test
* @requires vm.jvmci
- * @requires vm.simpleArch == "x64"
+ * @requires vm.simpleArch == "x64" | vm.simpleArch == "aarch64"
* @library /
* @modules jdk.internal.vm.ci/jdk.vm.ci.hotspot
* jdk.internal.vm.ci/jdk.vm.ci.meta
* jdk.internal.vm.ci/jdk.vm.ci.code
* jdk.internal.vm.ci/jdk.vm.ci.code.site
* jdk.internal.vm.ci/jdk.vm.ci.runtime
+ * jdk.internal.vm.ci/jdk.vm.ci.aarch64
* jdk.internal.vm.ci/jdk.vm.ci.amd64
- * @compile CodeInstallationTest.java DebugInfoTest.java TestAssembler.java TestHotSpotVMConfig.java amd64/AMD64TestAssembler.java
+ * @compile CodeInstallationTest.java DebugInfoTest.java TestAssembler.java TestHotSpotVMConfig.java amd64/AMD64TestAssembler.java aarch64/AArch64TestAssembler.java
* @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:-UseJVMCICompiler jdk.vm.ci.code.test.DataPatchTest
*/
diff --git a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/InterpreterFrameSizeTest.java b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/InterpreterFrameSizeTest.java
index d5b41ff1424db..b88832677eb50 100644
--- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/InterpreterFrameSizeTest.java
+++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/InterpreterFrameSizeTest.java
@@ -24,15 +24,16 @@
/**
* @test
* @requires vm.jvmci
- * @requires vm.simpleArch == "x64"
+ * @requires vm.simpleArch == "x64" | vm.simpleArch == "aarch64"
* @modules jdk.internal.vm.ci/jdk.vm.ci.hotspot
* jdk.internal.vm.ci/jdk.vm.ci.code
* jdk.internal.vm.ci/jdk.vm.ci.code.site
* jdk.internal.vm.ci/jdk.vm.ci.meta
* jdk.internal.vm.ci/jdk.vm.ci.runtime
* jdk.internal.vm.ci/jdk.vm.ci.common
+ * jdk.internal.vm.ci/jdk.vm.ci.aarch64
* jdk.internal.vm.ci/jdk.vm.ci.amd64
- * @compile CodeInstallationTest.java TestAssembler.java TestHotSpotVMConfig.java amd64/AMD64TestAssembler.java
+ * @compile CodeInstallationTest.java TestAssembler.java TestHotSpotVMConfig.java amd64/AMD64TestAssembler.java aarch64/AArch64TestAssembler.java
* @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:-UseJVMCICompiler jdk.vm.ci.code.test.InterpreterFrameSizeTest
*/
diff --git a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/MaxOopMapStackOffsetTest.java b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/MaxOopMapStackOffsetTest.java
index 2a92029b92ec4..f473d089a54a4 100644
--- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/MaxOopMapStackOffsetTest.java
+++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/MaxOopMapStackOffsetTest.java
@@ -24,7 +24,7 @@
/**
* @test
* @requires vm.jvmci
- * @requires vm.simpleArch == "x64"
+ * @requires vm.simpleArch == "x64" | vm.simpleArch == "aarch64"
* @library /
* @modules jdk.internal.vm.ci/jdk.vm.ci.hotspot
* jdk.internal.vm.ci/jdk.vm.ci.meta
@@ -32,8 +32,9 @@
* jdk.internal.vm.ci/jdk.vm.ci.code.site
* jdk.internal.vm.ci/jdk.vm.ci.common
* jdk.internal.vm.ci/jdk.vm.ci.runtime
+ * jdk.internal.vm.ci/jdk.vm.ci.aarch64
* jdk.internal.vm.ci/jdk.vm.ci.amd64
- * @compile CodeInstallationTest.java DebugInfoTest.java TestAssembler.java TestHotSpotVMConfig.java amd64/AMD64TestAssembler.java
+ * @compile CodeInstallationTest.java DebugInfoTest.java TestAssembler.java TestHotSpotVMConfig.java amd64/AMD64TestAssembler.java aarch64/AArch64TestAssembler.java
* @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:-UseJVMCICompiler jdk.vm.ci.code.test.MaxOopMapStackOffsetTest
*/
diff --git a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/NativeCallTest.java b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/NativeCallTest.java
index 26b3736ae7370..dce107095d54d 100644
--- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/NativeCallTest.java
+++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/NativeCallTest.java
@@ -24,7 +24,7 @@
/**
* @test
* @requires vm.jvmci
- * @requires vm.simpleArch == "x64"
+ * @requires vm.simpleArch == "x64" | vm.simpleArch == "aarch64"
* @library /test/lib /
* @modules jdk.internal.vm.ci/jdk.vm.ci.hotspot
* jdk.internal.vm.ci/jdk.vm.ci.code
@@ -32,8 +32,9 @@
* jdk.internal.vm.ci/jdk.vm.ci.meta
* jdk.internal.vm.ci/jdk.vm.ci.runtime
* jdk.internal.vm.ci/jdk.vm.ci.common
+ * jdk.internal.vm.ci/jdk.vm.ci.aarch64
* jdk.internal.vm.ci/jdk.vm.ci.amd64
- * @compile CodeInstallationTest.java TestHotSpotVMConfig.java NativeCallTest.java TestAssembler.java amd64/AMD64TestAssembler.java
+ * @compile CodeInstallationTest.java TestHotSpotVMConfig.java NativeCallTest.java TestAssembler.java amd64/AMD64TestAssembler.java aarch64/AArch64TestAssembler.java
* @run junit/othervm/native -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -Xbootclasspath/a:. jdk.vm.ci.code.test.NativeCallTest
*/
package jdk.vm.ci.code.test;
diff --git a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/SimpleCodeInstallationTest.java b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/SimpleCodeInstallationTest.java
index a84fd04d2cdad..e5fc53e8013f1 100644
--- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/SimpleCodeInstallationTest.java
+++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/SimpleCodeInstallationTest.java
@@ -24,15 +24,16 @@
/**
* @test
* @requires vm.jvmci
- * @requires vm.simpleArch == "x64"
+ * @requires vm.simpleArch == "x64" | vm.simpleArch == "aarch64"
* @library /
* @modules jdk.internal.vm.ci/jdk.vm.ci.hotspot
* jdk.internal.vm.ci/jdk.vm.ci.meta
* jdk.internal.vm.ci/jdk.vm.ci.code
* jdk.internal.vm.ci/jdk.vm.ci.code.site
* jdk.internal.vm.ci/jdk.vm.ci.runtime
+ * jdk.internal.vm.ci/jdk.vm.ci.aarch64
* jdk.internal.vm.ci/jdk.vm.ci.amd64
- * @compile CodeInstallationTest.java DebugInfoTest.java TestAssembler.java TestHotSpotVMConfig.java amd64/AMD64TestAssembler.java
+ * @compile CodeInstallationTest.java DebugInfoTest.java TestAssembler.java TestHotSpotVMConfig.java amd64/AMD64TestAssembler.java aarch64/AArch64TestAssembler.java
* @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:-UseJVMCICompiler jdk.vm.ci.code.test.SimpleCodeInstallationTest
*/
diff --git a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/SimpleDebugInfoTest.java b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/SimpleDebugInfoTest.java
index b588b37c1ec25..bfd611312a2af 100644
--- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/SimpleDebugInfoTest.java
+++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/SimpleDebugInfoTest.java
@@ -24,15 +24,16 @@
/**
* @test
* @requires vm.jvmci
- * @requires vm.simpleArch == "x64"
+ * @requires vm.simpleArch == "x64" | vm.simpleArch == "aarch64"
* @library /
* @modules jdk.internal.vm.ci/jdk.vm.ci.hotspot
* jdk.internal.vm.ci/jdk.vm.ci.meta
* jdk.internal.vm.ci/jdk.vm.ci.code
* jdk.internal.vm.ci/jdk.vm.ci.code.site
* jdk.internal.vm.ci/jdk.vm.ci.runtime
+ * jdk.internal.vm.ci/jdk.vm.ci.aarch64
* jdk.internal.vm.ci/jdk.vm.ci.amd64
- * @compile CodeInstallationTest.java DebugInfoTest.java TestAssembler.java TestHotSpotVMConfig.java amd64/AMD64TestAssembler.java
+ * @compile CodeInstallationTest.java DebugInfoTest.java TestAssembler.java TestHotSpotVMConfig.java amd64/AMD64TestAssembler.java aarch64/AArch64TestAssembler.java
* @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:-UseJVMCICompiler jdk.vm.ci.code.test.SimpleDebugInfoTest
*/
diff --git a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/VirtualObjectDebugInfoTest.java b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/VirtualObjectDebugInfoTest.java
index 50b3a54fbbdbb..1fb0d77eb73ca 100644
--- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/VirtualObjectDebugInfoTest.java
+++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/VirtualObjectDebugInfoTest.java
@@ -24,15 +24,16 @@
/**
* @test
* @requires vm.jvmci
- * @requires vm.simpleArch == "x64"
+ * @requires vm.simpleArch == "x64" | vm.simpleArch == "aarch64"
* @library /
* @modules jdk.internal.vm.ci/jdk.vm.ci.hotspot
* jdk.internal.vm.ci/jdk.vm.ci.meta
* jdk.internal.vm.ci/jdk.vm.ci.code
* jdk.internal.vm.ci/jdk.vm.ci.code.site
* jdk.internal.vm.ci/jdk.vm.ci.runtime
+ * jdk.internal.vm.ci/jdk.vm.ci.aarch64
* jdk.internal.vm.ci/jdk.vm.ci.amd64
- * @compile CodeInstallationTest.java DebugInfoTest.java TestAssembler.java TestHotSpotVMConfig.java amd64/AMD64TestAssembler.java
+ * @compile CodeInstallationTest.java DebugInfoTest.java TestAssembler.java TestHotSpotVMConfig.java amd64/AMD64TestAssembler.java aarch64/AArch64TestAssembler.java
* @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:-UseJVMCICompiler jdk.vm.ci.code.test.VirtualObjectDebugInfoTest
*/
diff --git a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/aarch64/AArch64TestAssembler.java b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/aarch64/AArch64TestAssembler.java
new file mode 100644
index 0000000000000..b71d2397f7152
--- /dev/null
+++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/aarch64/AArch64TestAssembler.java
@@ -0,0 +1,537 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 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
+ * 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.vm.ci.code.test.aarch64;
+
+import jdk.vm.ci.aarch64.AArch64;
+import jdk.vm.ci.aarch64.AArch64Kind;
+import jdk.vm.ci.code.CallingConvention;
+import jdk.vm.ci.code.CodeCacheProvider;
+import jdk.vm.ci.code.DebugInfo;
+import jdk.vm.ci.code.Register;
+import jdk.vm.ci.code.RegisterValue;
+import jdk.vm.ci.code.StackSlot;
+import jdk.vm.ci.code.site.ConstantReference;
+import jdk.vm.ci.code.site.DataSectionReference;
+import jdk.vm.ci.code.test.TestAssembler;
+import jdk.vm.ci.code.test.TestHotSpotVMConfig;
+import jdk.vm.ci.hotspot.HotSpotCallingConventionType;
+import jdk.vm.ci.hotspot.HotSpotConstant;
+import jdk.vm.ci.hotspot.HotSpotForeignCallTarget;
+import jdk.vm.ci.meta.AllocatableValue;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.VMConstant;
+
+public class AArch64TestAssembler extends TestAssembler {
+
+ private static final Register scratchRegister = AArch64.rscratch1;
+ private static final Register doubleScratch = AArch64.v9;
+
+ public AArch64TestAssembler(CodeCacheProvider codeCache, TestHotSpotVMConfig config) {
+ super(codeCache, config,
+ 16 /* initialFrameSize */, 16 /* stackAlignment */,
+ AArch64Kind.DWORD /* narrowOopKind */,
+ /* registers */
+ AArch64.r0, AArch64.r1, AArch64.r2, AArch64.r3,
+ AArch64.r4, AArch64.r5, AArch64.r6, AArch64.r7);
+ }
+
+ private static int f(int val, int msb, int lsb) {
+ int nbits = msb - lsb + 1;
+ assert val >= 0;
+ assert val < (1 << nbits);
+ assert msb >= lsb;
+ return val << lsb;
+ }
+
+ private static int f(Register r, int msb, int lsb) {
+ assert msb - lsb == 4;
+ return f(r.encoding, msb, lsb);
+ }
+
+ private void emitNop() {
+ code.emitInt(0xd503201f);
+ }
+
+ private void emitAdd(Register Rd, Register Rn, Register Rm) {
+ // ADD (shifted register)
+ code.emitInt(f(0b10001011000, 31, 21)
+ | f(Rm, 20, 16)
+ | f(0, 15, 10)
+ | f(Rn, 9, 5)
+ | f(Rd, 4, 0));
+ }
+
+ private void emitAdd(Register Rd, Register Rn, int imm12) {
+ // ADD (immediate)
+ code.emitInt(f(0b1001000100, 31, 22)
+ | f(imm12, 21, 10)
+ | f(Rn, 9, 5)
+ | f(Rd, 4, 0));
+ }
+
+ private void emitSub(Register Rd, Register Rn, int imm12) {
+ // SUB (immediate)
+ code.emitInt(f(0b1101000100, 31, 22)
+ | f(imm12, 21, 10)
+ | f(Rn, 9, 5)
+ | f(Rd, 4, 0));
+ }
+
+ private void emitSub(Register Rd, Register Rn, Register Rm) {
+ // SUB (extended register)
+ code.emitInt(f(0b11001011001, 31, 21)
+ | f(Rm, 20, 16)
+ | f(0b011000, 15, 10)
+ | f(Rn, 9, 5)
+ | f(Rd, 4, 0));
+ }
+
+ private void emitMov(Register Rd, Register Rm) {
+ // MOV (register)
+ code.emitInt(f(0b10101010000, 31, 21)
+ | f(Rm, 20, 16)
+ | f(0, 15, 10)
+ | f(AArch64.zr, 9, 5)
+ | f(Rd, 4, 0));
+ }
+
+ private void emitMovz(Register Rd, int imm16, int shift) {
+ // MOVZ
+ int hw = 0;
+ switch (shift) {
+ case 0: hw = 0; break;
+ case 16: hw = 1; break;
+ case 32: hw = 2; break;
+ case 48: hw = 3; break;
+ default: throw new IllegalArgumentException();
+ }
+ code.emitInt(f(0b110100101, 31, 23)
+ | f(hw, 22, 21)
+ | f(imm16, 20, 5)
+ | f(Rd, 4, 0));
+ }
+
+ private void emitMovk(Register Rd, int imm16, int shift) {
+ // MOVK
+ int hw = 0;
+ switch (shift) {
+ case 0: hw = 0; break;
+ case 16: hw = 1; break;
+ case 32: hw = 2; break;
+ case 48: hw = 3; break;
+ default: throw new IllegalArgumentException();
+ }
+ code.emitInt(f(0b111100101, 31, 23)
+ | f(hw, 22, 21)
+ | f(imm16, 20, 5)
+ | f(Rd, 4, 0));
+ }
+
+ private void emitShiftLeft(Register Rd, Register Rn, int shift) {
+ // LSL (immediate)
+ code.emitInt(f(0b1101001101, 31, 22)
+ | f(-shift & 0b111111, 21, 16)
+ | f(63 - shift, 15, 10)
+ | f(Rn, 9, 5)
+ | f(Rd, 4, 0));
+ }
+
+ private void emitLoadRegister(Register Rt, AArch64Kind kind, int offset) {
+ // LDR (literal)
+ int opc = 0;
+ switch (kind) {
+ case DWORD: opc = 0; break;
+ case QWORD: opc = 1; break;
+ default: throw new IllegalArgumentException();
+ }
+ code.emitInt(f(opc, 31, 30)
+ | f(0b011000, 29, 24)
+ | f(offset, 23, 5)
+ | f(Rt, 4, 0));
+ }
+
+ private void emitLoadRegister(Register Rt, AArch64Kind kind, Register Rn, int offset) {
+ // LDR (immediate)
+ assert offset >= 0;
+ int size = 0;
+ switch (kind) {
+ case DWORD: size = 0b10; break;
+ case QWORD: size = 0b11; break;
+ default: throw new IllegalArgumentException();
+ }
+ code.emitInt(f(size, 31, 30)
+ | f(0b11100101, 29, 22)
+ | f(offset >> size, 21, 10)
+ | f(Rn, 9, 5)
+ | f(Rt, 4, 0));
+ }
+
+ private void emitStoreRegister(Register Rt, AArch64Kind kind, Register Rn, int offset) {
+ // STR (immediate)
+ assert offset >= 0;
+ int size = 0, fp = 0;
+ switch (kind) {
+ case DWORD: size = 0b10; fp = 0; break;
+ case QWORD: size = 0b11; fp = 0; break;
+ case SINGLE: size = 0b10; fp = 1; break;
+ case DOUBLE: size = 0b11; fp = 1; break;
+ default: throw new IllegalArgumentException();
+ }
+ code.emitInt(f(size, 31, 30)
+ | f(0b111, 29, 27)
+ | f(fp, 26, 26)
+ | f(0b0100, 25, 22)
+ | f(offset >> size, 21, 10)
+ | f(Rn, 9, 5)
+ | f(Rt, 4, 0));
+ }
+
+ private void emitBlr(Register Rn) {
+ // BLR
+ code.emitInt(f(0b1101011000111111000000, 31, 10)
+ | f(Rn, 9, 5)
+ | f(0, 4, 0));
+ }
+
+ private void emitFmov(Register Rd, AArch64Kind kind, Register Rn) {
+ // FMOV (general)
+ int ftype = 0, sf = 0;
+ switch (kind) {
+ case SINGLE: sf = 0; ftype = 0b00; break;
+ case DOUBLE: sf = 1; ftype = 0b01; break;
+ default: throw new IllegalArgumentException();
+ }
+ code.emitInt(f(sf, 31, 31)
+ | f(0b0011110, 30, 24)
+ | f(ftype, 23, 22)
+ | f(0b100111, 21, 16)
+ | f(0, 15, 10)
+ | f(Rn, 9, 5)
+ | f(Rd, 4, 0));
+ }
+
+ @Override
+ public void emitGrowStack(int size) {
+ assert size % 16 == 0;
+ if (size > -4096 && size < 0) {
+ emitAdd(AArch64.sp, AArch64.sp, -size);
+ } else if (size == 0) {
+ // No-op
+ } else if (size < 4096) {
+ emitSub(AArch64.sp, AArch64.sp, size);
+ } else if (size < 65535) {
+ emitMovz(scratchRegister, size & 0xffff, 0);
+ emitMovk(scratchRegister, (size >> 16) & 0xffff, 16);
+ emitSub(AArch64.sp, AArch64.sp, scratchRegister);
+ } else {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ @Override
+ public void emitPrologue() {
+ // Must be patchable by NativeJump::patch_verified_entry
+ emitNop();
+ code.emitInt(0xa9be7bfd); // stp x29, x30, [sp, #-32]!
+ code.emitInt(0x910003fd); // mov x29, sp
+
+ setDeoptRescueSlot(newStackSlot(AArch64Kind.QWORD));
+ }
+
+ @Override
+ public void emitEpilogue() {
+ recordMark(config.MARKID_DEOPT_HANDLER_ENTRY);
+ recordCall(new HotSpotForeignCallTarget(config.handleDeoptStub), 5, true, null);
+ code.emitInt(0x94000000); // bl
+ }
+
+ @Override
+ public void emitCallPrologue(CallingConvention cc, Object... prim) {
+ emitGrowStack(cc.getStackSize());
+ frameSize += cc.getStackSize();
+ AllocatableValue[] args = cc.getArguments();
+ for (int i = 0; i < args.length; i++) {
+ emitLoad(args[i], prim[i]);
+ }
+ }
+
+ @Override
+ public void emitCallEpilogue(CallingConvention cc) {
+ emitGrowStack(-cc.getStackSize());
+ frameSize -= cc.getStackSize();
+ }
+
+ @Override
+ public void emitCall(long addr) {
+ emitLoadLong(scratchRegister, addr);
+ emitBlr(scratchRegister);
+ }
+
+ @Override
+ public void emitLoad(AllocatableValue av, Object prim) {
+ if (av instanceof RegisterValue) {
+ Register reg = ((RegisterValue) av).getRegister();
+ if (prim instanceof Float) {
+ emitLoadFloat(reg, (Float) prim);
+ } else if (prim instanceof Double) {
+ emitLoadDouble(reg, (Double) prim);
+ } else if (prim instanceof Integer) {
+ emitLoadInt(reg, (Integer) prim);
+ } else if (prim instanceof Long) {
+ emitLoadLong(reg, (Long) prim);
+ }
+ } else if (av instanceof StackSlot) {
+ StackSlot slot = (StackSlot) av;
+ if (prim instanceof Float) {
+ emitFloatToStack(slot, emitLoadFloat(doubleScratch, (Float) prim));
+ } else if (prim instanceof Double) {
+ emitDoubleToStack(slot, emitLoadDouble(doubleScratch, (Double) prim));
+ } else if (prim instanceof Integer) {
+ emitIntToStack(slot, emitLoadInt(scratchRegister, (Integer) prim));
+ } else if (prim instanceof Long) {
+ emitLongToStack(slot, emitLoadLong(scratchRegister, (Long) prim));
+ } else {
+ assert false : "Unimplemented";
+ }
+ } else {
+ throw new IllegalArgumentException("Unknown value " + av);
+ }
+ }
+
+ @Override
+ public Register emitLoadPointer(HotSpotConstant c) {
+ recordDataPatchInCode(new ConstantReference((VMConstant) c));
+
+ Register ret = newRegister();
+ if (c.isCompressed()) {
+ // Set upper 16 bits first. See MacroAssembler::patch_oop().
+ emitMovz(ret, 0xdead, 16);
+ emitMovk(ret, 0xdead, 0);
+ } else {
+ // 48-bit VA
+ emitMovz(ret, 0xdead, 0);
+ emitMovk(ret, 0xdead, 16);
+ emitMovk(ret, 0xdead, 32);
+ }
+ return ret;
+ }
+
+ @Override
+ public Register emitLoadPointer(Register b, int offset) {
+ Register ret = newRegister();
+ emitLoadRegister(ret, AArch64Kind.QWORD, b, offset);
+ return ret;
+ }
+
+ @Override
+ public Register emitLoadNarrowPointer(DataSectionReference ref) {
+ recordDataPatchInCode(ref);
+
+ Register ret = newRegister();
+ emitLoadRegister(ret, AArch64Kind.DWORD, 0xdead);
+ return ret;
+ }
+
+ @Override
+ public Register emitLoadPointer(DataSectionReference ref) {
+ recordDataPatchInCode(ref);
+
+ Register ret = newRegister();
+ emitLoadRegister(ret, AArch64Kind.QWORD, 0xdead);
+ return ret;
+ }
+
+ private Register emitLoadDouble(Register reg, double c) {
+ DataSectionReference ref = new DataSectionReference();
+ ref.setOffset(data.position());
+ data.emitDouble(c);
+
+ recordDataPatchInCode(ref);
+ emitLoadRegister(scratchRegister, AArch64Kind.QWORD, 0xdead);
+ emitFmov(reg, AArch64Kind.DOUBLE, scratchRegister);
+ return reg;
+ }
+
+ private Register emitLoadFloat(Register reg, float c) {
+ DataSectionReference ref = new DataSectionReference();
+ ref.setOffset(data.position());
+ data.emitFloat(c);
+
+ recordDataPatchInCode(ref);
+ emitLoadRegister(scratchRegister, AArch64Kind.DWORD, 0xdead);
+ emitFmov(reg, AArch64Kind.SINGLE, scratchRegister);
+ return reg;
+ }
+
+ @Override
+ public Register emitLoadFloat(float c) {
+ Register ret = AArch64.v0;
+ return emitLoadFloat(ret, c);
+ }
+
+ private Register emitLoadLong(Register reg, long c) {
+ emitMovz(reg, (int)(c & 0xffff), 0);
+ emitMovk(reg, (int)((c >> 16) & 0xffff), 16);
+ emitMovk(reg, (int)((c >> 32) & 0xffff), 32);
+ emitMovk(reg, (int)((c >> 48) & 0xffff), 48);
+ return reg;
+ }
+
+ @Override
+ public Register emitLoadLong(long c) {
+ Register ret = newRegister();
+ return emitLoadLong(ret, c);
+ }
+
+ private Register emitLoadInt(Register reg, int c) {
+ emitMovz(reg, (int)(c & 0xffff), 0);
+ emitMovk(reg, (int)((c >> 16) & 0xffff), 16);
+ return reg;
+ }
+
+ @Override
+ public Register emitLoadInt(int c) {
+ Register ret = newRegister();
+ return emitLoadInt(ret, c);
+ }
+
+ @Override
+ public Register emitIntArg0() {
+ return codeCache.getRegisterConfig()
+ .getCallingConventionRegisters(HotSpotCallingConventionType.JavaCall, JavaKind.Int)
+ .get(0);
+ }
+
+ @Override
+ public Register emitIntArg1() {
+ return codeCache.getRegisterConfig()
+ .getCallingConventionRegisters(HotSpotCallingConventionType.JavaCall, JavaKind.Int)
+ .get(1);
+ }
+
+ @Override
+ public Register emitIntAdd(Register a, Register b) {
+ emitAdd(a, a, b);
+ return a;
+ }
+
+ @Override
+ public void emitTrap(DebugInfo info) {
+ // Dereference null pointer
+ emitMovz(scratchRegister, 0, 0);
+ recordImplicitException(info);
+ emitLoadRegister(AArch64.zr, AArch64Kind.QWORD, scratchRegister, 0);
+ }
+
+ @Override
+ public void emitIntRet(Register a) {
+ emitMov(AArch64.r0, a);
+ code.emitInt(0x910003bf); // mov sp, x29
+ code.emitInt(0xa8c27bfd); // ldp x29, x30, [sp], #32
+ code.emitInt(0xd65f03c0); // ret
+ }
+
+ @Override
+ public void emitFloatRet(Register a) {
+ assert a == AArch64.v0 : "Unimplemented move " + a;
+ code.emitInt(0x910003bf); // mov sp, x29
+ code.emitInt(0xa8c27bfd); // ldp x29, x30, [sp], #32
+ code.emitInt(0xd65f03c0); // ret
+ }
+
+ @Override
+ public void emitPointerRet(Register a) {
+ emitIntRet(a);
+ }
+
+ @Override
+ public StackSlot emitPointerToStack(Register a) {
+ return emitLongToStack(a);
+ }
+
+ @Override
+ public StackSlot emitNarrowPointerToStack(Register a) {
+ return emitIntToStack(a);
+ }
+
+ @Override
+ public Register emitUncompressPointer(Register compressed, long base, int shift) {
+ if (shift > 0) {
+ emitShiftLeft(compressed, compressed, shift);
+ }
+
+ if (base != 0) {
+ emitLoadLong(scratchRegister, base);
+ emitAdd(compressed, compressed, scratchRegister);
+ }
+
+ return compressed;
+ }
+
+ private StackSlot emitDoubleToStack(StackSlot slot, Register a) {
+ emitStoreRegister(a, AArch64Kind.DOUBLE, AArch64.sp, slot.getOffset(frameSize));
+ return slot;
+ }
+
+ @Override
+ public StackSlot emitDoubleToStack(Register a) {
+ StackSlot ret = newStackSlot(AArch64Kind.DOUBLE);
+ return emitDoubleToStack(ret, a);
+ }
+
+ private StackSlot emitFloatToStack(StackSlot slot, Register a) {
+ emitStoreRegister(a, AArch64Kind.SINGLE, AArch64.sp, slot.getOffset(frameSize));
+ return slot;
+ }
+
+ @Override
+ public StackSlot emitFloatToStack(Register a) {
+ StackSlot ret = newStackSlot(AArch64Kind.SINGLE);
+ return emitFloatToStack(ret, a);
+ }
+
+ private StackSlot emitIntToStack(StackSlot slot, Register a) {
+ emitStoreRegister(a, AArch64Kind.DWORD, AArch64.sp, slot.getOffset(frameSize));
+ return slot;
+ }
+
+ @Override
+ public StackSlot emitIntToStack(Register a) {
+ StackSlot ret = newStackSlot(AArch64Kind.DWORD);
+ return emitIntToStack(ret, a);
+ }
+
+ private StackSlot emitLongToStack(StackSlot slot, Register a) {
+ emitStoreRegister(a, AArch64Kind.QWORD, AArch64.sp, slot.getOffset(frameSize));
+ return slot;
+ }
+
+ @Override
+ public StackSlot emitLongToStack(Register a) {
+ StackSlot ret = newStackSlot(AArch64Kind.QWORD);
+ return emitLongToStack(ret, a);
+ }
+
+}
From ae1eb286c6a2e76c3b38d68641208d4c01d4eef8 Mon Sep 17 00:00:00 2001
From: Thomas Stuefe
Date: Thu, 3 Dec 2020 07:50:19 +0000
Subject: [PATCH 038/504] 8257604: JNI_ArgumentPusherVaArg leaks valist
Reviewed-by: dcubed, coleenp
---
src/hotspot/share/prims/jni.cpp | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/hotspot/share/prims/jni.cpp b/src/hotspot/share/prims/jni.cpp
index c400456f2efd5..bdf03279580b2 100644
--- a/src/hotspot/share/prims/jni.cpp
+++ b/src/hotspot/share/prims/jni.cpp
@@ -870,7 +870,6 @@ class JNI_ArgumentPusher : public SignatureIterator {
class JNI_ArgumentPusherVaArg : public JNI_ArgumentPusher {
- protected:
va_list _ap;
void set_ap(va_list rap) {
@@ -906,6 +905,10 @@ class JNI_ArgumentPusherVaArg : public JNI_ArgumentPusher {
set_ap(rap);
}
+ ~JNI_ArgumentPusherVaArg() {
+ va_end(_ap);
+ }
+
virtual void push_arguments_on(JavaCallArguments* arguments) {
_arguments = arguments;
do_parameters_on(this);
From b44a329f919a7d5c53a45584d3d681a30730731f Mon Sep 17 00:00:00 2001
From: Thomas Stuefe
Date: Thu, 3 Dec 2020 08:41:26 +0000
Subject: [PATCH 039/504] 8256864: [windows] Improve tracing for mapping errors
Reviewed-by: iklam, rrich
---
src/hotspot/os/windows/os_windows.cpp | 111 +++++++++++++++++++++----
src/hotspot/share/runtime/os.cpp | 5 ++
src/hotspot/share/runtime/os.hpp | 2 +
test/hotspot/gtest/runtime/test_os.cpp | 43 ++++++++--
4 files changed, 141 insertions(+), 20 deletions(-)
diff --git a/src/hotspot/os/windows/os_windows.cpp b/src/hotspot/os/windows/os_windows.cpp
index 3342ecf781756..32020da916db7 100644
--- a/src/hotspot/os/windows/os_windows.cpp
+++ b/src/hotspot/os/windows/os_windows.cpp
@@ -3215,9 +3215,10 @@ void os::split_reserved_memory(char *base, size_t size, size_t split) {
(attempt_reserve_memory_at(base, split) != NULL) &&
(attempt_reserve_memory_at(split_address, size - split) != NULL);
if (!rc) {
- log_warning(os)("os::split_reserved_memory failed for [" RANGE_FORMAT ")",
+ log_warning(os)("os::split_reserved_memory failed for " RANGE_FORMAT,
RANGE_FORMAT_ARGS(base, size));
- assert(false, "os::split_reserved_memory failed for [" RANGE_FORMAT ")",
+ os::print_memory_mappings(base, size, tty);
+ assert(false, "os::split_reserved_memory failed for " RANGE_FORMAT,
RANGE_FORMAT_ARGS(base, size));
}
@@ -5989,19 +5990,55 @@ bool os::win32::find_mapping(address addr, mapping_info_t* mi) {
return rc;
}
+// Helper for print_one_mapping: print n words, both as hex and ascii.
+// Use Safefetch for all values.
+static void print_snippet(const void* p, outputStream* st) {
+ static const int num_words = LP64_ONLY(3) NOT_LP64(6);
+ static const int num_bytes = num_words * sizeof(int);
+ intptr_t v[num_words];
+ const int errval = 0xDE210244;
+ for (int i = 0; i < num_words; i++) {
+ v[i] = SafeFetchN((intptr_t*)p + i, errval);
+ if (v[i] == errval &&
+ SafeFetchN((intptr_t*)p + i, ~errval) == ~errval) {
+ return;
+ }
+ }
+ st->put('[');
+ for (int i = 0; i < num_words; i++) {
+ st->print(INTPTR_FORMAT " ", v[i]);
+ }
+ const char* b = (char*)v;
+ st->put('\"');
+ for (int i = 0; i < num_bytes; i++) {
+ st->put(::isgraph(b[i]) ? b[i] : '.');
+ }
+ st->put('\"');
+ st->put(']');
+}
+
// Helper function for print_memory_mappings:
// Given a MEMORY_BASIC_INFORMATION, containing information about a non-free region:
// print out all regions in that allocation. If any of those regions
// fall outside the given range [start, end), indicate that in the output.
// Return the pointer to the end of the allocation.
static address print_one_mapping(MEMORY_BASIC_INFORMATION* minfo, address start, address end, outputStream* st) {
- assert(start != NULL && end != NULL && end > start, "Sanity");
+ // Print it like this:
+ //
+ // Base: : [xxxx - xxxx], state=MEM_xxx, prot=x, type=MEM_xxx (region 1)
+ // [xxxx - xxxx], state=MEM_xxx, prot=x, type=MEM_xxx (region 2)
assert(minfo->State != MEM_FREE, "Not inside an allocation.");
address allocation_base = (address)minfo->AllocationBase;
- address last_region_end = NULL;
- st->print_cr("AllocationBase: " PTR_FORMAT ":", allocation_base);
#define IS_IN(p) (p >= start && p < end)
+ bool first_line = true;
+ bool is_dll = false;
for(;;) {
+ if (first_line) {
+ st->print("Base " PTR_FORMAT ": ", p2i(allocation_base));
+ } else {
+ st->print_raw(NOT_LP64 (" ")
+ LP64_ONLY(" "));
+ }
address region_start = (address)minfo->BaseAddress;
address region_end = region_start + minfo->RegionSize;
assert(region_end > region_start, "Sanity");
@@ -6014,19 +6051,39 @@ static address print_one_mapping(MEMORY_BASIC_INFORMATION* minfo, address start,
}
st->print("[" PTR_FORMAT "-" PTR_FORMAT "), state=", p2i(region_start), p2i(region_end));
switch (minfo->State) {
- case MEM_COMMIT: st->print("MEM_COMMIT"); break;
- case MEM_FREE: st->print("MEM_FREE"); break;
- case MEM_RESERVE: st->print("MEM_RESERVE"); break;
+ case MEM_COMMIT: st->print_raw("MEM_COMMIT "); break;
+ case MEM_FREE: st->print_raw("MEM_FREE "); break;
+ case MEM_RESERVE: st->print_raw("MEM_RESERVE"); break;
default: st->print("%x?", (unsigned)minfo->State);
}
- st->print(", prot=%x, type=", (unsigned)minfo->AllocationProtect);
+ st->print(", prot=%3x, type=", (unsigned)minfo->Protect);
switch (minfo->Type) {
- case MEM_IMAGE: st->print("MEM_IMAGE"); break;
- case MEM_MAPPED: st->print("MEM_MAPPED"); break;
- case MEM_PRIVATE: st->print("MEM_PRIVATE"); break;
+ case MEM_IMAGE: st->print_raw("MEM_IMAGE "); break;
+ case MEM_MAPPED: st->print_raw("MEM_MAPPED "); break;
+ case MEM_PRIVATE: st->print_raw("MEM_PRIVATE"); break;
default: st->print("%x?", (unsigned)minfo->State);
}
+ // At the start of every allocation, print some more information about this mapping.
+ // Notes:
+ // - this could be beefed up a lot, similar to os::print_location
+ // - for now we just query the allocation start point. This may be confusing for cases where
+ // the kernel merges multiple mappings.
+ if (first_line) {
+ char buf[MAX_PATH];
+ if (os::dll_address_to_library_name(allocation_base, buf, sizeof(buf), nullptr)) {
+ st->print(", %s", buf);
+ is_dll = true;
+ }
+ }
+ // If memory is accessible, and we do not know anything else about it, print a snippet
+ if (!is_dll &&
+ minfo->State == MEM_COMMIT &&
+ !(minfo->Protect & PAGE_NOACCESS || minfo->Protect & PAGE_GUARD)) {
+ st->print_raw(", ");
+ print_snippet(region_start, st);
+ }
st->cr();
+ // Next region...
bool rc = checkedVirtualQuery(region_end, minfo);
if (rc == false || // VirtualQuery error, end of allocation?
(minfo->State == MEM_FREE) || // end of allocation, free memory follows
@@ -6035,6 +6092,7 @@ static address print_one_mapping(MEMORY_BASIC_INFORMATION* minfo, address start,
{
return region_end;
}
+ first_line = false;
}
#undef IS_IN
ShouldNotReachHere();
@@ -6046,7 +6104,14 @@ void os::print_memory_mappings(char* addr, size_t bytes, outputStream* st) {
address start = (address)addr;
address end = start + bytes;
address p = start;
- while (p < end) {
+ if (p == nullptr) { // Lets skip the zero pages.
+ p += os::vm_allocation_granularity();
+ }
+ address p2 = p; // guard against wraparounds
+ int fuse = 0;
+
+ while (p < end && p >= p2) {
+ p2 = p;
// Probe for the next mapping.
if (checkedVirtualQuery(p, &minfo)) {
if (minfo.State != MEM_FREE) {
@@ -6064,8 +6129,24 @@ void os::print_memory_mappings(char* addr, size_t bytes, outputStream* st) {
p = region_end;
}
} else {
- // advance probe pointer.
- p += os::vm_allocation_granularity();
+ // MSDN doc on VirtualQuery is unclear about what it means if it returns an error.
+ // In particular, whether querying an address outside any mappings would report
+ // a MEM_FREE region or just return an error. From experiments, it seems to return
+ // a MEM_FREE region for unmapped areas in valid address space and an error if we
+ // are outside valid address space.
+ // Here, we advance the probe pointer by alloc granularity. But if the range to print
+ // is large, this may take a long time. Therefore lets stop right away if the address
+ // is outside of what we know are valid addresses on Windows. Also, add a loop fuse.
+ static const address end_virt = (address)(LP64_ONLY(0x7ffffffffffULL) NOT_LP64(3*G));
+ if (p >= end_virt) {
+ break;
+ } else {
+ // Advance probe pointer, but with a fuse to break long loops.
+ if (fuse++ == 100000) {
+ break;
+ }
+ p += os::vm_allocation_granularity();
+ }
}
}
}
diff --git a/src/hotspot/share/runtime/os.cpp b/src/hotspot/share/runtime/os.cpp
index 4d702eb94699c..b228a0eecd33b 100644
--- a/src/hotspot/share/runtime/os.cpp
+++ b/src/hotspot/share/runtime/os.cpp
@@ -1737,6 +1737,11 @@ bool os::release_memory(char* addr, size_t bytes) {
return res;
}
+// Prints all mappings
+void os::print_memory_mappings(outputStream* st) {
+ os::print_memory_mappings(nullptr, (size_t)-1, st);
+}
+
void os::pretouch_memory(void* start, void* end, size_t page_size) {
for (volatile char *p = (char*)start; p < (char*)end; p += page_size) {
*p = 0;
diff --git a/src/hotspot/share/runtime/os.hpp b/src/hotspot/share/runtime/os.hpp
index e38e1a068b43c..56afb9d1ec021 100644
--- a/src/hotspot/share/runtime/os.hpp
+++ b/src/hotspot/share/runtime/os.hpp
@@ -349,6 +349,8 @@ class os: AllStatic {
// A diagnostic function to print memory mappings in the given range.
static void print_memory_mappings(char* addr, size_t bytes, outputStream* st);
+ // 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.
diff --git a/test/hotspot/gtest/runtime/test_os.cpp b/test/hotspot/gtest/runtime/test_os.cpp
index 4795a78407ec0..e7605baf6ef59 100644
--- a/test/hotspot/gtest/runtime/test_os.cpp
+++ b/test/hotspot/gtest/runtime/test_os.cpp
@@ -22,6 +22,7 @@
*/
#include "precompiled.hpp"
+#include "memory/allocation.hpp"
#include "memory/resourceArea.hpp"
#include "runtime/os.hpp"
#include "utilities/globalDefinitions.hpp"
@@ -494,11 +495,43 @@ TEST_VM(os, release_one_mapping_multi_commits) {
PRINT_MAPPINGS("D");
}
-TEST_VM(os, show_mappings_1) {
- // Display an arbitrary large address range. Make this works, does not hang, etc.
- char dummy[16 * K]; // silent truncation is fine, we don't care.
- stringStream ss(dummy, sizeof(dummy));
- os::print_memory_mappings((char*)0x1000, LP64_ONLY(1024) NOT_LP64(3) * G, &ss);
+static void test_show_mappings(address start, size_t size) {
+ // Note: should this overflow, thats okay. stream will silently truncate. Does not matter for the test.
+ const size_t buflen = 4 * M;
+ char* buf = NEW_C_HEAP_ARRAY(char, buflen, mtInternal);
+ buf[0] = '\0';
+ stringStream ss(buf, buflen);
+ if (start != nullptr) {
+ os::print_memory_mappings((char*)start, size, &ss);
+ } else {
+ os::print_memory_mappings(&ss); // prints full address space
+ }
+ // Still an empty implementation on MacOS and AIX
+#if defined(LINUX) || defined(_WIN32)
+ EXPECT_NE(buf[0], '\0');
+#endif
+ // buf[buflen - 1] = '\0';
+ // tty->print_raw(buf);
+ FREE_C_HEAP_ARRAY(char, buf);
+}
+
+TEST_VM(os, show_mappings_small_range) {
+ test_show_mappings((address)0x100000, 2 * G);
+}
+
+TEST_VM(os, show_mappings_full_range) {
+ // Reserve a small range and fill it with a marker string, should show up
+ // on implementations displaying range snippets
+ char* p = os::reserve_memory(1 * M, mtInternal);
+ if (p != nullptr) {
+ if (os::commit_memory(p, 1 * M, false)) {
+ strcpy(p, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
+ }
+ }
+ test_show_mappings(nullptr, 0);
+ if (p != nullptr) {
+ os::release_memory(p, 1 * M);
+ }
}
#ifdef _WIN32
From 4a267f1bc2b025aae2cb9df7283156aeb0282406 Mon Sep 17 00:00:00 2001
From: Richard Reingruber
Date: Thu, 3 Dec 2020 08:50:08 +0000
Subject: [PATCH 040/504] 8244847: Linux/PPC:
runtime/CompressedOops/CompressedClassPointers: smallHeapTest fails
Reviewed-by: stuefe, mdoerr
---
src/hotspot/share/memory/metaspace.cpp | 11 ++++++++++-
.../CompressedOops/CompressedClassPointers.java | 8 ++++++--
2 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/src/hotspot/share/memory/metaspace.cpp b/src/hotspot/share/memory/metaspace.cpp
index 6d1ada365b56a..4bd6118cfbb42 100644
--- a/src/hotspot/share/memory/metaspace.cpp
+++ b/src/hotspot/share/memory/metaspace.cpp
@@ -532,7 +532,7 @@ bool Metaspace::class_space_is_initialized() {
// On error, returns an unreserved space.
ReservedSpace Metaspace::reserve_address_space_for_compressed_classes(size_t size) {
-#ifdef AARCH64
+#if defined(AARCH64) || defined(PPC64)
const size_t alignment = Metaspace::reserve_alignment();
// AArch64: Try to align metaspace so that we can decode a compressed
@@ -542,6 +542,13 @@ ReservedSpace Metaspace::reserve_address_space_for_compressed_classes(size_t siz
// of the upper 32-bits of the address are zero so we can handle a shift
// when decoding.
+ // PPC64: smaller heaps up to 2g will be mapped just below 4g. Then the
+ // attempt to place the compressed class space just after the heap fails on
+ // Linux 4.1.42 and higher because the launcher is loaded at 4g
+ // (ELF_ET_DYN_BASE). In that case we reach here and search the address space
+ // below 32g to get a zerobased CCS. For simplicity we reuse the search
+ // strategy for AARCH64.
+
static const struct {
address from;
address to;
@@ -565,7 +572,9 @@ ReservedSpace Metaspace::reserve_address_space_for_compressed_classes(size_t siz
a += search_ranges[i].increment;
}
}
+#endif // defined(AARCH64) || defined(PPC64)
+#ifdef AARCH64
// Note: on AARCH64, if the code above does not find any good placement, we
// have no recourse. We return an empty space and the VM will exit.
return ReservedSpace();
diff --git a/test/hotspot/jtreg/runtime/CompressedOops/CompressedClassPointers.java b/test/hotspot/jtreg/runtime/CompressedOops/CompressedClassPointers.java
index ec46c128d7291..8c3bacfacb46b 100644
--- a/test/hotspot/jtreg/runtime/CompressedOops/CompressedClassPointers.java
+++ b/test/hotspot/jtreg/runtime/CompressedOops/CompressedClassPointers.java
@@ -44,7 +44,7 @@ public class CompressedClassPointers {
// Returns true if we are to test the narrow klass base; we only do this on
// platforms where we can be reasonably shure that we get reproducable placement).
static boolean testNarrowKlassBase() {
- if (Platform.isWindows() || Platform.isPPC()) {
+ if (Platform.isWindows()) {
return false;
}
return true;
@@ -98,7 +98,11 @@ public static void largeHeapTest() throws Exception {
"-Xshare:off",
"-XX:+VerifyBeforeGC", "-version");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
- if (testNarrowKlassBase()) {
+ if (testNarrowKlassBase() && !Platform.isAix()) {
+ // AIX: the heap cannot be placed below 32g. The first attempt to
+ // place the CCS behind the heap fails (luckily). Subsequently CCS
+ // is successfully placed below 32g. So we get 0x0 as narrow klass
+ // base.
output.shouldNotContain("Narrow klass base: 0x0000000000000000");
output.shouldContain("Narrow klass shift: 0");
}
From e4497c9e6969cbf0ba25526a49febda205abecfb Mon Sep 17 00:00:00 2001
From: Harold Seigel
Date: Thu, 3 Dec 2020 13:14:57 +0000
Subject: [PATCH 041/504] 8256718: Obsolete the long term deprecated and
aliased Trace flags
Reviewed-by: sspitsyn, iklam, dholmes, coleenp
---
.../cpu/aarch64/methodHandles_aarch64.cpp | 2 -
src/hotspot/cpu/x86/methodHandles_x86.cpp | 2 -
src/hotspot/share/oops/method.hpp | 2 +-
src/hotspot/share/runtime/arguments.cpp | 130 +++---------------
src/hotspot/share/runtime/arguments.hpp | 18 ---
src/hotspot/share/runtime/globals.hpp | 3 -
.../CommandLine/TraceExceptionsTest.java | 2 +-
.../runtime/cds/appcds/ClassPathAttr.java | 10 --
.../cds/appcds/IgnoreEmptyClassPaths.java | 6 +-
.../cds/appcds/javaldr/GCDuringDump.java | 2 +-
.../javaldr/GCSharedStringsDuringDump.java | 4 +-
.../appcds/javaldr/HumongousDuringDump.java | 2 +-
.../classpathtests/BootAppendTests.java | 2 +-
.../runtime/logging/BiasedLockingTest.java | 14 +-
.../runtime/logging/ClassLoadUnloadTest.java | 18 +--
.../runtime/logging/ClassResolutionTest.java | 16 +--
.../jtreg/runtime/logging/ExceptionsTest.java | 14 +-
.../logging/ExceptionsTest_options_file | 2 +-
.../logging/LoaderConstraintsTest.java | 13 +-
.../runtime/logging/MonitorInflationTest.java | 10 +-
.../logging/RemovedDevelopFlagsTest.java | 63 ---------
.../runtime/logging/SafepointCleanupTest.java | 8 --
test/jdk/com/sun/jdi/cds/CDSJDITest.java | 4 +-
23 files changed, 37 insertions(+), 310 deletions(-)
delete mode 100644 test/hotspot/jtreg/runtime/logging/RemovedDevelopFlagsTest.java
diff --git a/src/hotspot/cpu/aarch64/methodHandles_aarch64.cpp b/src/hotspot/cpu/aarch64/methodHandles_aarch64.cpp
index 82b1401e34b60..e60fb5539e68c 100644
--- a/src/hotspot/cpu/aarch64/methodHandles_aarch64.cpp
+++ b/src/hotspot/cpu/aarch64/methodHandles_aarch64.cpp
@@ -132,8 +132,6 @@ void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm,
assert(recv != noreg, "required register");
assert(method_temp == rmethod, "required register for loading method");
- //NOT_PRODUCT({ FlagSetting fs(TraceMethodHandles, true); trace_method_handle(_masm, "LZMH"); });
-
// Load the invoker, as MH -> MH.form -> LF.vmentry
__ verify_oop(recv);
__ load_heap_oop(method_temp, Address(recv, NONZERO(java_lang_invoke_MethodHandle::form_offset())), temp2);
diff --git a/src/hotspot/cpu/x86/methodHandles_x86.cpp b/src/hotspot/cpu/x86/methodHandles_x86.cpp
index b4c7d43c73275..298c5144a1575 100644
--- a/src/hotspot/cpu/x86/methodHandles_x86.cpp
+++ b/src/hotspot/cpu/x86/methodHandles_x86.cpp
@@ -168,8 +168,6 @@ void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm,
assert(recv != noreg, "required register");
assert(method_temp == rbx, "required register for loading method");
- //NOT_PRODUCT({ FlagSetting fs(TraceMethodHandles, true); trace_method_handle(_masm, "LZMH"); });
-
// Load the invoker, as MH -> MH.form -> LF.vmentry
__ verify_oop(recv);
__ load_heap_oop(method_temp, Address(recv, NONZERO(java_lang_invoke_MethodHandle::form_offset())), temp2);
diff --git a/src/hotspot/share/oops/method.hpp b/src/hotspot/share/oops/method.hpp
index f80ecdf369d05..38646672d5c8f 100644
--- a/src/hotspot/share/oops/method.hpp
+++ b/src/hotspot/share/oops/method.hpp
@@ -1009,7 +1009,7 @@ class Method : public Metadata {
// Printing
void print_short_name(outputStream* st = tty); // prints as klassname::methodname; Exposed so field engineers can debug VM
#if INCLUDE_JVMTI
- void print_name(outputStream* st = tty); // prints as "virtual void foo(int)"; exposed for TraceRedefineClasses
+ void print_name(outputStream* st = tty); // prints as "virtual void foo(int)"; exposed for -Xlog:redefine+class
#else
void print_name(outputStream* st = tty) PRODUCT_RETURN; // prints as "virtual void foo(int)"
#endif
diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp
index 357b7e7e3a82a..3b62a67deec49 100644
--- a/src/hotspot/share/runtime/arguments.cpp
+++ b/src/hotspot/share/runtime/arguments.cpp
@@ -557,6 +557,22 @@ static SpecialFlag const special_jvm_flags[] = {
{ "Debugging", JDK_Version::undefined(), JDK_Version::jdk(16), JDK_Version::jdk(17) },
{ "UseRDPCForConstantTableBase", JDK_Version::undefined(), JDK_Version::jdk(16), JDK_Version::jdk(17) },
{ "VerifyMergedCPBytecodes", JDK_Version::undefined(), JDK_Version::jdk(16), JDK_Version::jdk(17) },
+ { "PrintSharedSpaces", JDK_Version::undefined(), JDK_Version::jdk(16), JDK_Version::jdk(17) },
+ { "TraceBiasedLocking", JDK_Version::undefined(), JDK_Version::jdk(16), JDK_Version::jdk(17) },
+ { "TraceClassLoading", JDK_Version::undefined(), JDK_Version::jdk(16), JDK_Version::jdk(17) },
+ { "TraceClassLoadingPreorder", JDK_Version::undefined(), JDK_Version::jdk(16), JDK_Version::jdk(17) },
+ { "TraceClassPaths", JDK_Version::undefined(), JDK_Version::jdk(16), JDK_Version::jdk(17) },
+ { "TraceClassResolution", JDK_Version::undefined(), JDK_Version::jdk(16), JDK_Version::jdk(17) },
+ { "TraceClassUnloading", JDK_Version::undefined(), JDK_Version::jdk(16), JDK_Version::jdk(17) },
+ { "TraceExceptions", JDK_Version::undefined(), JDK_Version::jdk(16), JDK_Version::jdk(17) },
+ { "TraceInvokeDynamic", JDK_Version::undefined(), JDK_Version::jdk(16), JDK_Version::jdk(17) },
+ { "TraceLoaderConstraints", JDK_Version::undefined(), JDK_Version::jdk(16), JDK_Version::jdk(17) },
+ { "TraceMethodHandles", JDK_Version::undefined(), JDK_Version::jdk(16), JDK_Version::jdk(17) },
+ { "TraceMonitorInflation", JDK_Version::undefined(), JDK_Version::jdk(16), JDK_Version::jdk(17) },
+ { "TraceSafepointCleanupTime", JDK_Version::undefined(), JDK_Version::jdk(16), JDK_Version::jdk(17) },
+ { "TraceJVMTIObjectTagging", JDK_Version::undefined(), JDK_Version::jdk(16), JDK_Version::jdk(17) },
+ { "TraceRedefineClasses", JDK_Version::undefined(), JDK_Version::jdk(16), JDK_Version::jdk(17) },
+ { "PrintJNIResolving", JDK_Version::undefined(), JDK_Version::jdk(16), JDK_Version::jdk(17) },
#ifdef TEST_VERIFY_SPECIAL_JVM_FLAGS
// These entries will generate build errors. Their purpose is to test the macros.
@@ -584,44 +600,6 @@ static AliasedFlag const aliased_jvm_flags[] = {
{ NULL, NULL}
};
-// NOTE: A compatibility request will be necessary for each alias to be removed.
-static AliasedLoggingFlag const aliased_logging_flags[] = {
- { "PrintSharedSpaces", LogLevel::Info, true, LOG_TAGS(cds) },
- { "TraceBiasedLocking", LogLevel::Info, true, LOG_TAGS(biasedlocking) },
- { "TraceClassLoading", LogLevel::Info, true, LOG_TAGS(class, load) },
- { "TraceClassLoadingPreorder", LogLevel::Debug, true, LOG_TAGS(class, preorder) },
- { "TraceClassPaths", LogLevel::Info, true, LOG_TAGS(class, path) },
- { "TraceClassResolution", LogLevel::Debug, true, LOG_TAGS(class, resolve) },
- { "TraceClassUnloading", LogLevel::Info, true, LOG_TAGS(class, unload) },
- { "TraceExceptions", LogLevel::Info, true, LOG_TAGS(exceptions) },
- { "TraceInvokeDynamic", LogLevel::Debug, true, LOG_TAGS(methodhandles, indy) },
- { "TraceLoaderConstraints", LogLevel::Info, true, LOG_TAGS(class, loader, constraints) },
- { "TraceMethodHandles", LogLevel::Info, true, LOG_TAGS(methodhandles) },
- { "TraceMonitorInflation", LogLevel::Trace, true, LOG_TAGS(monitorinflation) },
- { "TraceSafepointCleanupTime", LogLevel::Info, true, LOG_TAGS(safepoint, cleanup) },
- { "TraceJVMTIObjectTagging", LogLevel::Debug, true, LOG_TAGS(jvmti, objecttagging) },
- { "TraceRedefineClasses", LogLevel::Info, false, LOG_TAGS(redefine, class) },
- { "PrintJNIResolving", LogLevel::Debug, true, LOG_TAGS(jni, resolve) },
- { NULL, LogLevel::Off, false, LOG_TAGS(_NO_TAG) }
-};
-
-#ifndef PRODUCT
-// These options are removed in jdk9. Remove this code for jdk10.
-static AliasedFlag const removed_develop_logging_flags[] = {
- { "TraceClassInitialization", "-Xlog:class+init" },
- { "TraceClassLoaderData", "-Xlog:class+loader+data" },
- { "TraceDefaultMethods", "-Xlog:defaultmethods=debug" },
- { "TraceItables", "-Xlog:itables=debug" },
- { "TraceMonitorMismatch", "-Xlog:monitormismatch=info" },
- { "TraceSafepoint", "-Xlog:safepoint=debug" },
- { "TraceStartupTime", "-Xlog:startuptime" },
- { "TraceVMOperation", "-Xlog:vmoperation=debug" },
- { "PrintVtables", "-Xlog:vtables=debug" },
- { "VerboseVerification", "-Xlog:verification" },
- { NULL, NULL }
-};
-#endif //PRODUCT
-
// Return true if "v" is less than "other", where "other" may be "undefined".
static bool version_less_than(JDK_Version v, JDK_Version other) {
assert(!v.is_undefined(), "must be defined");
@@ -685,18 +663,6 @@ int Arguments::is_deprecated_flag(const char *flag_name, JDK_Version* version) {
return 0;
}
-#ifndef PRODUCT
-const char* Arguments::removed_develop_logging_flag_name(const char* name){
- for (size_t i = 0; removed_develop_logging_flags[i].alias_name != NULL; i++) {
- const AliasedFlag& flag = removed_develop_logging_flags[i];
- if (strcmp(flag.alias_name, name) == 0) {
- return flag.real_name;
- }
- }
- return NULL;
-}
-#endif // PRODUCT
-
const char* Arguments::real_flag_name(const char *flag_name) {
for (size_t i = 0; aliased_jvm_flags[i].alias_name != NULL; i++) {
const AliasedFlag& flag_status = aliased_jvm_flags[i];
@@ -1014,44 +980,6 @@ const char* Arguments::handle_aliases_and_deprecation(const char* arg, bool warn
return NULL;
}
-void log_deprecated_flag(const char* name, bool on, AliasedLoggingFlag alf) {
- LogTagType tagSet[] = {alf.tag0, alf.tag1, alf.tag2, alf.tag3, alf.tag4, alf.tag5};
- // Set tagset string buffer at max size of 256, large enough for any alias tagset
- const int max_tagset_size = 256;
- int max_tagset_len = max_tagset_size - 1;
- char tagset_buffer[max_tagset_size];
- tagset_buffer[0] = '\0';
-
- // Write tag-set for aliased logging option, in string list form
- int max_tags = sizeof(tagSet)/sizeof(tagSet[0]);
- for (int i = 0; i < max_tags && tagSet[i] != LogTag::__NO_TAG; i++) {
- if (i > 0) {
- strncat(tagset_buffer, "+", max_tagset_len - strlen(tagset_buffer));
- }
- strncat(tagset_buffer, LogTag::name(tagSet[i]), max_tagset_len - strlen(tagset_buffer));
- }
- if (!alf.exactMatch) {
- strncat(tagset_buffer, "*", max_tagset_len - strlen(tagset_buffer));
- }
- log_warning(arguments)("-XX:%s%s is deprecated. Will use -Xlog:%s=%s instead.",
- (on) ? "+" : "-",
- name,
- tagset_buffer,
- (on) ? LogLevel::name(alf.level) : "off");
-}
-
-AliasedLoggingFlag Arguments::catch_logging_aliases(const char* name, bool on){
- for (size_t i = 0; aliased_logging_flags[i].alias_name != NULL; i++) {
- const AliasedLoggingFlag& alf = aliased_logging_flags[i];
- if (strcmp(alf.alias_name, name) == 0) {
- log_deprecated_flag(name, on, alf);
- return alf;
- }
- }
- AliasedLoggingFlag a = {NULL, LogLevel::Off, false, LOG_TAGS(_NO_TAG)};
- return a;
-}
-
bool Arguments::parse_argument(const char* arg, JVMFlagOrigin origin) {
// range of acceptable characters spelled out for portability reasons
@@ -1063,11 +991,6 @@ bool Arguments::parse_argument(const char* arg, JVMFlagOrigin origin) {
bool warn_if_deprecated = true;
if (sscanf(arg, "-%" XSTR(BUFLEN) NAME_RANGE "%c", name, &dummy) == 1) {
- AliasedLoggingFlag alf = catch_logging_aliases(name, false);
- if (alf.alias_name != NULL){
- LogConfiguration::configure_stdout(LogLevel::Off, alf.exactMatch, alf.tag0, alf.tag1, alf.tag2, alf.tag3, alf.tag4, alf.tag5);
- return true;
- }
real_name = handle_aliases_and_deprecation(name, warn_if_deprecated);
if (real_name == NULL) {
return false;
@@ -1076,11 +999,6 @@ bool Arguments::parse_argument(const char* arg, JVMFlagOrigin origin) {
return set_bool_flag(flag, false, origin);
}
if (sscanf(arg, "+%" XSTR(BUFLEN) NAME_RANGE "%c", name, &dummy) == 1) {
- AliasedLoggingFlag alf = catch_logging_aliases(name, true);
- if (alf.alias_name != NULL){
- LogConfiguration::configure_stdout(alf.level, alf.exactMatch, alf.tag0, alf.tag1, alf.tag2, alf.tag3, alf.tag4, alf.tag5);
- return true;
- }
real_name = handle_aliases_and_deprecation(name, warn_if_deprecated);
if (real_name == NULL) {
return false;
@@ -1094,11 +1012,6 @@ bool Arguments::parse_argument(const char* arg, JVMFlagOrigin origin) {
const char* value = strchr(arg, '=') + 1;
// this scanf pattern matches both strings (handled here) and numbers (handled later))
- AliasedLoggingFlag alf = catch_logging_aliases(name, true);
- if (alf.alias_name != NULL) {
- LogConfiguration::configure_stdout(alf.level, alf.exactMatch, alf.tag0, alf.tag1, alf.tag2, alf.tag3, alf.tag4, alf.tag5);
- return true;
- }
real_name = handle_aliases_and_deprecation(name, warn_if_deprecated);
if (real_name == NULL) {
return false;
@@ -1297,17 +1210,6 @@ bool Arguments::process_argument(const char* arg,
warning("Ignoring option %s; support was removed in %s", stripped_argname, version);
return true;
}
-#ifndef PRODUCT
- else {
- const char* replacement;
- if ((replacement = removed_develop_logging_flag_name(stripped_argname)) != NULL){
- log_warning(arguments)("%s has been removed. Please use %s instead.",
- stripped_argname,
- replacement);
- return false;
- }
- }
-#endif //PRODUCT
}
// For locked flags, report a custom error message if available.
diff --git a/src/hotspot/share/runtime/arguments.hpp b/src/hotspot/share/runtime/arguments.hpp
index 7bb0c27453247..c0b874ac18c65 100644
--- a/src/hotspot/share/runtime/arguments.hpp
+++ b/src/hotspot/share/runtime/arguments.hpp
@@ -226,19 +226,6 @@ class AgentLibraryList {
// Helper class for controlling the lifetime of JavaVMInitArgs objects.
class ScopedVMInitArgs;
-// Most logging functions require 5 tags. Some of them may be _NO_TAG.
-typedef struct {
- const char* alias_name;
- LogLevelType level;
- bool exactMatch;
- LogTagType tag0;
- LogTagType tag1;
- LogTagType tag2;
- LogTagType tag3;
- LogTagType tag4;
- LogTagType tag5;
-} AliasedLoggingFlag;
-
class Arguments : AllStatic {
friend class VMStructs;
friend class JvmtiExport;
@@ -460,10 +447,6 @@ class Arguments : AllStatic {
// the version number when the flag became obsolete.
static bool is_obsolete_flag(const char* flag_name, JDK_Version* version);
-#ifndef PRODUCT
- static const char* removed_develop_logging_flag_name(const char* name);
-#endif // PRODUCT
-
// Returns 1 if the flag is deprecated (and not yet obsolete or expired).
// In this case the 'version' buffer is filled in with the version number when
// the flag became deprecated.
@@ -477,7 +460,6 @@ class Arguments : AllStatic {
// Return the "real" name for option arg if arg is an alias, and print a warning if arg is deprecated.
// Return NULL if the arg has expired.
static const char* handle_aliases_and_deprecation(const char* arg, bool warn);
- static AliasedLoggingFlag catch_logging_aliases(const char* name, bool on);
static char* SharedArchivePath;
static char* SharedDynamicArchivePath;
diff --git a/src/hotspot/share/runtime/globals.hpp b/src/hotspot/share/runtime/globals.hpp
index fc2fd82733311..2814742768093 100644
--- a/src/hotspot/share/runtime/globals.hpp
+++ b/src/hotspot/share/runtime/globals.hpp
@@ -955,9 +955,6 @@ const intx ObjectAlignmentInBytes = 8;
\
/* JVMTI heap profiling */ \
\
- product(bool, TraceJVMTIObjectTagging, false, DIAGNOSTIC, \
- "Trace JVMTI object tagging calls") \
- \
product(bool, VerifyBeforeIteration, false, DIAGNOSTIC, \
"Verify memory system before JVMTI iteration") \
\
diff --git a/test/hotspot/jtreg/runtime/CommandLine/TraceExceptionsTest.java b/test/hotspot/jtreg/runtime/CommandLine/TraceExceptionsTest.java
index 14a447452d7f2..5a363114882ab 100644
--- a/test/hotspot/jtreg/runtime/CommandLine/TraceExceptionsTest.java
+++ b/test/hotspot/jtreg/runtime/CommandLine/TraceExceptionsTest.java
@@ -24,7 +24,7 @@
/*
* @test
* @bug 8048933
- * @summary TraceExceptions output should have the exception message - useful for ClassNotFoundExceptions especially
+ * @summary -Xlog:exceptions=info output should have the exception message - useful for ClassNotFoundExceptions especially
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
diff --git a/test/hotspot/jtreg/runtime/cds/appcds/ClassPathAttr.java b/test/hotspot/jtreg/runtime/cds/appcds/ClassPathAttr.java
index bf9bb5bb274db..5a3bb39b8b968 100644
--- a/test/hotspot/jtreg/runtime/cds/appcds/ClassPathAttr.java
+++ b/test/hotspot/jtreg/runtime/cds/appcds/ClassPathAttr.java
@@ -85,16 +85,6 @@ static void testNormalOps() throws Exception {
output.shouldMatch("checking shared classpath entry: .*cpattr2.jar");
output.shouldMatch("checking shared classpath entry: .*cpattr3.jar");
});
-
- // Make sure aliased TraceClassPaths still works
- TestCommon.run(
- "-XX:+TraceClassPaths",
- "-cp", cp,
- "CpAttr1")
- .assertNormalExit(output -> {
- output.shouldMatch("checking shared classpath entry: .*cpattr2.jar");
- output.shouldMatch("checking shared classpath entry: .*cpattr3.jar");
- });
}
}
diff --git a/test/hotspot/jtreg/runtime/cds/appcds/IgnoreEmptyClassPaths.java b/test/hotspot/jtreg/runtime/cds/appcds/IgnoreEmptyClassPaths.java
index daa4e7e162737..97b5a26755bb4 100644
--- a/test/hotspot/jtreg/runtime/cds/appcds/IgnoreEmptyClassPaths.java
+++ b/test/hotspot/jtreg/runtime/cds/appcds/IgnoreEmptyClassPaths.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -46,13 +46,13 @@ public static void main(String[] args) throws Exception {
String cp_exec = sep + jar1 + sep + sep + jar2 + sep;
TestCommon.testDump(cp_dump, TestCommon.list("Hello", "HelloMore"),
- "-XX:+TraceClassPaths", "-XX:+IgnoreEmptyClassPaths");
+ "-Xlog:class+path=info", "-XX:+IgnoreEmptyClassPaths");
TestCommon.run(
"-verbose:class",
"-cp", cp_exec,
"-XX:+IgnoreEmptyClassPaths", // should affect classpath even if placed after the "-cp" argument
- "-XX:+TraceClassPaths",
+ "-Xlog:class+path=info",
"HelloMore")
.assertNormalExit();
}
diff --git a/test/hotspot/jtreg/runtime/cds/appcds/javaldr/GCDuringDump.java b/test/hotspot/jtreg/runtime/cds/appcds/javaldr/GCDuringDump.java
index a9499866ebcb2..e4a16bb6f21ae 100644
--- a/test/hotspot/jtreg/runtime/cds/appcds/javaldr/GCDuringDump.java
+++ b/test/hotspot/jtreg/runtime/cds/appcds/javaldr/GCDuringDump.java
@@ -73,7 +73,7 @@ public static void main(String[] args) throws Throwable {
TestCommon.run(
"-cp", appJar,
"-Xmx32m",
- "-XX:+PrintSharedSpaces",
+ "-Xlog:cds=info",
"-XX:+UnlockDiagnosticVMOptions", extraOption,
gcLog,
Hello.class.getName())
diff --git a/test/hotspot/jtreg/runtime/cds/appcds/javaldr/GCSharedStringsDuringDump.java b/test/hotspot/jtreg/runtime/cds/appcds/javaldr/GCSharedStringsDuringDump.java
index beda2edd79396..465f5d196fd6c 100644
--- a/test/hotspot/jtreg/runtime/cds/appcds/javaldr/GCSharedStringsDuringDump.java
+++ b/test/hotspot/jtreg/runtime/cds/appcds/javaldr/GCSharedStringsDuringDump.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 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
@@ -112,7 +112,7 @@ public static void main(String[] args) throws Throwable {
extraArg,
"-Xlog:cds=info,class+path=info",
"-Xmx32m",
- "-XX:+PrintSharedSpaces",
+ "-Xlog:cds=info",
"-XX:+UnlockDiagnosticVMOptions",
extraOption,
"-XX:+WhiteBoxAPI",
diff --git a/test/hotspot/jtreg/runtime/cds/appcds/javaldr/HumongousDuringDump.java b/test/hotspot/jtreg/runtime/cds/appcds/javaldr/HumongousDuringDump.java
index f87534dae21c8..94601b6bcf3b8 100644
--- a/test/hotspot/jtreg/runtime/cds/appcds/javaldr/HumongousDuringDump.java
+++ b/test/hotspot/jtreg/runtime/cds/appcds/javaldr/HumongousDuringDump.java
@@ -75,7 +75,7 @@ public static void main(String[] args) throws Throwable {
"-cp", appJar,
"-verbose",
"-Xmx64m",
- "-XX:+PrintSharedSpaces",
+ "-Xlog:cds=info",
"-XX:+UnlockDiagnosticVMOptions", extraOption,
gcLog,
Hello.class.getName())
diff --git a/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/classpathtests/BootAppendTests.java b/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/classpathtests/BootAppendTests.java
index a367bcffb03c7..2a037ce1a916b 100644
--- a/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/classpathtests/BootAppendTests.java
+++ b/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/classpathtests/BootAppendTests.java
@@ -189,7 +189,7 @@ public static void testBootAppendClassWithAppCDS() throws Exception {
OutputAnalyzer output = TestCommon.exec(
appJar,
"-Xbootclasspath/a:" + bootAppendJar,
- "-XX:+TraceClassLoading",
+ "-Xlog:class+load=info",
MAIN_CLASS,
"Test #6", BOOT_APPEND_CLASS, "true", "BOOT");
TestCommon.checkExec(output);
diff --git a/test/hotspot/jtreg/runtime/logging/BiasedLockingTest.java b/test/hotspot/jtreg/runtime/logging/BiasedLockingTest.java
index a0605d0ff4f77..df4486efbf77b 100644
--- a/test/hotspot/jtreg/runtime/logging/BiasedLockingTest.java
+++ b/test/hotspot/jtreg/runtime/logging/BiasedLockingTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 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
@@ -54,23 +54,11 @@ public static void main(String[] args) throws Exception {
InnerClass.class.getName());
analyzeOutputOn(pb);
- pb = ProcessTools.createJavaProcessBuilder("-XX:+UseBiasedLocking",
- "-XX:+TraceBiasedLocking",
- "-XX:BiasedLockingStartupDelay=0",
- InnerClass.class.getName());
- analyzeOutputOn(pb);
-
pb = ProcessTools.createJavaProcessBuilder("-XX:+UseBiasedLocking",
"-Xlog:biasedlocking=off",
"-XX:BiasedLockingStartupDelay=0",
InnerClass.class.getName());
analyzeOutputOff(pb);
-
- pb = ProcessTools.createJavaProcessBuilder("-XX:+UseBiasedLocking",
- "-XX:-TraceBiasedLocking",
- "-XX:BiasedLockingStartupDelay=0",
- InnerClass.class.getName());
- analyzeOutputOff(pb);
}
public static class InnerClass {
diff --git a/test/hotspot/jtreg/runtime/logging/ClassLoadUnloadTest.java b/test/hotspot/jtreg/runtime/logging/ClassLoadUnloadTest.java
index 06e8171e0a75e..1ccda83101b19 100644
--- a/test/hotspot/jtreg/runtime/logging/ClassLoadUnloadTest.java
+++ b/test/hotspot/jtreg/runtime/logging/ClassLoadUnloadTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 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
@@ -90,14 +90,6 @@ public static void main(String... args) throws Exception {
pb = exec("-Xlog:class+unload=off");
checkAbsent("[class,unload]");
- // -XX:+TraceClassUnloading
- pb = exec("-XX:+TraceClassUnloading");
- checkFor("[class,unload]", "unloading class");
-
- // -XX:-TraceClassUnloading
- pb = exec("-XX:-TraceClassUnloading");
- checkAbsent("[class,unload]");
-
// -Xlog:class+load=info
pb = exec("-Xlog:class+load=info");
checkFor("[class,load]", "java.lang.Object", "source:");
@@ -110,14 +102,6 @@ public static void main(String... args) throws Exception {
pb = exec("-Xlog:class+load=off");
checkAbsent("[class,load]");
- // -XX:+TraceClassLoading
- pb = exec("-XX:+TraceClassLoading");
- checkFor("[class,load]", "java.lang.Object", "source:");
-
- // -XX:-TraceClassLoading
- pb = exec("-XX:-TraceClassLoading");
- checkAbsent("[class,load]");
-
// -verbose:class
pb = exec("-verbose:class");
checkFor("[class,load]", "java.lang.Object", "source:");
diff --git a/test/hotspot/jtreg/runtime/logging/ClassResolutionTest.java b/test/hotspot/jtreg/runtime/logging/ClassResolutionTest.java
index 32f43b1333784..18b74e2635399 100644
--- a/test/hotspot/jtreg/runtime/logging/ClassResolutionTest.java
+++ b/test/hotspot/jtreg/runtime/logging/ClassResolutionTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 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
@@ -71,20 +71,6 @@ public static void main(String... args) throws Exception {
ClassResolutionTestMain.class.getName());
o = new OutputAnalyzer(pb.start());
o.shouldNotContain("[class,resolve]");
-
- // (3) TraceClassResolution should turn on.
- pb = ProcessTools.createJavaProcessBuilder("-XX:+TraceClassResolution",
- ClassResolutionTestMain.class.getName());
- o = new OutputAnalyzer(pb.start());
- o.shouldContain("[class,resolve] ClassResolutionTest$ClassResolutionTestMain$Thing1Handler ClassResolutionTest$ClassResolutionTestMain$Thing1");
-
- // (4) TraceClassResolution should turn off.
- pb = ProcessTools.createJavaProcessBuilder("-Xlog:class+resolve=debug",
- "-XX:-TraceClassResolution",
- ClassResolutionTestMain.class.getName());
- o = new OutputAnalyzer(pb.start());
- o.shouldNotContain("[class,resolve]");
-
};
}
diff --git a/test/hotspot/jtreg/runtime/logging/ExceptionsTest.java b/test/hotspot/jtreg/runtime/logging/ExceptionsTest.java
index db2cf0a5bdb8f..ab61fb8b7c3af 100644
--- a/test/hotspot/jtreg/runtime/logging/ExceptionsTest.java
+++ b/test/hotspot/jtreg/runtime/logging/ExceptionsTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -60,24 +60,16 @@ public static void main(String[] args) throws Exception {
InternalClass.class.getName());
analyzeOutputOn(pb);
- pb = ProcessTools.createJavaProcessBuilder("-XX:+TraceExceptions",
- InternalClass.class.getName());
- analyzeOutputOn(pb);
-
pb = ProcessTools.createJavaProcessBuilder("-Xlog:exceptions=off",
InternalClass.class.getName());
analyzeOutputOff(pb);
- pb = ProcessTools.createJavaProcessBuilder("-XX:-TraceExceptions",
- InternalClass.class.getName());
- analyzeOutputOff(pb);
-
pb = ProcessTools.createJavaProcessBuilder(InternalClass.class.getName());
- updateEnvironment(pb, "_JAVA_OPTIONS", "-XX:+TraceExceptions");
+ updateEnvironment(pb, "_JAVA_OPTIONS", "-Xlog:exceptions=info");
analyzeOutputOn(pb);
pb = ProcessTools.createJavaProcessBuilder(InternalClass.class.getName());
- updateEnvironment(pb, "JAVA_TOOL_OPTIONS", "-Xlog:exceptions=info -XX:-TraceExceptions");
+ updateEnvironment(pb, "JAVA_TOOL_OPTIONS", "-Xlog:exceptions=info -Xlog:exceptions=off");
analyzeOutputOff(pb);
pb = ProcessTools.createJavaProcessBuilder("-XX:VMOptionsFile=" + System.getProperty("test.src", ".")
diff --git a/test/hotspot/jtreg/runtime/logging/ExceptionsTest_options_file b/test/hotspot/jtreg/runtime/logging/ExceptionsTest_options_file
index b5f0532f96cc4..d3e8be7f85752 100644
--- a/test/hotspot/jtreg/runtime/logging/ExceptionsTest_options_file
+++ b/test/hotspot/jtreg/runtime/logging/ExceptionsTest_options_file
@@ -1 +1 @@
--XX:+TraceExceptions
+-Xlog:exceptions=info
diff --git a/test/hotspot/jtreg/runtime/logging/LoaderConstraintsTest.java b/test/hotspot/jtreg/runtime/logging/LoaderConstraintsTest.java
index b2b56b4238b9e..cf37a49f43aa2 100644
--- a/test/hotspot/jtreg/runtime/logging/LoaderConstraintsTest.java
+++ b/test/hotspot/jtreg/runtime/logging/LoaderConstraintsTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 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
@@ -63,22 +63,11 @@ static ProcessBuilder exec(String... args) throws Exception {
public static void main(String... args) throws Exception {
- // -XX:+TraceLoaderConstraints
- pb = exec("-XX:+TraceLoaderConstraints");
- out = new OutputAnalyzer(pb.start());
- out.getOutput();
- out.shouldContain("[class,loader,constraints] adding new constraint for name: java/lang/Class, loader[0]: 'app', loader[1]: 'bootstrap'");
-
// -Xlog:class+loader+constraints=info
pb = exec("-Xlog:class+loader+constraints=info");
out = new OutputAnalyzer(pb.start());
out.shouldContain("[class,loader,constraints] adding new constraint for name: java/lang/Class, loader[0]: 'app', loader[1]: 'bootstrap'");
- // -XX:-TraceLoaderConstraints
- pb = exec("-XX:-TraceLoaderConstraints");
- out = new OutputAnalyzer(pb.start());
- out.shouldNotContain("[class,loaderconstraints]");
-
// -Xlog:class+loader+constraints=off
pb = exec("-Xlog:class+loader+constraints=off");
out = new OutputAnalyzer(pb.start());
diff --git a/test/hotspot/jtreg/runtime/logging/MonitorInflationTest.java b/test/hotspot/jtreg/runtime/logging/MonitorInflationTest.java
index 1be25bd9a9b73..568055617f9c6 100644
--- a/test/hotspot/jtreg/runtime/logging/MonitorInflationTest.java
+++ b/test/hotspot/jtreg/runtime/logging/MonitorInflationTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -54,17 +54,9 @@ public static void main(String[] args) throws Exception {
InnerClass.class.getName());
analyzeOutputOn(pb);
- pb = ProcessTools.createJavaProcessBuilder("-XX:+TraceMonitorInflation",
- InnerClass.class.getName());
- analyzeOutputOn(pb);
-
pb = ProcessTools.createJavaProcessBuilder("-Xlog:monitorinflation=off",
InnerClass.class.getName());
analyzeOutputOff(pb);
-
- pb = ProcessTools.createJavaProcessBuilder("-XX:-TraceMonitorInflation",
- InnerClass.class.getName());
- analyzeOutputOff(pb);
}
public static class Waiter {
diff --git a/test/hotspot/jtreg/runtime/logging/RemovedDevelopFlagsTest.java b/test/hotspot/jtreg/runtime/logging/RemovedDevelopFlagsTest.java
deleted file mode 100644
index 9c9ce86b7cd72..0000000000000
--- a/test/hotspot/jtreg/runtime/logging/RemovedDevelopFlagsTest.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2016, 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 RemovedDevelopFlagsTest
- * @bug 8146632
- * @modules java.base/jdk.internal.misc
- * @requires vm.debug
- * @library /test/lib
- * @run driver RemovedDevelopFlagsTest
- */
-import jdk.test.lib.process.ProcessTools;
-import jdk.test.lib.process.OutputAnalyzer;
-
-public class RemovedDevelopFlagsTest {
- public static ProcessBuilder pb;
-
- public static class RemovedDevelopFlagsTestMain {
- public static void main(String... args) {
- System.out.print("Hello!");
- }
- }
-
- public static void exec(String flag, String value) throws Exception {
- pb = ProcessTools.createJavaProcessBuilder("-XX:+"+flag, RemovedDevelopFlagsTestMain.class.getName());
- OutputAnalyzer o = new OutputAnalyzer(pb.start());
- o.shouldContain(flag+" has been removed. Please use "+value+" instead.");
- o.shouldHaveExitValue(1);
- }
-
- public static void main(String... args) throws Exception {
- exec("TraceClassInitialization", "-Xlog:class+init");
- exec("TraceClassLoaderData", "-Xlog:class+loader+data");
- exec("TraceDefaultMethods", "-Xlog:defaultmethods=debug");
- exec("TraceItables", "-Xlog:itables=debug");
- exec("TraceSafepoint", "-Xlog:safepoint=debug");
- exec("TraceStartupTime", "-Xlog:startuptime");
- exec("TraceVMOperation", "-Xlog:vmoperation=debug");
- exec("PrintVtables", "-Xlog:vtables=debug");
- exec("VerboseVerification", "-Xlog:verification");
- }
-}
diff --git a/test/hotspot/jtreg/runtime/logging/SafepointCleanupTest.java b/test/hotspot/jtreg/runtime/logging/SafepointCleanupTest.java
index 5c445dc4f1c56..9136953a5e980 100644
--- a/test/hotspot/jtreg/runtime/logging/SafepointCleanupTest.java
+++ b/test/hotspot/jtreg/runtime/logging/SafepointCleanupTest.java
@@ -55,17 +55,9 @@ public static void main(String[] args) throws Exception {
InnerClass.class.getName());
analyzeOutputOn(pb);
- pb = ProcessTools.createJavaProcessBuilder("-XX:+TraceSafepointCleanupTime",
- InnerClass.class.getName());
- analyzeOutputOn(pb);
-
pb = ProcessTools.createJavaProcessBuilder("-Xlog:safepoint+cleanup=off",
InnerClass.class.getName());
analyzeOutputOff(pb);
-
- pb = ProcessTools.createJavaProcessBuilder("-XX:-TraceSafepointCleanupTime",
- InnerClass.class.getName());
- analyzeOutputOff(pb);
}
public static class InnerClass {
diff --git a/test/jdk/com/sun/jdi/cds/CDSJDITest.java b/test/jdk/com/sun/jdi/cds/CDSJDITest.java
index f55c55373d017..e10c61d748c05 100644
--- a/test/jdk/com/sun/jdi/cds/CDSJDITest.java
+++ b/test/jdk/com/sun/jdi/cds/CDSJDITest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -61,7 +61,7 @@ public static void runTest(String testname, String[] jarClasses) throws Exceptio
// pass them as JVM arguments to the debuggee process it creates.
"-Xbootclasspath/a:" + appJar,
"-XX:+UnlockDiagnosticVMOptions",
- "-XX:+TraceClassPaths",
+ "-Xlog:class+path=info",
"-XX:SharedArchiveFile=./SharedArchiveFile.jsa",
"-Xshare:on",
"-showversion"
From 129c37700ff1ab6f2b9540422f93689970b5e9a0 Mon Sep 17 00:00:00 2001
From: Tobias Hartmann
Date: Thu, 3 Dec 2020 13:42:19 +0000
Subject: [PATCH 042/504] 8257594: C2 compiled checkcast of non-null object
triggers endless deoptimization/recompilation cycle
Reviewed-by: roland, vlivanov
---
src/hotspot/share/opto/graphKit.cpp | 8 +-
src/hotspot/share/opto/parse2.cpp | 3 +
src/hotspot/share/opto/parseHelper.cpp | 5 +-
.../TestNullAssertAtCheckCast.java | 119 ++++++++++++++++++
4 files changed, 133 insertions(+), 2 deletions(-)
create mode 100644 test/hotspot/jtreg/compiler/uncommontrap/TestNullAssertAtCheckCast.java
diff --git a/src/hotspot/share/opto/graphKit.cpp b/src/hotspot/share/opto/graphKit.cpp
index 166933525a1a3..dc5c19fa6b3dd 100644
--- a/src/hotspot/share/opto/graphKit.cpp
+++ b/src/hotspot/share/opto/graphKit.cpp
@@ -3311,7 +3311,13 @@ Node* GraphKit::gen_checkcast(Node *obj, Node* superklass,
case Compile::SSC_always_false:
// It needs a null check because a null will *pass* the cast check.
// A non-null value will always produce an exception.
- return null_assert(obj);
+ if (!objtp->maybe_null()) {
+ builtin_throw(Deoptimization::Reason_class_check, makecon(TypeKlassPtr::make(objtp->klass())));
+ return top();
+ } else if (!too_many_traps_or_recompiles(Deoptimization::Reason_null_assert)) {
+ return null_assert(obj);
+ }
+ break; // Fall through to full check
}
}
}
diff --git a/src/hotspot/share/opto/parse2.cpp b/src/hotspot/share/opto/parse2.cpp
index 6f2ae1af88a6d..c006de2ae5acb 100644
--- a/src/hotspot/share/opto/parse2.cpp
+++ b/src/hotspot/share/opto/parse2.cpp
@@ -83,6 +83,9 @@ void Parse::array_store(BasicType bt) {
if (stopped()) return; // guaranteed null or range check
if (bt == T_OBJECT) {
array_store_check();
+ if (stopped()) {
+ return;
+ }
}
Node* val; // Oop to store
if (big_val) {
diff --git a/src/hotspot/share/opto/parseHelper.cpp b/src/hotspot/share/opto/parseHelper.cpp
index c885f7806b18a..fbcb0713555ab 100644
--- a/src/hotspot/share/opto/parseHelper.cpp
+++ b/src/hotspot/share/opto/parseHelper.cpp
@@ -89,7 +89,10 @@ void Parse::do_checkcast() {
return;
}
- Node *res = gen_checkcast(obj, makecon(TypeKlassPtr::make(klass)) );
+ Node* res = gen_checkcast(obj, makecon(TypeKlassPtr::make(klass)));
+ if (stopped()) {
+ return;
+ }
// Pop from stack AFTER gen_checkcast because it can uncommon trap and
// the debug info has to be correct.
diff --git a/test/hotspot/jtreg/compiler/uncommontrap/TestNullAssertAtCheckCast.java b/test/hotspot/jtreg/compiler/uncommontrap/TestNullAssertAtCheckCast.java
new file mode 100644
index 0000000000000..7b69f3411b19a
--- /dev/null
+++ b/test/hotspot/jtreg/compiler/uncommontrap/TestNullAssertAtCheckCast.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 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
+ * @bug 8257594
+ * @summary Test that failing checkcast does not trigger repeated recompilation until cutoff is hit.
+ * @requires vm.compiler2.enabled
+ * @modules java.base/jdk.internal.misc
+ * @library /test/lib
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ * -Xbatch -XX:CompileCommand=dontinline,compiler.uncommontrap.TestNullAssertAtCheckCast::test*
+ * -XX:CompileCommand=inline,compiler.uncommontrap.TestNullAssertAtCheckCast::cast
+ * -XX:CompileCommand=inline,compiler.uncommontrap.TestNullAssertAtCheckCast::store
+ * compiler.uncommontrap.TestNullAssertAtCheckCast
+ */
+
+package compiler.uncommontrap;
+
+import sun.hotspot.WhiteBox;
+
+import java.lang.reflect.Method;
+
+public class TestNullAssertAtCheckCast {
+ private static final WhiteBox WB = WhiteBox.getWhiteBox();
+ private static final int COMP_LEVEL_FULL_OPTIMIZATION = 4;
+
+ static Long cast(Object val) {
+ return (Long)val;
+ }
+
+ static void test1() {
+ try {
+ // Always fails
+ cast(new Integer(42));
+ } catch (ClassCastException cce) {
+ // Ignored
+ }
+ }
+
+ static void test2(Integer val) {
+ try {
+ // Always fails
+ cast(val);
+ } catch (ClassCastException cce) {
+ // Ignored
+ }
+ }
+
+ static void store(Object[] array, Object val) {
+ array[0] = val;
+ }
+
+ static void test3() {
+ try {
+ // Always fails
+ store(new Long[1], new Integer(42));
+ } catch (ArrayStoreException cce) {
+ // Ignored
+ }
+ }
+
+ static void test4(Integer val) {
+ try {
+ // Always fails
+ store(new Long[1], val);
+ } catch (ArrayStoreException cce) {
+ // Ignored
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ for (int i = 0; i < 1_000_000; ++i) {
+ test1();
+ test2((i % 2 == 0) ? null : 42);
+ test3();
+ test4((i % 2 == 0) ? null : 42);
+ }
+ Method method = TestNullAssertAtCheckCast.class.getDeclaredMethod("test1");
+ if (!WB.isMethodCompilable(method, COMP_LEVEL_FULL_OPTIMIZATION, false)) {
+ throw new RuntimeException("TestNullAssertAtCheckCast::test1 not compilable");
+ }
+ method = TestNullAssertAtCheckCast.class.getDeclaredMethod("test2", Integer.class);
+ if (!WB.isMethodCompilable(method, COMP_LEVEL_FULL_OPTIMIZATION, false)) {
+ throw new RuntimeException("TestNullAssertAtCheckCast::test2 not compilable");
+ }
+ method = TestNullAssertAtCheckCast.class.getDeclaredMethod("test3");
+ if (!WB.isMethodCompilable(method, COMP_LEVEL_FULL_OPTIMIZATION, false)) {
+ throw new RuntimeException("TestNullAssertAtCheckCast::test3 not compilable");
+ }
+ method = TestNullAssertAtCheckCast.class.getDeclaredMethod("test4", Integer.class);
+ if (!WB.isMethodCompilable(method, COMP_LEVEL_FULL_OPTIMIZATION, false)) {
+ throw new RuntimeException("TestNullAssertAtCheckCast::test4 not compilable");
+ }
+ }
+}
+
From fa58671f9f8a8230d907c0a6289685f8455bce1f Mon Sep 17 00:00:00 2001
From: Doug Simon
Date: Thu, 3 Dec 2020 13:42:50 +0000
Subject: [PATCH 043/504] 8257020: [JVMCI] enable a JVMCICompiler to specify
which GCs it supports
Reviewed-by: stefank, kvn
---
.../share/compiler/compilerDefinitions.cpp | 2 +-
src/hotspot/share/jvmci/jvmciEnv.cpp | 25 +++++++++
src/hotspot/share/jvmci/jvmciEnv.hpp | 2 +
src/hotspot/share/jvmci/jvmciJavaClasses.hpp | 1 +
src/hotspot/share/jvmci/jvmciRuntime.cpp | 9 +++
src/hotspot/share/jvmci/jvmciRuntime.hpp | 4 ++
src/hotspot/share/jvmci/jvmci_globals.cpp | 8 ++-
src/hotspot/share/jvmci/jvmci_globals.hpp | 5 +-
src/hotspot/share/jvmci/vmStructs_jvmci.cpp | 8 +++
src/hotspot/share/jvmci/vmSymbols_jvmci.hpp | 1 +
src/hotspot/share/logging/logTag.hpp | 1 +
src/hotspot/share/prims/whitebox.cpp | 24 ++++++++
.../hotspot/HotSpotJVMCICompilerConfig.java | 5 ++
.../vm/ci/hotspot/HotSpotJVMCIRuntime.java | 11 ++++
.../src/jdk/vm/ci/runtime/JVMCICompiler.java | 11 ++++
.../hotspot/HotSpotGraalCompiler.java | 10 ++++
.../compiler/hotspot/HotSpotGraalRuntime.java | 55 +++++++++++++++----
test/jtreg-ext/requires/VMProps.java | 33 ++---------
test/lib/sun/hotspot/WhiteBox.java | 2 +
test/lib/sun/hotspot/code/Compiler.java | 14 +++++
test/lib/sun/hotspot/gc/GC.java | 7 +++
21 files changed, 197 insertions(+), 41 deletions(-)
diff --git a/src/hotspot/share/compiler/compilerDefinitions.cpp b/src/hotspot/share/compiler/compilerDefinitions.cpp
index dc8c726ce3605..c12ca9a466cd9 100644
--- a/src/hotspot/share/compiler/compilerDefinitions.cpp
+++ b/src/hotspot/share/compiler/compilerDefinitions.cpp
@@ -457,7 +457,7 @@ void CompilerConfig::ergo_initialize() {
#endif
#if INCLUDE_JVMCI
- // Check that JVMCI compiler supports selested GC.
+ // Check that JVMCI supports selected GC.
// Should be done after GCConfig::initialize() was called.
JVMCIGlobals::check_jvmci_supported_gc();
diff --git a/src/hotspot/share/jvmci/jvmciEnv.cpp b/src/hotspot/share/jvmci/jvmciEnv.cpp
index daa4b8ad4cf4b..73afe41e90313 100644
--- a/src/hotspot/share/jvmci/jvmciEnv.cpp
+++ b/src/hotspot/share/jvmci/jvmciEnv.cpp
@@ -635,6 +635,31 @@ void JVMCIEnv::fthrow_error(const char* file, int line, const char* format, ...)
}
}
+jboolean JVMCIEnv::call_HotSpotJVMCIRuntime_isGCSupported (JVMCIObject runtime, jint gcIdentifier) {
+ JavaThread* THREAD = JavaThread::current();
+ if (is_hotspot()) {
+ JavaCallArguments jargs;
+ jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
+ jargs.push_int(gcIdentifier);
+ JavaValue result(T_BOOLEAN);
+ JavaCalls::call_special(&result,
+ HotSpotJVMCI::HotSpotJVMCIRuntime::klass(),
+ vmSymbols::isGCSupported_name(),
+ vmSymbols::int_bool_signature(), &jargs, CHECK_0);
+ return result.get_jboolean();
+ } else {
+ JNIAccessMark jni(this, THREAD);
+ jboolean result = jni()->CallNonvirtualBooleanMethod(runtime.as_jobject(),
+ JNIJVMCI::HotSpotJVMCIRuntime::clazz(),
+ JNIJVMCI::HotSpotJVMCIRuntime::isGCSupported_method(),
+ gcIdentifier);
+ if (jni()->ExceptionCheck()) {
+ return false;
+ }
+ return result;
+ }
+}
+
JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_compileMethod (JVMCIObject runtime, JVMCIObject method, int entry_bci,
jlong compile_state, int id) {
JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current());
diff --git a/src/hotspot/share/jvmci/jvmciEnv.hpp b/src/hotspot/share/jvmci/jvmciEnv.hpp
index e59a3bde6e037..3f5658a19ada0 100644
--- a/src/hotspot/share/jvmci/jvmciEnv.hpp
+++ b/src/hotspot/share/jvmci/jvmciEnv.hpp
@@ -310,6 +310,8 @@ class JVMCIEnv : public ResourceObj {
JVMCIObject call_JavaConstant_forFloat(float value, JVMCI_TRAPS);
JVMCIObject call_JavaConstant_forDouble(double value, JVMCI_TRAPS);
+ jboolean call_HotSpotJVMCIRuntime_isGCSupported(JVMCIObject runtime, jint gcIdentifier);
+
BasicType kindToBasicType(JVMCIObject kind, JVMCI_TRAPS);
#define DO_THROW(name) \
diff --git a/src/hotspot/share/jvmci/jvmciJavaClasses.hpp b/src/hotspot/share/jvmci/jvmciJavaClasses.hpp
index 7e981d5738a45..25d0a109e7e64 100644
--- a/src/hotspot/share/jvmci/jvmciJavaClasses.hpp
+++ b/src/hotspot/share/jvmci/jvmciJavaClasses.hpp
@@ -348,6 +348,7 @@
start_class(HotSpotJVMCIRuntime, jdk_vm_ci_hotspot_HotSpotJVMCIRuntime) \
objectarray_field(HotSpotJVMCIRuntime, excludeFromJVMCICompilation, "[Ljava/lang/Module;") \
jvmci_method(CallNonvirtualObjectMethod, GetMethodID, call_special, JVMCIObject, HotSpotJVMCIRuntime, compileMethod, compileMethod_signature, (JVMCIObject runtime, JVMCIObject method, int entry_bci, jlong env, int id)) \
+ jvmci_method(CallNonvirtualObjectMethod, GetMethodID, call_special, JVMCIObject, HotSpotJVMCIRuntime, isGCSupported, int_bool_signature, (JVMCIObject runtime, int gcIdentifier)) \
jvmci_method(CallStaticObjectMethod, GetStaticMethodID, call_static, JVMCIObject, HotSpotJVMCIRuntime, encodeThrowable, encodeThrowable_signature, (JVMCIObject throwable)) \
jvmci_method(CallStaticObjectMethod, GetStaticMethodID, call_static, JVMCIObject, HotSpotJVMCIRuntime, decodeThrowable, decodeThrowable_signature, (JVMCIObject encodedThrowable)) \
jvmci_method(CallNonvirtualVoidMethod, GetMethodID, call_special, void, HotSpotJVMCIRuntime, bootstrapFinished, void_method_signature, (JVMCIObject runtime, JVMCI_TRAPS)) \
diff --git a/src/hotspot/share/jvmci/jvmciRuntime.cpp b/src/hotspot/share/jvmci/jvmciRuntime.cpp
index c7ed875f85444..4cd91108f4849 100644
--- a/src/hotspot/share/jvmci/jvmciRuntime.cpp
+++ b/src/hotspot/share/jvmci/jvmciRuntime.cpp
@@ -1516,6 +1516,15 @@ void JVMCIRuntime::compile_method(JVMCIEnv* JVMCIENV, JVMCICompiler* compiler, c
}
}
+bool JVMCIRuntime::is_gc_supported(JVMCIEnv* JVMCIENV, CollectedHeap::Name name) {
+ JVMCI_EXCEPTION_CONTEXT
+
+ JVMCIObject receiver = get_HotSpotJVMCIRuntime(JVMCIENV);
+ if (JVMCIENV->has_pending_exception()) {
+ fatal_exception(JVMCIENV, "Exception during HotSpotJVMCIRuntime initialization");
+ }
+ return JVMCIENV->call_HotSpotJVMCIRuntime_isGCSupported(receiver, (int) name);
+}
// ------------------------------------------------------------------
JVMCI::CodeInstallResult JVMCIRuntime::register_method(JVMCIEnv* JVMCIENV,
diff --git a/src/hotspot/share/jvmci/jvmciRuntime.hpp b/src/hotspot/share/jvmci/jvmciRuntime.hpp
index 0fb677c2d0160..2f475f9e4470c 100644
--- a/src/hotspot/share/jvmci/jvmciRuntime.hpp
+++ b/src/hotspot/share/jvmci/jvmciRuntime.hpp
@@ -25,6 +25,7 @@
#define SHARE_JVMCI_JVMCIRUNTIME_HPP
#include "code/nmethod.hpp"
+#include "gc/shared/collectedHeap.hpp"
#include "jvmci/jvmci.hpp"
#include "jvmci/jvmciExceptions.hpp"
#include "jvmci/jvmciObject.hpp"
@@ -279,6 +280,9 @@ class JVMCIRuntime: public CHeapObj {
// Compiles `target` with the JVMCI compiler.
void compile_method(JVMCIEnv* JVMCIENV, JVMCICompiler* compiler, const methodHandle& target, int entry_bci);
+ // Determines if the GC identified by `name` is supported by the JVMCI compiler.
+ bool is_gc_supported(JVMCIEnv* JVMCIENV, CollectedHeap::Name name);
+
// Register the result of a compilation.
JVMCI::CodeInstallResult register_method(JVMCIEnv* JVMCIENV,
const methodHandle& target,
diff --git a/src/hotspot/share/jvmci/jvmci_globals.cpp b/src/hotspot/share/jvmci/jvmci_globals.cpp
index bbf3ec67b1b09..4d9dbc3005b7b 100644
--- a/src/hotspot/share/jvmci/jvmci_globals.cpp
+++ b/src/hotspot/share/jvmci/jvmci_globals.cpp
@@ -200,11 +200,15 @@ bool JVMCIGlobals::enable_jvmci_product_mode(JVMFlagOrigin origin) {
return true;
}
+bool JVMCIGlobals::gc_supports_jvmci() {
+ return UseSerialGC || UseParallelGC || UseG1GC;
+}
+
void JVMCIGlobals::check_jvmci_supported_gc() {
if (EnableJVMCI) {
// Check if selected GC is supported by JVMCI and Java compiler
- if (!(UseSerialGC || UseParallelGC || UseG1GC)) {
- vm_exit_during_initialization("JVMCI Compiler does not support selected GC", GCConfig::hs_err_name());
+ if (!gc_supports_jvmci()) {
+ log_warning(gc, jvmci)("Setting EnableJVMCI to false as selected GC does not support JVMCI: %s", GCConfig::hs_err_name());
FLAG_SET_DEFAULT(EnableJVMCI, false);
FLAG_SET_DEFAULT(UseJVMCICompiler, false);
}
diff --git a/src/hotspot/share/jvmci/jvmci_globals.hpp b/src/hotspot/share/jvmci/jvmci_globals.hpp
index 5009b17db6234..57d40b5fabd09 100644
--- a/src/hotspot/share/jvmci/jvmci_globals.hpp
+++ b/src/hotspot/share/jvmci/jvmci_globals.hpp
@@ -155,7 +155,10 @@ class JVMCIGlobals {
// Convert JVMCI experimental flags to product
static bool enable_jvmci_product_mode(JVMFlagOrigin);
- // Check and exit VM with error if selected GC is not supported by JVMCI.
+ // Returns true iff the GC fully supports JVMCI.
+ static bool gc_supports_jvmci();
+
+ // Check and turn off EnableJVMCI if selected GC does not support JVMCI.
static void check_jvmci_supported_gc();
static fileStream* get_jni_config_file() { return _jni_config_file; }
diff --git a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp
index ccc611ca07b4b..8b8d3061d573a 100644
--- a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp
+++ b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp
@@ -482,6 +482,14 @@
declare_constant(CodeInstaller::VERIFY_OOP_MASK) \
declare_constant(CodeInstaller::INVOKE_INVALID) \
\
+ declare_constant(CollectedHeap::None) \
+ declare_constant(CollectedHeap::Serial) \
+ declare_constant(CollectedHeap::Parallel) \
+ declare_constant(CollectedHeap::G1) \
+ declare_constant(CollectedHeap::Epsilon) \
+ declare_constant(CollectedHeap::Z) \
+ declare_constant(CollectedHeap::Shenandoah) \
+ \
declare_constant(vmIntrinsics::FIRST_MH_SIG_POLY) \
declare_constant(vmIntrinsics::LAST_MH_SIG_POLY) \
declare_constant(vmIntrinsics::_invokeGeneric) \
diff --git a/src/hotspot/share/jvmci/vmSymbols_jvmci.hpp b/src/hotspot/share/jvmci/vmSymbols_jvmci.hpp
index 4d0b167bb433d..801c1cdd2b171 100644
--- a/src/hotspot/share/jvmci/vmSymbols_jvmci.hpp
+++ b/src/hotspot/share/jvmci/vmSymbols_jvmci.hpp
@@ -103,6 +103,7 @@
template(visitFrame_signature, "(Ljdk/vm/ci/code/stack/InspectedFrame;)Ljava/lang/Object;") \
template(compileMethod_name, "compileMethod") \
template(compileMethod_signature, "(Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethod;IJI)Ljdk/vm/ci/hotspot/HotSpotCompilationRequestResult;") \
+ template(isGCSupported_name, "isGCSupported") \
template(encodeThrowable_name, "encodeThrowable") \
template(encodeThrowable_signature, "(Ljava/lang/Throwable;)Ljava/lang/String;") \
template(decodeThrowable_name, "decodeThrowable") \
diff --git a/src/hotspot/share/logging/logTag.hpp b/src/hotspot/share/logging/logTag.hpp
index fea94d89d2d37..d558159ddb77d 100644
--- a/src/hotspot/share/logging/logTag.hpp
+++ b/src/hotspot/share/logging/logTag.hpp
@@ -94,6 +94,7 @@
LOG_TAG(jfr) \
LOG_TAG(jit) \
LOG_TAG(jni) \
+ LOG_TAG(jvmci) \
LOG_TAG(jvmti) \
LOG_TAG(lambda) \
LOG_TAG(library) \
diff --git a/src/hotspot/share/prims/whitebox.cpp b/src/hotspot/share/prims/whitebox.cpp
index 9640c9e04a7f5..ffcddade86cc0 100644
--- a/src/hotspot/share/prims/whitebox.cpp
+++ b/src/hotspot/share/prims/whitebox.cpp
@@ -108,6 +108,10 @@
#include "services/memTracker.hpp"
#include "utilities/nativeCallStack.hpp"
#endif // INCLUDE_NMT
+#if INCLUDE_JVMCI
+#include "jvmci/jvmciEnv.hpp"
+#include "jvmci/jvmciRuntime.hpp"
+#endif
#if INCLUDE_AOT
#include "aot/aotLoader.hpp"
#endif // INCLUDE_AOT
@@ -354,6 +358,16 @@ WB_ENTRY(jboolean, WB_IsGCSupported(JNIEnv* env, jobject o, jint name))
return GCConfig::is_gc_supported((CollectedHeap::Name)name);
WB_END
+WB_ENTRY(jboolean, WB_IsGCSupportedByJVMCICompiler(JNIEnv* env, jobject o, jint name))
+#if INCLUDE_JVMCI
+ if (EnableJVMCI) {
+ JVMCIEnv jvmciEnv(thread, env, __FILE__, __LINE__);
+ return jvmciEnv.runtime()->is_gc_supported(&jvmciEnv, (CollectedHeap::Name)name);
+ }
+#endif
+ return false;
+WB_END
+
WB_ENTRY(jboolean, WB_IsGCSelected(JNIEnv* env, jobject o, jint name))
return GCConfig::is_gc_selected((CollectedHeap::Name)name);
WB_END
@@ -1945,6 +1959,14 @@ WB_ENTRY(jboolean, WB_isC2OrJVMCIIncludedInVmBuild(JNIEnv* env))
#endif
WB_END
+WB_ENTRY(jboolean, WB_IsJVMCISupportedByGC(JNIEnv* env))
+#if INCLUDE_JVMCI
+ return JVMCIGlobals::gc_supports_jvmci();
+#else
+ return false;
+#endif
+WB_END
+
WB_ENTRY(jboolean, WB_IsJavaHeapArchiveSupported(JNIEnv* env))
return HeapShared::is_heap_object_archiving_allowed();
WB_END
@@ -2508,6 +2530,7 @@ static JNINativeMethod methods[] = {
{CC"isCDSIncludedInVmBuild", CC"()Z", (void*)&WB_IsCDSIncludedInVmBuild },
{CC"isJFRIncludedInVmBuild", CC"()Z", (void*)&WB_IsJFRIncludedInVmBuild },
{CC"isC2OrJVMCIIncludedInVmBuild", CC"()Z", (void*)&WB_isC2OrJVMCIIncludedInVmBuild },
+ {CC"isJVMCISupportedByGC", CC"()Z", (void*)&WB_IsJVMCISupportedByGC},
{CC"isJavaHeapArchiveSupported", CC"()Z", (void*)&WB_IsJavaHeapArchiveSupported },
{CC"cdsMemoryMappingFailed", CC"()Z", (void*)&WB_CDSMemoryMappingFailed },
@@ -2520,6 +2543,7 @@ static JNINativeMethod methods[] = {
(void*)&WB_AddCompilerDirective },
{CC"removeCompilerDirective", CC"(I)V", (void*)&WB_RemoveCompilerDirective },
{CC"isGCSupported", CC"(I)Z", (void*)&WB_IsGCSupported},
+ {CC"isGCSupportedByJVMCICompiler", CC"(I)Z", (void*)&WB_IsGCSupportedByJVMCICompiler},
{CC"isGCSelected", CC"(I)Z", (void*)&WB_IsGCSelected},
{CC"isGCSelectedErgonomically", CC"()Z", (void*)&WB_IsGCSelectedErgonomically},
{CC"supportsConcurrentGCBreakpoints", CC"()Z", (void*)&WB_SupportsConcurrentGCBreakpoints},
diff --git a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCICompilerConfig.java b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCICompilerConfig.java
index 9bfb3050b6b99..c84fe09f2b5d4 100644
--- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCICompilerConfig.java
+++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCICompilerConfig.java
@@ -69,6 +69,11 @@ public String getCompilerName() {
public JVMCICompiler createCompiler(JVMCIRuntime rt) {
return this;
}
+
+ @Override
+ public boolean isGCSupported(int gcIdentifier) {
+ return false;
+ }
}
/**
diff --git a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java
index 23ec67eb89ec2..442c93164ca5d 100644
--- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java
+++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java
@@ -712,6 +712,11 @@ static class ErrorCreatingCompiler implements JVMCICompiler {
public CompilationRequestResult compileMethod(CompilationRequest request) {
throw t;
}
+
+ @Override
+ public boolean isGCSupported(int gcIdentifier) {
+ return false;
+ }
}
@Override
@@ -814,6 +819,12 @@ private HotSpotCompilationRequestResult compileMethod(HotSpotResolvedJavaMethod
return hsResult;
}
+ @SuppressWarnings("try")
+ @VMEntryPoint
+ private boolean isGCSupported(int gcIdentifier) {
+ return getCompiler().isGCSupported(gcIdentifier);
+ }
+
/**
* Guard to ensure shut down actions are performed at most once.
*/
diff --git a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCICompiler.java b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCICompiler.java
index 8aa5df1bf8c3c..bbb9c79e9f56a 100644
--- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCICompiler.java
+++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCICompiler.java
@@ -33,4 +33,15 @@ public interface JVMCICompiler {
* install it in the code cache if the compilation is successful.
*/
CompilationRequestResult compileMethod(CompilationRequest request);
+
+ /**
+ * Determines if this compiler supports the {@code gcIdentifier} garbage collector. The default
+ * implementation of this method returns true as that is the effective answer given by a
+ * {@link JVMCICompiler} before this method was added.
+ *
+ * @param gcIdentifier a VM dependent GC identifier
+ */
+ default boolean isGCSupported(int gcIdentifier) {
+ return true;
+ }
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompiler.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompiler.java
index f61528b37b05e..3c054bdd90504 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompiler.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompiler.java
@@ -43,6 +43,7 @@
import org.graalvm.compiler.debug.DebugHandlersFactory;
import org.graalvm.compiler.debug.DebugOptions;
import org.graalvm.compiler.hotspot.CompilationCounters.Options;
+import org.graalvm.compiler.hotspot.HotSpotGraalRuntime.HotSpotGC;
import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
import org.graalvm.compiler.hotspot.phases.OnStackReplacementPhase;
import org.graalvm.compiler.java.GraphBuilderPhase;
@@ -323,4 +324,13 @@ public void formatTo(Formatter buf, int flags, int width, int precision) {
}
};
}
+
+ @Override
+ public boolean isGCSupported(int gcIdentifier) {
+ HotSpotGC gc = HotSpotGC.forName(gcIdentifier, graalRuntime.getVMConfig());
+ if (gc != null) {
+ return gc.supported;
+ }
+ return false;
+ }
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java
index 3e1917b23d84c..d89ba75305748 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java
@@ -247,38 +247,59 @@ public GlobalMetrics getMetricValues() {
}
/**
- * Constants denoting the GC algorithms available in HotSpot.
+ * Constants denoting the GC algorithms available in HotSpot. The names of the constants match
+ * the constants in the {@code CollectedHeap::Name} C++ enum.
*/
public enum HotSpotGC {
// Supported GCs
- Serial(true, "UseSerialGC", true),
- Parallel(true, "UseParallelGC", true, "UseParallelOldGC", JDK < 15, "UseParNewGC", JDK < 10),
- CMS(true, "UseConcMarkSweepGC", JDK < 14),
- G1(true, "UseG1GC", true),
+ Serial(true, JDK >= 11, "UseSerialGC", true),
+ Parallel(true, JDK >= 11, "UseParallelGC", true, "UseParallelOldGC", JDK < 15, "UseParNewGC", JDK < 10),
+ CMS(true, JDK >= 11 && JDK <= 14, "UseConcMarkSweepGC", JDK < 14),
+ G1(true, JDK >= 11, "UseG1GC", true),
// Unsupported GCs
- Epsilon(false, "UseEpsilonGC", JDK >= 11),
- Z(false, "UseZGC", JDK >= 11);
+ Epsilon(false, JDK >= 11, "UseEpsilonGC", JDK >= 11),
+ Z(false, JDK >= 11, "UseZGC", JDK >= 11),
+ Shenandoah(false, JDK >= 12, "UseShenandoahGC", JDK >= 12);
- HotSpotGC(boolean supported,
+ HotSpotGC(boolean supported, boolean expectNamePresent,
String flag1, boolean expectFlagPresent1,
String flag2, boolean expectFlagPresent2,
String flag3, boolean expectFlagPresent3) {
this.supported = supported;
+ this.expectNamePresent = expectNamePresent;
this.expectFlagsPresent = new boolean[]{expectFlagPresent1, expectFlagPresent2, expectFlagPresent3};
this.flags = new String[]{flag1, flag2, flag3};
}
- HotSpotGC(boolean supported, String flag, boolean expectFlagPresent) {
+ HotSpotGC(boolean supported, boolean expectNamePresent, String flag, boolean expectFlagPresent) {
this.supported = supported;
+ this.expectNamePresent = expectNamePresent;
this.expectFlagsPresent = new boolean[]{expectFlagPresent};
this.flags = new String[]{flag};
}
+ /**
+ * Specifies if this GC supported by Graal.
+ */
final boolean supported;
- final boolean[] expectFlagsPresent;
+
+ /**
+ * Specifies if {@link #name()} is expected to be present in the {@code CollectedHeap::Name}
+ * C++ enum.
+ */
+ final boolean expectNamePresent;
+
+ /**
+ * The VM flags that will select this GC.
+ */
private final String[] flags;
+ /**
+ * Specifies which {@link #flags} are expected to be present in the VM.
+ */
+ final boolean[] expectFlagsPresent;
+
public boolean isSelected(GraalHotSpotVMConfig config) {
boolean selected = false;
for (int i = 0; i < flags.length; i++) {
@@ -293,6 +314,20 @@ public boolean isSelected(GraalHotSpotVMConfig config) {
}
return selected;
}
+
+ /**
+ * Gets the GC matching {@code name}.
+ *
+ * @param name the ordinal of a {@code CollectedHeap::Name} value
+ */
+ static HotSpotGC forName(int name, GraalHotSpotVMConfig config) {
+ for (HotSpotGC gc : HotSpotGC.values()) {
+ if (config.getConstant("CollectedHeap::" + gc.name(), Integer.class, -1, gc.expectNamePresent) == name) {
+ return gc;
+ }
+ }
+ return null;
+ }
}
private HotSpotGC getSelectedGC() throws GraalError {
diff --git a/test/jtreg-ext/requires/VMProps.java b/test/jtreg-ext/requires/VMProps.java
index 68a6f1e3f88ca..599bf969efbb6 100644
--- a/test/jtreg-ext/requires/VMProps.java
+++ b/test/jtreg-ext/requires/VMProps.java
@@ -239,18 +239,12 @@ protected String vmJvmci() {
return "false";
}
- switch (GC.selected()) {
- case Serial:
- case Parallel:
- case G1:
- // These GCs are supported with JVMCI
- return "true";
- default:
- break;
+ // Not all GCs have full JVMCI support
+ if (!WB.isJVMCISupportedByGC()) {
+ return "false";
}
- // Every other GC is not supported
- return "false";
+ return "true";
}
/**
@@ -271,21 +265,6 @@ protected String cpuFeatures() {
return CPUInfo.getFeatures().toString();
}
- private boolean isGcSupportedByGraal(GC gc) {
- switch (gc) {
- case Serial:
- case Parallel:
- case G1:
- return true;
- case Epsilon:
- case Z:
- case Shenandoah:
- return false;
- default:
- throw new IllegalStateException("Unknown GC " + gc.name());
- }
- }
-
/**
* For all existing GC sets vm.gc.X property.
* Example vm.gc.G1=true means:
@@ -296,11 +275,11 @@ private boolean isGcSupportedByGraal(GC gc) {
* @param map - property-value pairs
*/
protected void vmGC(SafeMap map) {
- var isGraalEnabled = Compiler.isGraalEnabled();
+ var isJVMCIEnabled = Compiler.isJVMCIEnabled();
for (GC gc: GC.values()) {
map.put("vm.gc." + gc.name(),
() -> "" + (gc.isSupported()
- && (!isGraalEnabled || isGcSupportedByGraal(gc))
+ && (!isJVMCIEnabled || gc.isSupportedByJVMCICompiler())
&& (gc.isSelected() || GC.isSelectedErgonomically())));
}
}
diff --git a/test/lib/sun/hotspot/WhiteBox.java b/test/lib/sun/hotspot/WhiteBox.java
index 0c6ffed0b4a7f..fc34a795300c7 100644
--- a/test/lib/sun/hotspot/WhiteBox.java
+++ b/test/lib/sun/hotspot/WhiteBox.java
@@ -232,6 +232,7 @@ public Object[] parseCommandLine(String commandline, char delim, Dia
// Compiler
public native boolean isC2OrJVMCIIncludedInVmBuild();
+ public native boolean isJVMCISupportedByGC();
public native int matchesMethod(Executable method, String pattern);
public native int matchesInline(Executable method, String pattern);
@@ -415,6 +416,7 @@ public void clearInlineCaches(boolean preserve_static_stubs) {
// Don't use these methods directly
// Use sun.hotspot.gc.GC class instead.
public native boolean isGCSupported(int name);
+ public native boolean isGCSupportedByJVMCICompiler(int name);
public native boolean isGCSelected(int name);
public native boolean isGCSelectedErgonomically();
diff --git a/test/lib/sun/hotspot/code/Compiler.java b/test/lib/sun/hotspot/code/Compiler.java
index 3df802d462e55..99122bd93b8e9 100644
--- a/test/lib/sun/hotspot/code/Compiler.java
+++ b/test/lib/sun/hotspot/code/Compiler.java
@@ -43,6 +43,20 @@ public static boolean isC2OrJVMCIIncludedInVmBuild() {
return WB.isC2OrJVMCIIncludedInVmBuild();
}
+ /**
+ * Check if JVMCI is enabled.
+ *
+ * @return true if JVMCI is enabled
+ */
+ public static boolean isJVMCIEnabled() {
+ Boolean enableJvmci = WB.getBooleanVMFlag("EnableJVMCI");
+ if (enableJvmci == null || !enableJvmci) {
+ return false;
+ }
+
+ return true;
+ }
+
/**
* Check if Graal is used as JIT compiler.
*
diff --git a/test/lib/sun/hotspot/gc/GC.java b/test/lib/sun/hotspot/gc/GC.java
index 19fb51f26d180..99b33aa2ac08d 100644
--- a/test/lib/sun/hotspot/gc/GC.java
+++ b/test/lib/sun/hotspot/gc/GC.java
@@ -55,6 +55,13 @@ public boolean isSupported() {
return WB.isGCSupported(name);
}
+ /**
+ * @return true if this GC is supported by the JVMCI compiler
+ */
+ public boolean isSupportedByJVMCICompiler() {
+ return WB.isGCSupportedByJVMCICompiler(name);
+ }
+
/**
* @return true if this GC is currently selected/used
*/
From 66a2e70985fcdb8e0b91b05fbeae825db6ae9c78 Mon Sep 17 00:00:00 2001
From: Evan Whelan
Date: Thu, 3 Dec 2020 15:28:42 +0000
Subject: [PATCH 044/504] 8255845: Memory leak in imageFile.cpp
Reviewed-by: jlaskey, sundar
---
src/java.base/share/native/libjimage/imageFile.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/java.base/share/native/libjimage/imageFile.cpp b/src/java.base/share/native/libjimage/imageFile.cpp
index 001d7d8fcf3b7..0b7b92960b9bf 100644
--- a/src/java.base/share/native/libjimage/imageFile.cpp
+++ b/src/java.base/share/native/libjimage/imageFile.cpp
@@ -178,8 +178,8 @@ const char* ImageModuleData::package_to_module(const char* package_name) {
// retrieve package location
ImageLocation location;
bool found = _image_file->find_location(path, location);
+ delete[] path;
if (!found) {
- delete[] path;
return NULL;
}
From b170c8376d683a18acf786ac69a462da0dbf1386 Mon Sep 17 00:00:00 2001
From: Julia Boes
Date: Thu, 3 Dec 2020 15:48:03 +0000
Subject: [PATCH 045/504] 8257591: Remove suppression of record preview related
warnings in java.lang
Reviewed-by: chegar
---
src/java.base/share/classes/java/lang/Class.java | 2 --
.../share/classes/java/lang/reflect/RecordComponent.java | 4 +---
.../share/classes/java/lang/runtime/ObjectMethods.java | 3 +--
test/jdk/java/lang/invoke/unreflect/UnreflectTest.java | 5 ++---
.../java/lang/reflect/records/RecordPermissionsTest.java | 6 +++---
.../jdk/java/lang/reflect/records/RecordReflectionTest.java | 6 +++---
6 files changed, 10 insertions(+), 16 deletions(-)
diff --git a/src/java.base/share/classes/java/lang/Class.java b/src/java.base/share/classes/java/lang/Class.java
index d1a9f63cc69d4..3a8cae6e2a69b 100644
--- a/src/java.base/share/classes/java/lang/Class.java
+++ b/src/java.base/share/classes/java/lang/Class.java
@@ -269,7 +269,6 @@ public String toString() {
*
* @since 1.8
*/
- @SuppressWarnings("preview")
public String toGenericString() {
if (isPrimitive()) {
return toString();
@@ -3548,7 +3547,6 @@ private static Constructor[] copyConstructors(Constructor[] arg) {
private native Method[] getDeclaredMethods0(boolean publicOnly);
private native Constructor[] getDeclaredConstructors0(boolean publicOnly);
private native Class>[] getDeclaredClasses0();
- @SuppressWarnings("preview")
private native RecordComponent[] getRecordComponents0();
private native boolean isRecord0();
diff --git a/src/java.base/share/classes/java/lang/reflect/RecordComponent.java b/src/java.base/share/classes/java/lang/reflect/RecordComponent.java
index 7079f3d28f75b..50d36418631a0 100644
--- a/src/java.base/share/classes/java/lang/reflect/RecordComponent.java
+++ b/src/java.base/share/classes/java/lang/reflect/RecordComponent.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 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
@@ -57,7 +57,6 @@ public final class RecordComponent implements AnnotatedElement {
private transient FieldRepository genericInfo;
private byte[] annotations;
private byte[] typeAnnotations;
- @SuppressWarnings("preview")
private RecordComponent root;
// only the JVM can create record components
@@ -189,7 +188,6 @@ private Map, Annotation> declaredAnnotations() {
if ((declAnnos = declaredAnnotations) == null) {
synchronized (this) {
if ((declAnnos = declaredAnnotations) == null) {
- @SuppressWarnings("preview")
RecordComponent root = this.root;
if (root != null) {
declAnnos = root.declaredAnnotations();
diff --git a/src/java.base/share/classes/java/lang/runtime/ObjectMethods.java b/src/java.base/share/classes/java/lang/runtime/ObjectMethods.java
index ad50a002f718e..54155c4e5bd54 100644
--- a/src/java.base/share/classes/java/lang/runtime/ObjectMethods.java
+++ b/src/java.base/share/classes/java/lang/runtime/ObjectMethods.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 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
@@ -72,7 +72,6 @@ private ObjectMethods() { }
static {
try {
- @SuppressWarnings("preview")
Class OBJECT_METHODS_CLASS = ObjectMethods.class;
MethodHandles.Lookup publicLookup = MethodHandles.publicLookup();
MethodHandles.Lookup lookup = MethodHandles.lookup();
diff --git a/test/jdk/java/lang/invoke/unreflect/UnreflectTest.java b/test/jdk/java/lang/invoke/unreflect/UnreflectTest.java
index 206287c57c663..31dc851f4ea0f 100644
--- a/test/jdk/java/lang/invoke/unreflect/UnreflectTest.java
+++ b/test/jdk/java/lang/invoke/unreflect/UnreflectTest.java
@@ -21,10 +21,10 @@
* questions.
*/
-/**
+/*
* @test
* @bug 8238358 8247444
- * @run testng/othervm --enable-preview UnreflectTest
+ * @run testng/othervm UnreflectTest
* @summary Test Lookup::unreflectSetter and Lookup::unreflectVarHandle on
* trusted final fields (declared in hidden classes and records)
*/
@@ -99,7 +99,6 @@ static record TestRecord(int i) {
* Test Lookup::unreflectSetter and Lookup::unreflectVarHandle that
* cannot write the value of a non-static final field in a record class
*/
- @SuppressWarnings("preview")
public void testFieldsInRecordClass() throws Throwable {
assertTrue(TestRecord.class.isRecord());
Object o = new TestRecord(1);
diff --git a/test/jdk/java/lang/reflect/records/RecordPermissionsTest.java b/test/jdk/java/lang/reflect/records/RecordPermissionsTest.java
index d6947a7519f9b..46180ef143901 100644
--- a/test/jdk/java/lang/reflect/records/RecordPermissionsTest.java
+++ b/test/jdk/java/lang/reflect/records/RecordPermissionsTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 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
@@ -25,8 +25,8 @@
* @test
* @bug 8235369
* @summary Security manager checks for record related core reflection
- * @compile --enable-preview -source ${jdk.version} RecordPermissionsTest.java
- * @run testng/othervm/java.security.policy=allPermissions.policy --enable-preview RecordPermissionsTest
+ * @compile RecordPermissionsTest.java
+ * @run testng/othervm/java.security.policy=allPermissions.policy RecordPermissionsTest
*/
import java.net.URL;
diff --git a/test/jdk/java/lang/reflect/records/RecordReflectionTest.java b/test/jdk/java/lang/reflect/records/RecordReflectionTest.java
index b121bac5ef589..5968b4813ea8f 100644
--- a/test/jdk/java/lang/reflect/records/RecordReflectionTest.java
+++ b/test/jdk/java/lang/reflect/records/RecordReflectionTest.java
@@ -25,9 +25,9 @@
* @test
* @bug 8235369 8235550 8247444
* @summary reflection test for records
- * @compile --enable-preview -source ${jdk.version} RecordReflectionTest.java
- * @run testng/othervm --enable-preview RecordReflectionTest
- * @run testng/othervm/java.security.policy=allPermissions.policy --enable-preview RecordReflectionTest
+ * @compile RecordReflectionTest.java
+ * @run testng/othervm RecordReflectionTest
+ * @run testng/othervm/java.security.policy=allPermissions.policy RecordReflectionTest
*/
import java.lang.annotation.*;
From e83639620739749834d91e026cfecb56529aa295 Mon Sep 17 00:00:00 2001
From: Evgeny Astigeevich
Date: Thu, 3 Dec 2020 15:55:32 +0000
Subject: [PATCH 046/504] 8257436: [aarch64] Regressions in
ArrayCopyUnalignedDst.testByte/testChar for 65-78 bytes when
UseSIMDForMemoryOps is on
Reviewed-by: simonis
---
.../cpu/aarch64/stubGenerator_aarch64.cpp | 25 +++++++++++++++++--
1 file changed, 23 insertions(+), 2 deletions(-)
diff --git a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp
index c1b25a076e5b6..3022aacd40db5 100644
--- a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp
+++ b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp
@@ -1094,10 +1094,10 @@ class StubGenerator: public StubCodeGenerator {
Register count, Register tmp, int step) {
copy_direction direction = step < 0 ? copy_backwards : copy_forwards;
bool is_backwards = step < 0;
- int granularity = uabs(step);
+ unsigned int granularity = uabs(step);
const Register t0 = r3, t1 = r4;
- // <= 96 bytes do inline. Direction doesn't matter because we always
+ // <= 80 (or 96 for SIMD) bytes do inline. Direction doesn't matter because we always
// load all the data before writing anything
Label copy4, copy8, copy16, copy32, copy80, copy_big, finish;
const Register t2 = r5, t3 = r6, t4 = r7, t5 = r8;
@@ -1154,7 +1154,28 @@ class StubGenerator: public StubCodeGenerator {
if (UseSIMDForMemoryOps) {
__ ldpq(v0, v1, Address(s, 0));
__ ldpq(v2, v3, Address(s, 32));
+ // Unaligned pointers can be an issue for copying.
+ // The issue has more chances to happen when granularity of data is
+ // less than 4(sizeof(jint)). Pointers for arrays of jint are at least
+ // 4 byte aligned. Pointers for arrays of jlong are 8 byte aligned.
+ // The most performance drop has been seen for the range 65-80 bytes.
+ // For such cases using the pair of ldp/stp instead of the third pair of
+ // ldpq/stpq fixes the performance issue.
+ if (granularity < sizeof (jint)) {
+ Label copy96;
+ __ cmp(count, u1(80/granularity));
+ __ br(Assembler::HI, copy96);
+ __ ldp(t0, t1, Address(send, -16));
+
+ __ stpq(v0, v1, Address(d, 0));
+ __ stpq(v2, v3, Address(d, 32));
+ __ stp(t0, t1, Address(dend, -16));
+ __ b(finish);
+
+ __ bind(copy96);
+ }
__ ldpq(v4, v5, Address(send, -32));
+
__ stpq(v0, v1, Address(d, 0));
__ stpq(v2, v3, Address(d, 32));
__ stpq(v4, v5, Address(dend, -32));
From 70517c83c2784a781d85dc903a787ebeb64fdb0c Mon Sep 17 00:00:00 2001
From: Anthony Scarpino
Date: Thu, 3 Dec 2020 16:29:16 +0000
Subject: [PATCH 047/504] 8257642: CipherByteBufferOverwriteTest copyright
issue
Reviewed-by: xuelei, wetmore
---
.../javax/crypto/CipherSpi/CipherByteBufferOverwriteTest.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/jdk/javax/crypto/CipherSpi/CipherByteBufferOverwriteTest.java b/test/jdk/javax/crypto/CipherSpi/CipherByteBufferOverwriteTest.java
index 260d667714744..c1acd17712331 100644
--- a/test/jdk/javax/crypto/CipherSpi/CipherByteBufferOverwriteTest.java
+++ b/test/jdk/javax/crypto/CipherSpi/CipherByteBufferOverwriteTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 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
From 6c9482eef5710e7e04279a6172d18e30b80502fa Mon Sep 17 00:00:00 2001
From: Vladimir Kozlov
Date: Thu, 3 Dec 2020 17:02:04 +0000
Subject: [PATCH 048/504] 8257561: Some code is not vectorized after 8251925
and 8250607
Reviewed-by: chagedorn, vlivanov, thartmann
---
src/hotspot/share/opto/cfgnode.cpp | 6 ++----
src/hotspot/share/opto/superword.cpp | 16 +++++++---------
2 files changed, 9 insertions(+), 13 deletions(-)
diff --git a/src/hotspot/share/opto/cfgnode.cpp b/src/hotspot/share/opto/cfgnode.cpp
index 3cf786fd13742..b70d279f270ec 100644
--- a/src/hotspot/share/opto/cfgnode.cpp
+++ b/src/hotspot/share/opto/cfgnode.cpp
@@ -1105,11 +1105,9 @@ const Type* PhiNode::Value(PhaseGVN* phase) const {
if (bt != BoolTest::ne) {
if (stride_t->hi_as_long() < 0) { // Down-counter loop
swap(lo, hi);
- return TypeInteger::make(MIN2(lo->lo_as_long(), hi->lo_as_long()), hi->hi_as_long(), 3,
- l->bt())->filter_speculative(_type);
+ return TypeInteger::make(MIN2(lo->lo_as_long(), hi->lo_as_long()), hi->hi_as_long(), 3, l->bt());
} else if (stride_t->lo_as_long() >= 0) {
- return TypeInteger::make(lo->lo_as_long(), MAX2(lo->hi_as_long(), hi->hi_as_long()), 3,
- l->bt())->filter_speculative(_type);
+ return TypeInteger::make(lo->lo_as_long(), MAX2(lo->hi_as_long(), hi->hi_as_long()), 3, l->bt());
}
}
}
diff --git a/src/hotspot/share/opto/superword.cpp b/src/hotspot/share/opto/superword.cpp
index 1da62777018ee..8c8f47c80a446 100644
--- a/src/hotspot/share/opto/superword.cpp
+++ b/src/hotspot/share/opto/superword.cpp
@@ -3995,16 +3995,14 @@ bool SWPointer::offset_plus_k(Node* n, bool negate) {
assert(!is_main_loop_member(n), "sanity");
n = n->in(1);
}
-
- // Check if 'n' can really be used as invariant (not in main loop and dominating the pre loop).
- if (invariant(n)) {
- _negate_invar = negate;
- _invar = n;
- NOT_PRODUCT(_tracer.offset_plus_k_10(n, _invar, _negate_invar, _offset);)
- return true;
- }
}
- return false;
+ // Check if 'n' can really be used as invariant (not in main loop and dominating the pre loop).
+ if (invariant(n)) {
+ _negate_invar = negate;
+ _invar = n;
+ NOT_PRODUCT(_tracer.offset_plus_k_10(n, _invar, _negate_invar, _offset);)
+ return true;
+ }
}
NOT_PRODUCT(_tracer.offset_plus_k_11(n);)
From d3f3c322829c6cd595a6979a2147b3bcfc458d9d Mon Sep 17 00:00:00 2001
From: Volker Simonis
Date: Thu, 3 Dec 2020 18:02:05 +0000
Subject: [PATCH 049/504] 8255742: PrintInlining as compiler directive doesn't
print virtual calls
Reviewed-by: thartmann, kvn
---
src/hotspot/share/opto/doCall.cpp | 4 +-
.../compiler/inlining/PrintInlining.java | 98 +++++++++++++++++++
2 files changed, 101 insertions(+), 1 deletion(-)
create mode 100644 test/hotspot/jtreg/compiler/inlining/PrintInlining.java
diff --git a/src/hotspot/share/opto/doCall.cpp b/src/hotspot/share/opto/doCall.cpp
index 13053bb6317b2..c906b72b9d0a3 100644
--- a/src/hotspot/share/opto/doCall.cpp
+++ b/src/hotspot/share/opto/doCall.cpp
@@ -355,7 +355,9 @@ CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool
// Use a more generic tactic, like a simple call.
if (call_does_dispatch) {
const char* msg = "virtual call";
- if (PrintInlining) print_inlining(callee, jvms->depth() - 1, jvms->bci(), msg);
+ if (C->print_inlining()) {
+ print_inlining(callee, jvms->depth() - 1, jvms->bci(), msg);
+ }
C->log_inline_failure(msg);
return CallGenerator::for_virtual_call(callee, vtable_index);
} else {
diff --git a/test/hotspot/jtreg/compiler/inlining/PrintInlining.java b/test/hotspot/jtreg/compiler/inlining/PrintInlining.java
new file mode 100644
index 0000000000000..7feaa300c6d11
--- /dev/null
+++ b/test/hotspot/jtreg/compiler/inlining/PrintInlining.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 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
+ * @bug 8255742
+ * @summary PrintInlining as compiler directive doesn't print virtual calls
+ * @modules java.base/jdk.internal.misc
+ * @library /test/lib
+ *
+ * @run driver compiler.inlining.PrintInlining
+ */
+
+package compiler.inlining;
+
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+public class PrintInlining {
+
+ static void test(String option) throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+ "-XX:+IgnoreUnrecognizedVMOptions", "-showversion",
+ "-server", "-XX:-TieredCompilation", "-Xbatch", "-XX:-UseOnStackReplacement",
+ "-XX:CompileCommand=dontinline,*::bar",
+ "-XX:CompileCommand=compileonly,*::foo",
+ "-XX:+PrintCompilation", "-XX:+UnlockDiagnosticVMOptions", option,
+ Launcher.class.getName());
+
+ OutputAnalyzer analyzer = new OutputAnalyzer(pb.start());
+
+ analyzer.shouldHaveExitValue(0);
+
+ // The test is applicable only to C2 (present in Server VM).
+ if (analyzer.getStderr().contains("Server VM")) {
+ analyzer.outputTo(System.out);
+ if (analyzer.asLines().stream()
+ .filter(s -> s.matches(".*A::bar.+virtual call.*"))
+ .count() != 1) {
+ throw new Exception("'" + option + "' didn't print virtual call.");
+ }
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ test("-XX:+PrintInlining");
+ test("-XX:CompileCommand=option,*::foo,PrintInlining");
+ }
+
+ static class A {
+ void bar() {}
+ }
+
+ static class B extends A {
+ void bar() {}
+ }
+
+ static class C extends A {
+ void bar() {}
+ }
+
+ static class D extends A {
+ void bar() {}
+ }
+
+ static void foo(A a) {
+ a.bar();
+ }
+
+ static class Launcher {
+ public static void main(String[] args) throws Exception {
+ A[] as = { new B(), new C(), new D() };
+ for (int i = 0; i < 20_000; i++) {
+ foo(as[i % 3]);
+ }
+ }
+ }
+}
From 55f5542ca2104df91e14693534cc7b3c36e81953 Mon Sep 17 00:00:00 2001
From: Anthony Scarpino
Date: Thu, 3 Dec 2020 18:05:53 +0000
Subject: [PATCH 050/504] 8026976: ECParameters, Point does not match field
size
Reviewed-by: xuelei
---
.../classes/sun/security/pkcs11/P11ECKeyFactory.java | 10 ++++++++--
test/jdk/ProblemList.txt | 1 -
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11ECKeyFactory.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11ECKeyFactory.java
index f26ab6eb921e9..79daca151f17a 100644
--- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11ECKeyFactory.java
+++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11ECKeyFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -294,7 +294,13 @@ T implGetPublicKeySpec(P11Key key, Class keySpec,
try {
token.p11.C_GetAttributeValue(session[0].id(), keyID, attributes);
ECParameterSpec params = decodeParameters(attributes[1].getByteArray());
- ECPoint point = decodePoint(attributes[0].getByteArray(), params.getCurve());
+ ECPoint point;
+
+ if (!token.config.getUseEcX963Encoding()) {
+ point = decodePoint(new DerValue(attributes[0].getByteArray()).getOctetString(), params.getCurve());
+ } else {
+ point = decodePoint(attributes[0].getByteArray(), params.getCurve());
+ }
return keySpec.cast(new ECPublicKeySpec(point, params));
} catch (IOException e) {
throw new InvalidKeySpecException("Could not parse key", e);
diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt
index 9dc6a663dd882..0bd8eb8f5ab6f 100644
--- a/test/jdk/ProblemList.txt
+++ b/test/jdk/ProblemList.txt
@@ -661,7 +661,6 @@ com/sun/nio/sctp/SctpChannel/SocketOptionTests.java 8141694 linux-al
# jdk_security
-sun/security/pkcs11/ec/TestKeyFactory.java 8026976 generic-all
sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java 8161536 generic-all
sun/security/tools/keytool/ListKeychainStore.sh 8156889 macosx-all
From e29ee5b8a5a6c098871df885439412d872f669e8 Mon Sep 17 00:00:00 2001
From: Zhengyu Gu
Date: Thu, 3 Dec 2020 18:42:42 +0000
Subject: [PATCH 051/504] 8257641: Shenandoah: Query
is_at_shenandoah_safepoint() from control thread should return false
Reviewed-by: shade
---
src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp | 1 +
src/hotspot/share/gc/shenandoah/shenandoahUtils.hpp | 8 +++++++-
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp
index 3a109a2267324..90d809be6f481 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp
@@ -122,6 +122,7 @@ class ShenandoahHeap : public CollectedHeap {
friend class ShenandoahGCSession;
friend class ShenandoahGCStateResetter;
friend class ShenandoahParallelObjectIterator;
+ friend class ShenandoahSafepoint;
// ---------- Locks that guard important data structures in Heap
//
private:
diff --git a/src/hotspot/share/gc/shenandoah/shenandoahUtils.hpp b/src/hotspot/share/gc/shenandoah/shenandoahUtils.hpp
index 2f4fde1364115..c09507529fa46 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoahUtils.hpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahUtils.hpp
@@ -147,9 +147,15 @@ class ShenandoahSafepoint : public AllStatic {
static inline bool is_at_shenandoah_safepoint() {
if (!SafepointSynchronize::is_at_safepoint()) return false;
+ Thread* const thr = Thread::current();
+ // Shenandoah GC specific safepoints are scheduled by control thread.
+ // So if we are enter here from control thread, then we are definitely not
+ // at Shenandoah safepoint, but at something else.
+ if (thr == ShenandoahHeap::heap()->control_thread()) return false;
+
// This is not VM thread, cannot see what VM thread is doing,
// so pretend this is a proper Shenandoah safepoint
- if (!Thread::current()->is_VM_thread()) return true;
+ if (!thr->is_VM_thread()) return true;
// Otherwise check we are at proper operation type
VM_Operation* vm_op = VMThread::vm_operation();
From 805d05812c5e831947197419d163f9c83d55634a Mon Sep 17 00:00:00 2001
From: Amit Pawar
Date: Thu, 3 Dec 2020 19:05:04 +0000
Subject: [PATCH 052/504] 8254699: Suboptimal PreTouchParallelChunkSize
defaults and limits
Reviewed-by: tschatzl, sjohanss
---
src/hotspot/os/aix/globals_aix.hpp | 1 +
src/hotspot/os/bsd/globals_bsd.hpp | 1 +
src/hotspot/os/linux/globals_linux.hpp | 1 +
src/hotspot/os/windows/globals_windows.hpp | 1 +
src/hotspot/share/gc/shared/gc_globals.hpp | 4 ++--
5 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/src/hotspot/os/aix/globals_aix.hpp b/src/hotspot/os/aix/globals_aix.hpp
index 1203b09c883e1..a047e79b695fa 100644
--- a/src/hotspot/os/aix/globals_aix.hpp
+++ b/src/hotspot/os/aix/globals_aix.hpp
@@ -86,6 +86,7 @@
// UseLargePages means nothing, for now, on AIX.
// Use Use64KPages or Use16MPages instead.
+define_pd_global(size_t, PreTouchParallelChunkSize, 1 * G);
define_pd_global(bool, UseLargePages, false);
define_pd_global(bool, UseLargePagesIndividualAllocation, false);
define_pd_global(bool, UseThreadPriorities, true) ;
diff --git a/src/hotspot/os/bsd/globals_bsd.hpp b/src/hotspot/os/bsd/globals_bsd.hpp
index b36173655df8a..2204adc7abac6 100644
--- a/src/hotspot/os/bsd/globals_bsd.hpp
+++ b/src/hotspot/os/bsd/globals_bsd.hpp
@@ -42,6 +42,7 @@
// Defines Bsd-specific default values. The flags are available on all
// platforms, but they may have different default values on other platforms.
//
+define_pd_global(size_t, PreTouchParallelChunkSize, 1 * G);
define_pd_global(bool, UseLargePages, false);
define_pd_global(bool, UseLargePagesIndividualAllocation, false);
define_pd_global(bool, UseThreadPriorities, true) ;
diff --git a/src/hotspot/os/linux/globals_linux.hpp b/src/hotspot/os/linux/globals_linux.hpp
index a37fd28f0e476..72915b5afbbbe 100644
--- a/src/hotspot/os/linux/globals_linux.hpp
+++ b/src/hotspot/os/linux/globals_linux.hpp
@@ -90,6 +90,7 @@
// Defines Linux-specific default values. The flags are available on all
// platforms, but they may have different default values on other platforms.
//
+define_pd_global(size_t, PreTouchParallelChunkSize, 4 * M);
define_pd_global(bool, UseLargePages, false);
define_pd_global(bool, UseLargePagesIndividualAllocation, false);
define_pd_global(bool, UseThreadPriorities, true) ;
diff --git a/src/hotspot/os/windows/globals_windows.hpp b/src/hotspot/os/windows/globals_windows.hpp
index 61157041f887b..7ddf3c9131b8a 100644
--- a/src/hotspot/os/windows/globals_windows.hpp
+++ b/src/hotspot/os/windows/globals_windows.hpp
@@ -45,6 +45,7 @@ product(bool, UseOSErrorReporting, false, \
// Defines Windows-specific default values. The flags are available on all
// platforms, but they may have different default values on other platforms.
//
+define_pd_global(size_t, PreTouchParallelChunkSize, 1 * G);
define_pd_global(bool, UseLargePages, false);
define_pd_global(bool, UseLargePagesIndividualAllocation, true);
define_pd_global(bool, UseThreadPriorities, true) ;
diff --git a/src/hotspot/share/gc/shared/gc_globals.hpp b/src/hotspot/share/gc/shared/gc_globals.hpp
index 9aeb8a4ba2ef0..aca8d6b6c349f 100644
--- a/src/hotspot/share/gc/shared/gc_globals.hpp
+++ b/src/hotspot/share/gc/shared/gc_globals.hpp
@@ -200,9 +200,9 @@
product(bool, AlwaysPreTouch, false, \
"Force all freshly committed pages to be pre-touched") \
\
- product(size_t, PreTouchParallelChunkSize, 1 * G, \
+ product_pd(size_t, PreTouchParallelChunkSize, \
"Per-thread chunk size for parallel memory pre-touch.") \
- range(1, SIZE_MAX / 2) \
+ range(4*K, SIZE_MAX / 2) \
\
/* where does the range max value of (max_jint - 1) come from? */ \
product(size_t, MarkStackSizeMax, NOT_LP64(4*M) LP64_ONLY(512*M), \
From 2b73f9929f89693b9fb09e368eae55f95c57002c Mon Sep 17 00:00:00 2001
From: Stuart Marks
Date: Thu, 3 Dec 2020 19:32:53 +0000
Subject: [PATCH 053/504] 8228615: Optional.empty doc should suggest using
isEmpty
Reviewed-by: lancea, bpb, naoto
---
src/java.base/share/classes/java/util/Optional.java | 6 +++---
src/java.base/share/classes/java/util/OptionalDouble.java | 6 +++---
src/java.base/share/classes/java/util/OptionalInt.java | 6 +++---
src/java.base/share/classes/java/util/OptionalLong.java | 6 +++---
4 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/src/java.base/share/classes/java/util/Optional.java b/src/java.base/share/classes/java/util/Optional.java
index 9533e35e60eda..af8ea6d1f98bf 100644
--- a/src/java.base/share/classes/java/util/Optional.java
+++ b/src/java.base/share/classes/java/util/Optional.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -74,9 +74,9 @@ public final class Optional {
*
* @apiNote
* Though it may be tempting to do so, avoid testing if an object is empty
- * by comparing with {@code ==} against instances returned by
+ * by comparing with {@code ==} or {@code !=} against instances returned by
* {@code Optional.empty()}. There is no guarantee that it is a singleton.
- * Instead, use {@link #isPresent()}.
+ * Instead, use {@link #isEmpty()} or {@link #isPresent()}.
*
* @param The type of the non-existent value
* @return an empty {@code Optional}
diff --git a/src/java.base/share/classes/java/util/OptionalDouble.java b/src/java.base/share/classes/java/util/OptionalDouble.java
index 9eb4d46e4b31f..7c8ed649cbeea 100644
--- a/src/java.base/share/classes/java/util/OptionalDouble.java
+++ b/src/java.base/share/classes/java/util/OptionalDouble.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -83,9 +83,9 @@ private OptionalDouble() {
*
* @apiNote
* Though it may be tempting to do so, avoid testing if an object is empty
- * by comparing with {@code ==} against instances returned by
+ * by comparing with {@code ==} or {@code !=} against instances returned by
* {@code OptionalDouble.empty()}. There is no guarantee that it is a singleton.
- * Instead, use {@link #isPresent()}.
+ * Instead, use {@link #isEmpty()} or {@link #isPresent()}.
*
* @return an empty {@code OptionalDouble}.
*/
diff --git a/src/java.base/share/classes/java/util/OptionalInt.java b/src/java.base/share/classes/java/util/OptionalInt.java
index 7f97200f58513..aa8a669d0105c 100644
--- a/src/java.base/share/classes/java/util/OptionalInt.java
+++ b/src/java.base/share/classes/java/util/OptionalInt.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -83,9 +83,9 @@ private OptionalInt() {
*
* @apiNote
* Though it may be tempting to do so, avoid testing if an object is empty
- * by comparing with {@code ==} against instances returned by
+ * by comparing with {@code ==} or {@code !=} against instances returned by
* {@code OptionalInt.empty()}. There is no guarantee that it is a singleton.
- * Instead, use {@link #isPresent()}.
+ * Instead, use {@link #isEmpty()} or {@link #isPresent()}.
*
* @return an empty {@code OptionalInt}
*/
diff --git a/src/java.base/share/classes/java/util/OptionalLong.java b/src/java.base/share/classes/java/util/OptionalLong.java
index dc25a52666c16..c18457358fe74 100644
--- a/src/java.base/share/classes/java/util/OptionalLong.java
+++ b/src/java.base/share/classes/java/util/OptionalLong.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -83,9 +83,9 @@ private OptionalLong() {
*
* @apiNote
* Though it may be tempting to do so, avoid testing if an object is empty
- * by comparing with {@code ==} against instances returned by
+ * by comparing with {@code ==} or {@code !=} against instances returned by
* {@code OptionalLong.empty()}. There is no guarantee that it is a singleton.
- * Instead, use {@link #isPresent()}.
+ * Instead, use {@link #isEmpty()} or {@link #isPresent()}.
*
* @return an empty {@code OptionalLong}.
*/
From 7c7facc234c9def1b4603cd5f8c8a4fc724c5870 Mon Sep 17 00:00:00 2001
From: Zhengyu Gu
Date: Thu, 3 Dec 2020 19:58:58 +0000
Subject: [PATCH 054/504] 8257701: Shenandoah: objArrayKlass metadata is not
marked with chunked arrays
Reviewed-by: shade
---
.../share/gc/shenandoah/shenandoahConcurrentMark.inline.hpp | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.inline.hpp
index 837c00de2b085..40e0957fa72e1 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.inline.hpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.inline.hpp
@@ -111,6 +111,11 @@ inline void ShenandoahConcurrentMark::do_chunked_array_start(ShenandoahObjToScan
objArrayOop array = objArrayOop(obj);
int len = array->length();
+ // Mark objArray klass metadata
+ if (Devirtualizer::do_metadata(cl)) {
+ Devirtualizer::do_klass(cl, array->klass());
+ }
+
if (len <= (int) ObjArrayMarkingStride*2) {
// A few slices only, process directly
array->oop_iterate_range(cl, 0, len);
From 85269470e530f820f9190ae799c459c6f65104c6 Mon Sep 17 00:00:00 2001
From: Sergey Bylokhov
Date: Thu, 3 Dec 2020 20:08:09 +0000
Subject: [PATCH 055/504] 6508941: java.awt.Desktop.open causes VM to crash
with video files sporadically
Reviewed-by: kizune, aivanov
---
.../native/libawt/windows/awt_Desktop.cpp | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Desktop.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Desktop.cpp
index 7fd94b70f4ced..73b3c51c79603 100644
--- a/src/java.desktop/windows/native/libawt/windows/awt_Desktop.cpp
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Desktop.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -85,13 +85,24 @@ JNIEXPORT jstring JNICALL Java_sun_awt_windows_WDesktopPeer_ShellExecute
// 6457572: ShellExecute possibly changes FPU control word - saving it here
unsigned oldcontrol87 = _control87(0, 0);
- HINSTANCE retval = ::ShellExecute(NULL, verb_c, fileOrUri_c, NULL, NULL, SW_SHOWNORMAL);
- DWORD error = ::GetLastError();
+ HRESULT hr = ::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED |
+ COINIT_DISABLE_OLE1DDE);
+ HINSTANCE retval;
+ DWORD error;
+ if (SUCCEEDED(hr)) {
+ retval = ::ShellExecute(NULL, verb_c, fileOrUri_c, NULL, NULL,
+ SW_SHOWNORMAL);
+ error = ::GetLastError();
+ ::CoUninitialize();
+ }
_control87(oldcontrol87, 0xffffffff);
JNU_ReleaseStringPlatformChars(env, fileOrUri_j, fileOrUri_c);
JNU_ReleaseStringPlatformChars(env, verb_j, verb_c);
+ if (FAILED(hr)) {
+ return JNU_NewStringPlatform(env, L"CoInitializeEx() failed.");
+ }
if ((int)((intptr_t)retval) <= 32) {
// ShellExecute failed.
LPTSTR buffer = NULL;
From c5b32b33eb698fc6383c73c6b103b67c3e9568f0 Mon Sep 17 00:00:00 2001
From: Alex Menkov
Date: Thu, 3 Dec 2020 21:31:33 +0000
Subject: [PATCH 056/504] 8256808: com/sun/jdi/CatchAllTest.java failed with
"NullPointerException: Cannot invoke "lib.jdb.Jdb.log(String)" because
"this.jdb" is null"
Reviewed-by: cjplummer, sspitsyn
---
test/jdk/com/sun/jdi/lib/jdb/Jdb.java | 4 ++--
test/jdk/com/sun/jdi/lib/jdb/JdbTest.java | 8 ++++----
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/test/jdk/com/sun/jdi/lib/jdb/Jdb.java b/test/jdk/com/sun/jdi/lib/jdb/Jdb.java
index 2d34afead92e1..878ec77eff9e5 100644
--- a/test/jdk/com/sun/jdi/lib/jdb/Jdb.java
+++ b/test/jdk/com/sun/jdi/lib/jdb/Jdb.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 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
@@ -260,7 +260,7 @@ public void quit() {
command(JdbCommand.quit());
}
- void log(String s) {
+ private void log(String s) {
System.out.println(s);
}
diff --git a/test/jdk/com/sun/jdi/lib/jdb/JdbTest.java b/test/jdk/com/sun/jdi/lib/jdb/JdbTest.java
index f286e126aed76..b9872b91895be 100644
--- a/test/jdk/com/sun/jdi/lib/jdb/JdbTest.java
+++ b/test/jdk/com/sun/jdi/lib/jdb/JdbTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 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
@@ -94,9 +94,9 @@ public void run() {
setup();
runCases();
} catch (Throwable e) {
- jdb.log("=======================================");
- jdb.log("Exception thrown during test execution: " + e.getMessage());
- jdb.log("=======================================");
+ System.out.println("=======================================");
+ System.out.println("Exception thrown during test execution: " + e.getMessage());
+ System.out.println("=======================================");
throw e;
} finally {
shutdown();
From 36209b70daf4df54435b6acd7092b77d2b5053df Mon Sep 17 00:00:00 2001
From: Erik Joelsson
Date: Thu, 3 Dec 2020 21:41:37 +0000
Subject: [PATCH 057/504] 8257547: Handle multiple prereqs on the same line in
deps files
Reviewed-by: ihse, tbell
---
make/common/NativeCompilation.gmk | 18 +++++++--
test/make/TestFixDepsFile.gmk | 66 +++++++++++++++++++++++++++++++
test/make/TestMake.gmk | 6 ++-
3 files changed, 85 insertions(+), 5 deletions(-)
create mode 100644 test/make/TestFixDepsFile.gmk
diff --git a/make/common/NativeCompilation.gmk b/make/common/NativeCompilation.gmk
index 0472ec3802115..6901d6d003f54 100644
--- a/make/common/NativeCompilation.gmk
+++ b/make/common/NativeCompilation.gmk
@@ -240,12 +240,22 @@ ifeq ($(ALLOW_ABSOLUTE_PATHS_IN_OUTPUT)-$(FILE_MACRO_CFLAGS), false-)
# When compiling with relative paths, the deps file may come out with relative
# paths, and that path may start with './'. First remove any leading ./, then
# add WORKSPACE_ROOT to any line not starting with /, while allowing for
- # leading spaces.
+ # leading spaces. There may also be multiple entries on the same line, so start
+ # with splitting such lines.
+ # Non GNU sed (BSD on macosx) cannot substitue in literal \n using regex.
+ # Instead use a bash escaped literal newline. To avoid having unmatched quotes
+ # ruin the ability for an editor to properly syntax highlight this file, define
+ # that newline sequence as a separate variable and add the closing quote behind
+ # a comment.
+ sed_newline := \'$$'\n''#'
define fix-deps-file
$(SED) \
- -e 's|^\([ ]*\)\./|\1|' \
- -e '/^[ ]*[^/ ]/s|^\([ ]*\)|\1$(WORKSPACE_ROOT)/|' \
- $1.tmp > $1
+ -e 's|\([^ ]\) \{1,\}\([^\\:]\)|\1 \\$(sed_newline) \2|g' \
+ $1.tmp \
+ | $(SED) \
+ -e 's|^\([ ]*\)\./|\1|' \
+ -e '/^[ ]*[^/ ]/s|^\([ ]*\)|\1$(WORKSPACE_ROOT)/|' \
+ > $1
endef
else
# By default the MakeCommandRelative macro does nothing.
diff --git a/test/make/TestFixDepsFile.gmk b/test/make/TestFixDepsFile.gmk
new file mode 100644
index 0000000000000..22308260d617c
--- /dev/null
+++ b/test/make/TestFixDepsFile.gmk
@@ -0,0 +1,66 @@
+#
+# Copyright (c) 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. 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.
+#
+
+default: all
+
+include $(SPEC)
+include MakeBase.gmk
+include UtilsForTests.gmk
+
+THIS_FILE := $(TOPDIR)/test/make/FixDepsFile.gmk
+DEPS := $(THIS_FILE) \
+ $(TOPDIR)/make/common/NativeCompilation.gmk \
+ #
+
+OUTPUT_DIR := $(TESTMAKE_OUTPUTDIR)/fix-deps-file
+$(call MakeDir, $(OUTPUT_DIR))
+
+################################################################################
+# The relevant case to test is when absolute paths aren't allowed.
+ALLOW_ABSOLUTE_PATHS_IN_OUTPUT := false
+FILE_MACRO_CFLAGS :=
+include NativeCompilation.gmk
+
+DEPS_FILE := $(OUTPUT_DIR)/deps.d
+
+test-fix-deps-file:
+ $(ECHO) "foo/bar1: \\" > $(DEPS_FILE).tmp
+ $(ECHO) "foo/baz1" >> $(DEPS_FILE).tmp
+ $(ECHO) "foo/bar : bar \\" >> $(DEPS_FILE).tmp
+ $(ECHO) " ./bar/baz /foo/baz" >> $(DEPS_FILE).tmp
+ $(call fix-deps-file, $(DEPS_FILE))
+ $(ECHO) "$(WORKSPACE_ROOT)/foo/bar1: \\" > $(DEPS_FILE).expected
+ $(ECHO) "$(WORKSPACE_ROOT)/foo/baz1" >> $(DEPS_FILE).expected
+ $(ECHO) "$(WORKSPACE_ROOT)/foo/bar : \\" >> $(DEPS_FILE).expected
+ $(ECHO) " $(WORKSPACE_ROOT)/bar \\" >> $(DEPS_FILE).expected
+ $(ECHO) " $(WORKSPACE_ROOT)/bar/baz \\" >> $(DEPS_FILE).expected
+ $(ECHO) " /foo/baz" >> $(DEPS_FILE).expected
+ $(DIFF) $(DEPS_FILE).expected $(DEPS_FILE)
+
+TEST_TARGETS := test-fix-deps-file
+
+################################################################################
+
+all: $(TEST_TARGETS)
diff --git a/test/make/TestMake.gmk b/test/make/TestMake.gmk
index 669fa6e30a802..de715933b3b83 100644
--- a/test/make/TestMake.gmk
+++ b/test/make/TestMake.gmk
@@ -36,6 +36,9 @@ java-compilation:
copy-files:
+$(MAKE) -f TestCopyFiles.gmk $(TEST_SUBTARGET)
+fix-deps-file:
+ +$(MAKE) -f TestFixDepsFile.gmk $(TEST_SUBTARGET)
+
idea:
+$(MAKE) -f TestIdea.gmk $(TEST_SUBTARGET)
@@ -46,7 +49,8 @@ configure:
$(BASH) $(TOPDIR)/test/make/autoconf/test-configure.sh \
"$(AUTOCONF)" "$(TOPDIR)" "$(TEST_SUPPORT_DIR)"
-TARGETS += make-base java-compilation copy-files idea compile-commands configure
+TARGETS += make-base java-compilation copy-files fix-deps-file idea \
+ compile-commands configure
all: $(TARGETS)
From f0b1194004a6e7ebcb918cf58bad16f68130ccf2 Mon Sep 17 00:00:00 2001
From: Mandy Chung
Date: Thu, 3 Dec 2020 22:14:52 +0000
Subject: [PATCH 058/504] 8235784:
java/lang/invoke/VarHandles/VarHandleTestByteArrayAsInt.java fails due to
timeout with fastdebug bits
Reviewed-by: bchristi, naoto
---
.../invoke/VarHandles/VarHandleTestByteArrayAsChar.java | 8 ++++----
.../invoke/VarHandles/VarHandleTestByteArrayAsDouble.java | 8 ++++----
.../invoke/VarHandles/VarHandleTestByteArrayAsFloat.java | 8 ++++----
.../invoke/VarHandles/VarHandleTestByteArrayAsInt.java | 8 ++++----
.../invoke/VarHandles/VarHandleTestByteArrayAsLong.java | 8 ++++----
.../invoke/VarHandles/VarHandleTestByteArrayAsShort.java | 8 ++++----
.../VarHandles/X-VarHandleTestByteArrayView.java.template | 8 ++++----
7 files changed, 28 insertions(+), 28 deletions(-)
diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsChar.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsChar.java
index d7439671fcbd4..1f5cf9c63240d 100644
--- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsChar.java
+++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsChar.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -24,9 +24,9 @@
/*
* @test
* @bug 8154556
- * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsChar
- * @run testng/othervm -Diters=20000 VarHandleTestByteArrayAsChar
- * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAsChar
+ * @run testng/othervm/timeout=360 -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsChar
+ * @run testng/othervm/timeout=360 -Diters=20000 VarHandleTestByteArrayAsChar
+ * @run testng/othervm/timeout=360 -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAsChar
*/
import org.testng.annotations.DataProvider;
diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsDouble.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsDouble.java
index 943b1b3a612df..02a8a8d44975d 100644
--- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsDouble.java
+++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsDouble.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -24,9 +24,9 @@
/*
* @test
* @bug 8154556
- * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsDouble
- * @run testng/othervm -Diters=20000 VarHandleTestByteArrayAsDouble
- * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAsDouble
+ * @run testng/othervm/timeout=360 -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsDouble
+ * @run testng/othervm/timeout=360 -Diters=20000 VarHandleTestByteArrayAsDouble
+ * @run testng/othervm/timeout=360 -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAsDouble
*/
import org.testng.annotations.DataProvider;
diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsFloat.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsFloat.java
index 4c1c9c9aa3672..2fa4806d84f10 100644
--- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsFloat.java
+++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsFloat.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -24,9 +24,9 @@
/*
* @test
* @bug 8154556
- * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsFloat
- * @run testng/othervm -Diters=20000 VarHandleTestByteArrayAsFloat
- * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAsFloat
+ * @run testng/othervm/timeout=360 -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsFloat
+ * @run testng/othervm/timeout=360 -Diters=20000 VarHandleTestByteArrayAsFloat
+ * @run testng/othervm/timeout=360 -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAsFloat
*/
import org.testng.annotations.DataProvider;
diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsInt.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsInt.java
index 145a5b8e2bdf0..6585849284e53 100644
--- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsInt.java
+++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsInt.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -24,9 +24,9 @@
/*
* @test
* @bug 8154556
- * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsInt
- * @run testng/othervm -Diters=20000 VarHandleTestByteArrayAsInt
- * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAsInt
+ * @run testng/othervm/timeout=360 -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsInt
+ * @run testng/othervm/timeout=360 -Diters=20000 VarHandleTestByteArrayAsInt
+ * @run testng/othervm/timeout=360 -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAsInt
*/
import org.testng.annotations.DataProvider;
diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsLong.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsLong.java
index 3192d5aff2979..be6b6af439c6c 100644
--- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsLong.java
+++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsLong.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -24,9 +24,9 @@
/*
* @test
* @bug 8154556
- * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsLong
- * @run testng/othervm -Diters=20000 VarHandleTestByteArrayAsLong
- * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAsLong
+ * @run testng/othervm/timeout=360 -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsLong
+ * @run testng/othervm/timeout=360 -Diters=20000 VarHandleTestByteArrayAsLong
+ * @run testng/othervm/timeout=360 -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAsLong
*/
import org.testng.annotations.DataProvider;
diff --git a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsShort.java b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsShort.java
index cca8699522955..3b20bf21f569b 100644
--- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsShort.java
+++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsShort.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -24,9 +24,9 @@
/*
* @test
* @bug 8154556
- * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsShort
- * @run testng/othervm -Diters=20000 VarHandleTestByteArrayAsShort
- * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAsShort
+ * @run testng/othervm/timeout=360 -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsShort
+ * @run testng/othervm/timeout=360 -Diters=20000 VarHandleTestByteArrayAsShort
+ * @run testng/othervm/timeout=360 -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAsShort
*/
import org.testng.annotations.DataProvider;
diff --git a/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestByteArrayView.java.template b/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestByteArrayView.java.template
index 9c7246f2184c2..918609070e96b 100644
--- a/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestByteArrayView.java.template
+++ b/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestByteArrayView.java.template
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -24,9 +24,9 @@
/*
* @test
* @bug 8154556
- * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAs$Type$
- * @run testng/othervm -Diters=20000 VarHandleTestByteArrayAs$Type$
- * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAs$Type$
+ * @run testng/othervm/timeout=360 -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAs$Type$
+ * @run testng/othervm/timeout=360 -Diters=20000 VarHandleTestByteArrayAs$Type$
+ * @run testng/othervm/timeout=360 -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAs$Type$
*/
import org.testng.annotations.DataProvider;
From 37c7835c78a467d79b46fbd02eb199df513545c4 Mon Sep 17 00:00:00 2001
From: Jie Fu
Date: Thu, 3 Dec 2020 23:09:07 +0000
Subject: [PATCH 059/504] 8257673: Build fails without shenandoahgc after
JDK-8257563
Reviewed-by: aph, shade
---
src/hotspot/share/jvmci/compilerRuntime.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/hotspot/share/jvmci/compilerRuntime.cpp b/src/hotspot/share/jvmci/compilerRuntime.cpp
index f0776dbcad424..4c5edb5c1b156 100644
--- a/src/hotspot/share/jvmci/compilerRuntime.cpp
+++ b/src/hotspot/share/jvmci/compilerRuntime.cpp
@@ -29,6 +29,7 @@
#include "interpreter/linkResolver.hpp"
#include "jvmci/compilerRuntime.hpp"
#include "oops/cpCache.inline.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/frame.inline.hpp"
From f83fd4acb4c04285d14eae6b8fee0de58bfcdd45 Mon Sep 17 00:00:00 2001
From: Andrey Turbanov
Date: Thu, 3 Dec 2020 23:11:55 +0000
Subject: [PATCH 060/504] 8257438: Avoid adding duplicate values into
extendedKeyCodesSet
Reviewed-by: serb
---
.../share/classes/sun/awt/ExtendedKeyCodes.java | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/src/java.desktop/share/classes/sun/awt/ExtendedKeyCodes.java b/src/java.desktop/share/classes/sun/awt/ExtendedKeyCodes.java
index c034dbebd44f2..69e670a601e14 100644
--- a/src/java.desktop/share/classes/sun/awt/ExtendedKeyCodes.java
+++ b/src/java.desktop/share/classes/sun/awt/ExtendedKeyCodes.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 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
@@ -44,7 +44,7 @@ public class ExtendedKeyCodes {
// known keyboard layout. For instance, sterling sign is on the primary layer
// of the Mac Italian layout.
private static final HashSet extendedKeyCodesSet =
- new HashSet(501, 1.0f);
+ new HashSet(496, 1.0f);
public static final int getExtendedKeyCodeForChar( int c ) {
int uc = Character.toUpperCase( c );
int lc = Character.toLowerCase( c );
@@ -394,7 +394,6 @@ public static final int getExtendedKeyCodeForChar( int c ) {
extendedKeyCodesSet.add(0x01000000+0x06AF);
extendedKeyCodesSet.add(0x01000000+0x06BE);
extendedKeyCodesSet.add(0x01000000+0x06CC);
- extendedKeyCodesSet.add(0x01000000+0x06CC);
extendedKeyCodesSet.add(0x01000000+0x06D2);
extendedKeyCodesSet.add(0x01000000+0x0493);
extendedKeyCodesSet.add(0x01000000+0x0497);
@@ -577,12 +576,8 @@ public static final int getExtendedKeyCodeForChar( int c ) {
extendedKeyCodesSet.add(0x01000000+0x0E59);
extendedKeyCodesSet.add(0x01000000+0x0587);
extendedKeyCodesSet.add(0x01000000+0x0589);
- extendedKeyCodesSet.add(0x01000000+0x0589);
- extendedKeyCodesSet.add(0x01000000+0x055D);
extendedKeyCodesSet.add(0x01000000+0x055D);
extendedKeyCodesSet.add(0x01000000+0x055B);
- extendedKeyCodesSet.add(0x01000000+0x055B);
- extendedKeyCodesSet.add(0x01000000+0x055E);
extendedKeyCodesSet.add(0x01000000+0x055E);
extendedKeyCodesSet.add(0x01000000+0x0561);
extendedKeyCodesSet.add(0x01000000+0x0562);
From 49f9e577156986825a1ab6c627573956ba712beb Mon Sep 17 00:00:00 2001
From: Valerie Peng
Date: Fri, 4 Dec 2020 03:52:04 +0000
Subject: [PATCH 061/504] 8257734: Extraneous output in HmacSHA3_512
constructor
Reviewed-by: ascarpino
---
.../share/classes/com/sun/crypto/provider/HmacCore.java | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/java.base/share/classes/com/sun/crypto/provider/HmacCore.java b/src/java.base/share/classes/com/sun/crypto/provider/HmacCore.java
index baa85ab20d7b4..fecc30a5a085d 100644
--- a/src/java.base/share/classes/com/sun/crypto/provider/HmacCore.java
+++ b/src/java.base/share/classes/com/sun/crypto/provider/HmacCore.java
@@ -334,7 +334,6 @@ public HmacSHA3_384() throws NoSuchAlgorithmException {
public static final class HmacSHA3_512 extends HmacCore {
public HmacSHA3_512() throws NoSuchAlgorithmException {
super("SHA3-512", 72);
- System.out.println(AlgorithmId.get("HmacSHA3-512"));
}
}
}
From d08c612b4059f0ffa0dc97b5df45a5d7e4b2de8a Mon Sep 17 00:00:00 2001
From: Andrey Turbanov
Date: Fri, 4 Dec 2020 06:32:14 +0000
Subject: [PATCH 062/504] 8257708: Remove redundant unmodifiableSet wrapper
from already immutable set returned by Collections.singleton
Reviewed-by: shade, sspitsyn
---
.../DefaultPlatformMBeanProvider.java | 32 +++++++------------
.../internal/PlatformMBeanProviderImpl.java | 8 ++---
2 files changed, 14 insertions(+), 26 deletions(-)
diff --git a/src/java.management/share/classes/java/lang/management/DefaultPlatformMBeanProvider.java b/src/java.management/share/classes/java/lang/management/DefaultPlatformMBeanProvider.java
index ba8661c5bcbaa..7e928227e57cb 100644
--- a/src/java.management/share/classes/java/lang/management/DefaultPlatformMBeanProvider.java
+++ b/src/java.management/share/classes/java/lang/management/DefaultPlatformMBeanProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -56,8 +56,7 @@ private List> init() {
*/
initMBeanList.add(new PlatformComponent() {
private final Set classLoadingInterfaceNames =
- Collections.unmodifiableSet(Collections.singleton(
- "java.lang.management.ClassLoadingMXBean"));
+ Collections.singleton("java.lang.management.ClassLoadingMXBean");
@Override
public Set> mbeanInterfaces() {
@@ -87,8 +86,7 @@ public Map nameToMBeanMap() {
*/
initMBeanList.add(new PlatformComponent() {
private final Set compilationMXBeanInterfaceNames
- = Collections.unmodifiableSet(Collections.singleton(
- "java.lang.management.CompilationMXBean"));
+ = Collections.singleton("java.lang.management.CompilationMXBean");
@Override
public Set> mbeanInterfaces() {
@@ -123,8 +121,7 @@ public Map nameToMBeanMap() {
*/
initMBeanList.add(new PlatformComponent() {
private final Set memoryMXBeanInterfaceNames
- = Collections.unmodifiableSet(Collections.singleton(
- "java.lang.management.MemoryMXBean"));
+ = Collections.singleton("java.lang.management.MemoryMXBean");
@Override
public Set> mbeanInterfaces() {
@@ -203,8 +200,7 @@ public Map nameToMBeanMap() {
*/
initMBeanList.add(new PlatformComponent() {
private final Set memoryManagerMXBeanInterfaceNames
- = Collections.unmodifiableSet(Collections.singleton(
- "java.lang.management.MemoryManagerMXBean"));
+ = Collections.singleton("java.lang.management.MemoryManagerMXBean");
@Override
public Set> mbeanInterfaces() {
@@ -252,8 +248,7 @@ private boolean isMemoryManager(MemoryManagerMXBean mbean) {
*/
initMBeanList.add(new PlatformComponent() {
private final Set memoryPoolMXBeanInterfaceNames
- = Collections.unmodifiableSet(Collections.singleton(
- "java.lang.management.MemoryPoolMXBean"));
+ = Collections.singleton("java.lang.management.MemoryPoolMXBean");
@Override
public Set> mbeanInterfaces() {
@@ -298,8 +293,7 @@ public Map nameToMBeanMap() {
*/
initMBeanList.add(new PlatformComponent() {
private final Set runtimeMXBeanInterfaceNames
- = Collections.unmodifiableSet(Collections.singleton(
- "java.lang.management.RuntimeMXBean"));
+ = Collections.singleton("java.lang.management.RuntimeMXBean");
@Override
public Set> mbeanInterfaces() {
@@ -329,8 +323,7 @@ public Map nameToMBeanMap() {
*/
initMBeanList.add(new PlatformComponent() {
private final Set threadMXBeanInterfaceNames
- = Collections.unmodifiableSet(Collections.singleton(
- "java.lang.management.ThreadMXBean"));
+ = Collections.singleton("java.lang.management.ThreadMXBean");
@Override
public Set> mbeanInterfaces() {
@@ -361,8 +354,7 @@ public Map nameToMBeanMap() {
*/
initMBeanList.add(new PlatformComponent() {
private final Set platformLoggingMXBeanInterfaceNames
- = Collections.unmodifiableSet(Collections.singleton(
- "java.lang.management.PlatformLoggingMXBean"));
+ = Collections.singleton("java.lang.management.PlatformLoggingMXBean");
@Override
public Set> mbeanInterfaces() {
@@ -393,8 +385,7 @@ public Map nameToMBeanMap() {
*/
initMBeanList.add(new PlatformComponent() {
private final Set bufferPoolMXBeanInterfaceNames
- = Collections.unmodifiableSet(Collections.singleton(
- "java.lang.management.BufferPoolMXBean"));
+ = Collections.singleton("java.lang.management.BufferPoolMXBean");
@Override
public Set> mbeanInterfaces() {
@@ -437,8 +428,7 @@ public Map nameToMBeanMap() {
*/
initMBeanList.add(new PlatformComponent() {
private final Set operatingSystemMXBeanInterfaceNames
- = Collections.unmodifiableSet(Collections.singleton(
- "java.lang.management.OperatingSystemMXBean"));
+ = Collections.singleton("java.lang.management.OperatingSystemMXBean");
@Override
public Set> mbeanInterfaces() {
diff --git a/src/jdk.management/share/classes/com/sun/management/internal/PlatformMBeanProviderImpl.java b/src/jdk.management/share/classes/com/sun/management/internal/PlatformMBeanProviderImpl.java
index 24fbbb54c9392..da1558f59a877 100644
--- a/src/jdk.management/share/classes/com/sun/management/internal/PlatformMBeanProviderImpl.java
+++ b/src/jdk.management/share/classes/com/sun/management/internal/PlatformMBeanProviderImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -204,8 +204,7 @@ public Map nameToMBeanMap()
*/
initMBeanList.add(new PlatformComponent() {
private final Set hotSpotDiagnosticMXBeanInterfaceNames =
- Collections.unmodifiableSet(Collections.singleton(
- "com.sun.management.HotSpotDiagnosticMXBean"));
+ Collections.singleton("com.sun.management.HotSpotDiagnosticMXBean");
@Override
public Set> mbeanInterfaces() {
@@ -237,8 +236,7 @@ public Map nameToMBeanMap()
if (diagMBean != null) {
initMBeanList.add(new PlatformComponent() {
final Set dynamicMBeanInterfaceNames
- = Collections.unmodifiableSet(Collections.singleton(
- "javax.management.DynamicMBean"));
+ = Collections.singleton("javax.management.DynamicMBean");
@Override
public Set mbeanInterfaceNames() {
From 4390f2c8c3e87312ab25bb829f180c5d4d898361 Mon Sep 17 00:00:00 2001
From: Vladimir Ivanov
Date: Fri, 4 Dec 2020 07:53:17 +0000
Subject: [PATCH 063/504] 8257630: C2: ReplacedNodes doesn't handle non-CFG
multi nodes
Reviewed-by: neliasso, kvn, thartmann
---
src/hotspot/share/opto/replacednodes.cpp | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/src/hotspot/share/opto/replacednodes.cpp b/src/hotspot/share/opto/replacednodes.cpp
index 68928fc16010b..0a89b06a7e7d0 100644
--- a/src/hotspot/share/opto/replacednodes.cpp
+++ b/src/hotspot/share/opto/replacednodes.cpp
@@ -120,7 +120,7 @@ static void enqueue_use(Node* n, Node* use, Unique_Node_List& work) {
}
}
-// Perfom node replacement following late inlining
+// Perform node replacement following late inlining.
void ReplacedNodes::apply(Compile* C, Node* ctl) {
// ctl is the control on exit of the method that was late inlined
if (is_empty()) {
@@ -144,20 +144,22 @@ void ReplacedNodes::apply(Compile* C, Node* ctl) {
work.clear();
enqueue_use(initial, use, work);
bool replace = true;
- // Check that this use is dominated by ctl. Go ahead with the
- // replacement if it is.
+ // Check that this use is dominated by ctl. Go ahead with the replacement if it is.
while (work.size() != 0 && replace) {
Node* n = work.pop();
if (use->outcnt() == 0) {
continue;
}
if (n->is_CFG() || (n->in(0) != NULL && !n->in(0)->is_top())) {
- int depth = 0;
- Node *m = n;
+ // Skip projections, since some of the multi nodes aren't CFG (e.g., LoadStore and SCMemProj).
+ if (n->is_Proj()) {
+ n = n->in(0);
+ }
if (!n->is_CFG()) {
n = n->in(0);
}
assert(n->is_CFG(), "should be CFG now");
+ int depth = 0;
while(n != ctl) {
n = IfNode::up_one_dom(n);
depth++;
From 6845fee9055727e13f00e4a71e30067702057d5d Mon Sep 17 00:00:00 2001
From: Vladimir Ivanov
Date: Fri, 4 Dec 2020 07:54:24 +0000
Subject: [PATCH 064/504] 8257625: C2: Harden input checks in vector intrinsics
Reviewed-by: thartmann
---
src/hotspot/share/opto/vectorIntrinsics.cpp | 198 +++++++++++++-------
src/hotspot/share/opto/vectornode.cpp | 153 ++++++---------
src/hotspot/share/opto/vectornode.hpp | 2 +
3 files changed, 185 insertions(+), 168 deletions(-)
diff --git a/src/hotspot/share/opto/vectorIntrinsics.cpp b/src/hotspot/share/opto/vectorIntrinsics.cpp
index 6f6932af0ec51..07036d2ca7b7e 100644
--- a/src/hotspot/share/opto/vectorIntrinsics.cpp
+++ b/src/hotspot/share/opto/vectorIntrinsics.cpp
@@ -197,12 +197,13 @@ static bool is_klass_initialized(const TypeInstPtr* vec_klass) {
// TernaryOperation defaultImpl) {
//
bool LibraryCallKit::inline_vector_nary_operation(int n) {
- const TypeInt* opr = gvn().type(argument(0))->is_int();
- const TypeInstPtr* vector_klass = gvn().type(argument(1))->is_instptr();
- const TypeInstPtr* elem_klass = gvn().type(argument(2))->is_instptr();
- const TypeInt* vlen = gvn().type(argument(3))->is_int();
+ const TypeInt* opr = gvn().type(argument(0))->isa_int();
+ const TypeInstPtr* vector_klass = gvn().type(argument(1))->isa_instptr();
+ const TypeInstPtr* elem_klass = gvn().type(argument(2))->isa_instptr();
+ const TypeInt* vlen = gvn().type(argument(3))->isa_int();
- if (!opr->is_con() || vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || !vlen->is_con()) {
+ if (opr == NULL || vector_klass == NULL || elem_klass == NULL || vlen == NULL ||
+ !opr->is_con() || vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || !vlen->is_con()) {
if (C->print_intrinsics()) {
tty->print_cr(" ** missing constant: opr=%s vclass=%s etype=%s vlen=%s",
NodeClassNames[argument(0)->Opcode()],
@@ -229,6 +230,12 @@ bool LibraryCallKit::inline_vector_nary_operation(int n) {
int num_elem = vlen->get_con();
int opc = VectorSupport::vop2ideal(opr->get_con(), elem_bt);
int sopc = VectorNode::opcode(opc, elem_bt);
+ if (sopc == 0) {
+ if (C->print_intrinsics()) {
+ tty->print_cr(" ** operation not supported: opc=%s bt=%s", NodeClassNames[opc], type2name(elem_bt));
+ }
+ return false; // operation not supported
+ }
ciKlass* vbox_klass = vector_klass->const_oop()->as_instance()->java_lang_Class_klass();
const TypeInstPtr* vbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass);
@@ -305,14 +312,18 @@ bool LibraryCallKit::inline_vector_nary_operation(int n) {
// Sh ShuffleIota(Class> E, Class> ShuffleClass, Vector.Species s, int length,
// int start, int step, int wrap, ShuffleIotaOperation defaultImpl)
bool LibraryCallKit::inline_vector_shuffle_iota() {
- const TypeInstPtr* shuffle_klass = gvn().type(argument(1))->is_instptr();
- const TypeInt* vlen = gvn().type(argument(3))->is_int();
- Node* start = argument(4);
- const TypeInt* start_val = gvn().type(start)->is_int();
- Node* step = argument(5);
- const TypeInt* step_val = gvn().type(step)->is_int();
- const TypeInt* wrap = gvn().type(argument(6))->is_int();
+ const TypeInstPtr* shuffle_klass = gvn().type(argument(1))->isa_instptr();
+ const TypeInt* vlen = gvn().type(argument(3))->isa_int();
+ const TypeInt* start_val = gvn().type(argument(4))->isa_int();
+ const TypeInt* step_val = gvn().type(argument(5))->isa_int();
+ const TypeInt* wrap = gvn().type(argument(6))->isa_int();
+
+ Node* start = argument(4);
+ Node* step = argument(5);
+ if (shuffle_klass == NULL || vlen == NULL || start_val == NULL || step_val == NULL || wrap == NULL) {
+ return false; // dead code
+ }
if (!vlen->is_con() || !is_power_of_2(vlen->get_con()) ||
shuffle_klass->const_oop() == NULL || !wrap->is_con()) {
return false; // not enough info for intrinsification
@@ -396,12 +407,15 @@ bool LibraryCallKit::inline_vector_shuffle_iota() {
// VM shuffleToVector(Class VecClass, Class>E , Class> ShuffleClass, Sh s, int length,
// ShuffleToVectorOperation defaultImpl)
bool LibraryCallKit::inline_vector_shuffle_to_vector() {
- const TypeInstPtr* vector_klass = gvn().type(argument(0))->is_instptr();
- const TypeInstPtr* elem_klass = gvn().type(argument(1))->is_instptr();
- const TypeInstPtr* shuffle_klass = gvn().type(argument(2))->is_instptr();
- Node* shuffle = argument(3);
- const TypeInt* vlen = gvn().type(argument(4))->is_int();
+ const TypeInstPtr* vector_klass = gvn().type(argument(0))->isa_instptr();
+ const TypeInstPtr* elem_klass = gvn().type(argument(1))->isa_instptr();
+ const TypeInstPtr* shuffle_klass = gvn().type(argument(2))->isa_instptr();
+ Node* shuffle = argument(3);
+ const TypeInt* vlen = gvn().type(argument(4))->isa_int();
+ if (vector_klass == NULL || elem_klass == NULL || shuffle_klass == NULL || shuffle->is_top() || vlen == NULL) {
+ return false; // dead code
+ }
if (!vlen->is_con() || vector_klass->const_oop() == NULL || shuffle_klass->const_oop() == NULL) {
return false; // not enough info for intrinsification
}
@@ -451,11 +465,12 @@ bool LibraryCallKit::inline_vector_shuffle_to_vector() {
// long bits,
// LongFunction defaultImpl)
bool LibraryCallKit::inline_vector_broadcast_coerced() {
- const TypeInstPtr* vector_klass = gvn().type(argument(0))->is_instptr();
- const TypeInstPtr* elem_klass = gvn().type(argument(1))->is_instptr();
- const TypeInt* vlen = gvn().type(argument(2))->is_int();
+ const TypeInstPtr* vector_klass = gvn().type(argument(0))->isa_instptr();
+ const TypeInstPtr* elem_klass = gvn().type(argument(1))->isa_instptr();
+ const TypeInt* vlen = gvn().type(argument(2))->isa_int();
- if (vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || !vlen->is_con()) {
+ if (vector_klass == NULL || elem_klass == NULL || vlen == NULL ||
+ vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || !vlen->is_con()) {
if (C->print_intrinsics()) {
tty->print_cr(" ** missing constant: vclass=%s etype=%s vlen=%s",
NodeClassNames[argument(0)->Opcode()],
@@ -546,11 +561,12 @@ bool LibraryCallKit::inline_vector_broadcast_coerced() {
// StoreVectorOperation defaultImpl) {
bool LibraryCallKit::inline_vector_mem_operation(bool is_store) {
- const TypeInstPtr* vector_klass = gvn().type(argument(0))->is_instptr();
- const TypeInstPtr* elem_klass = gvn().type(argument(1))->is_instptr();
- const TypeInt* vlen = gvn().type(argument(2))->is_int();
+ const TypeInstPtr* vector_klass = gvn().type(argument(0))->isa_instptr();
+ const TypeInstPtr* elem_klass = gvn().type(argument(1))->isa_instptr();
+ const TypeInt* vlen = gvn().type(argument(2))->isa_int();
- if (vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || !vlen->is_con()) {
+ if (vector_klass == NULL || elem_klass == NULL || vlen == NULL ||
+ vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || !vlen->is_con()) {
if (C->print_intrinsics()) {
tty->print_cr(" ** missing constant: vclass=%s etype=%s vlen=%s",
NodeClassNames[argument(0)->Opcode()],
@@ -708,12 +724,13 @@ bool LibraryCallKit::inline_vector_mem_operation(bool is_store) {
// StoreVectorOperationWithMap defaultImpl) {
//
bool LibraryCallKit::inline_vector_gather_scatter(bool is_scatter) {
- const TypeInstPtr* vector_klass = gvn().type(argument(0))->is_instptr();
- const TypeInstPtr* elem_klass = gvn().type(argument(1))->is_instptr();
- const TypeInt* vlen = gvn().type(argument(2))->is_int();
- const TypeInstPtr* vector_idx_klass = gvn().type(argument(3))->is_instptr();
+ const TypeInstPtr* vector_klass = gvn().type(argument(0))->isa_instptr();
+ const TypeInstPtr* elem_klass = gvn().type(argument(1))->isa_instptr();
+ const TypeInt* vlen = gvn().type(argument(2))->isa_int();
+ const TypeInstPtr* vector_idx_klass = gvn().type(argument(3))->isa_instptr();
- if (vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || vector_idx_klass->const_oop() == NULL || !vlen->is_con()) {
+ if (vector_klass == NULL || elem_klass == NULL || vector_idx_klass == NULL || vlen == NULL ||
+ vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || vector_idx_klass->const_oop() == NULL || !vlen->is_con()) {
if (C->print_intrinsics()) {
tty->print_cr(" ** missing constant: vclass=%s etype=%s vlen=%s viclass=%s",
NodeClassNames[argument(0)->Opcode()],
@@ -812,12 +829,13 @@ bool LibraryCallKit::inline_vector_gather_scatter(bool is_scatter) {
// Function defaultImpl)
bool LibraryCallKit::inline_vector_reduction() {
- const TypeInt* opr = gvn().type(argument(0))->is_int();
- const TypeInstPtr* vector_klass = gvn().type(argument(1))->is_instptr();
- const TypeInstPtr* elem_klass = gvn().type(argument(2))->is_instptr();
- const TypeInt* vlen = gvn().type(argument(3))->is_int();
+ const TypeInt* opr = gvn().type(argument(0))->isa_int();
+ const TypeInstPtr* vector_klass = gvn().type(argument(1))->isa_instptr();
+ const TypeInstPtr* elem_klass = gvn().type(argument(2))->isa_instptr();
+ const TypeInt* vlen = gvn().type(argument(3))->isa_int();
- if (!opr->is_con() || vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || !vlen->is_con()) {
+ if (opr == NULL || vector_klass == NULL || elem_klass == NULL || vlen == NULL ||
+ !opr->is_con() || vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || !vlen->is_con()) {
if (C->print_intrinsics()) {
tty->print_cr(" ** missing constant: opr=%s vclass=%s etype=%s vlen=%s",
NodeClassNames[argument(0)->Opcode()],
@@ -899,12 +917,13 @@ bool LibraryCallKit::inline_vector_reduction() {
// BiFunction defaultImpl) {
//
bool LibraryCallKit::inline_vector_test() {
- const TypeInt* cond = gvn().type(argument(0))->is_int();
- const TypeInstPtr* vector_klass = gvn().type(argument(1))->is_instptr();
- const TypeInstPtr* elem_klass = gvn().type(argument(2))->is_instptr();
- const TypeInt* vlen = gvn().type(argument(3))->is_int();
+ const TypeInt* cond = gvn().type(argument(0))->isa_int();
+ const TypeInstPtr* vector_klass = gvn().type(argument(1))->isa_instptr();
+ const TypeInstPtr* elem_klass = gvn().type(argument(2))->isa_instptr();
+ const TypeInt* vlen = gvn().type(argument(3))->isa_int();
- if (!cond->is_con() || vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || !vlen->is_con()) {
+ if (cond == NULL || vector_klass == NULL || elem_klass == NULL || vlen == NULL ||
+ !cond->is_con() || vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || !vlen->is_con()) {
if (C->print_intrinsics()) {
tty->print_cr(" ** missing constant: cond=%s vclass=%s etype=%s vlen=%s",
NodeClassNames[argument(0)->Opcode()],
@@ -962,11 +981,14 @@ bool LibraryCallKit::inline_vector_test() {
// VectorBlendOp defaultImpl) { ...
//
bool LibraryCallKit::inline_vector_blend() {
- const TypeInstPtr* vector_klass = gvn().type(argument(0))->is_instptr();
- const TypeInstPtr* mask_klass = gvn().type(argument(1))->is_instptr();
- const TypeInstPtr* elem_klass = gvn().type(argument(2))->is_instptr();
- const TypeInt* vlen = gvn().type(argument(3))->is_int();
+ const TypeInstPtr* vector_klass = gvn().type(argument(0))->isa_instptr();
+ const TypeInstPtr* mask_klass = gvn().type(argument(1))->isa_instptr();
+ const TypeInstPtr* elem_klass = gvn().type(argument(2))->isa_instptr();
+ const TypeInt* vlen = gvn().type(argument(3))->isa_int();
+ if (mask_klass == NULL || vector_klass == NULL || elem_klass == NULL || vlen == NULL) {
+ return false; // dead code
+ }
if (mask_klass->const_oop() == NULL || vector_klass->const_oop() == NULL ||
elem_klass->const_oop() == NULL || !vlen->is_con()) {
if (C->print_intrinsics()) {
@@ -1032,12 +1054,15 @@ bool LibraryCallKit::inline_vector_blend() {
// VectorCompareOp defaultImpl) { ...
//
bool LibraryCallKit::inline_vector_compare() {
- const TypeInt* cond = gvn().type(argument(0))->is_int();
- const TypeInstPtr* vector_klass = gvn().type(argument(1))->is_instptr();
- const TypeInstPtr* mask_klass = gvn().type(argument(2))->is_instptr();
- const TypeInstPtr* elem_klass = gvn().type(argument(3))->is_instptr();
- const TypeInt* vlen = gvn().type(argument(4))->is_int();
+ const TypeInt* cond = gvn().type(argument(0))->isa_int();
+ const TypeInstPtr* vector_klass = gvn().type(argument(1))->isa_instptr();
+ const TypeInstPtr* mask_klass = gvn().type(argument(2))->isa_instptr();
+ const TypeInstPtr* elem_klass = gvn().type(argument(3))->isa_instptr();
+ const TypeInt* vlen = gvn().type(argument(4))->isa_int();
+ if (cond == NULL || vector_klass == NULL || mask_klass == NULL || elem_klass == NULL || vlen == NULL) {
+ return false; // dead code
+ }
if (!cond->is_con() || vector_klass->const_oop() == NULL || mask_klass->const_oop() == NULL ||
elem_klass->const_oop() == NULL || !vlen->is_con()) {
if (C->print_intrinsics()) {
@@ -1107,11 +1132,14 @@ bool LibraryCallKit::inline_vector_compare() {
// VectorSwizzleOp defaultImpl) { ...
bool LibraryCallKit::inline_vector_rearrange() {
- const TypeInstPtr* vector_klass = gvn().type(argument(0))->is_instptr();
- const TypeInstPtr* shuffle_klass = gvn().type(argument(1))->is_instptr();
- const TypeInstPtr* elem_klass = gvn().type(argument(2))->is_instptr();
- const TypeInt* vlen = gvn().type(argument(3))->is_int();
+ const TypeInstPtr* vector_klass = gvn().type(argument(0))->isa_instptr();
+ const TypeInstPtr* shuffle_klass = gvn().type(argument(1))->isa_instptr();
+ const TypeInstPtr* elem_klass = gvn().type(argument(2))->isa_instptr();
+ const TypeInt* vlen = gvn().type(argument(3))->isa_int();
+ if (vector_klass == NULL || shuffle_klass == NULL || elem_klass == NULL || vlen == NULL) {
+ return false; // dead code
+ }
if (shuffle_klass->const_oop() == NULL || vector_klass->const_oop() == NULL ||
elem_klass->const_oop() == NULL || !vlen->is_con()) {
if (C->print_intrinsics()) {
@@ -1182,11 +1210,14 @@ bool LibraryCallKit::inline_vector_rearrange() {
// VectorBroadcastIntOp defaultImpl) {
//
bool LibraryCallKit::inline_vector_broadcast_int() {
- const TypeInt* opr = gvn().type(argument(0))->is_int();
- const TypeInstPtr* vector_klass = gvn().type(argument(1))->is_instptr();
- const TypeInstPtr* elem_klass = gvn().type(argument(2))->is_instptr();
- const TypeInt* vlen = gvn().type(argument(3))->is_int();
+ const TypeInt* opr = gvn().type(argument(0))->isa_int();
+ const TypeInstPtr* vector_klass = gvn().type(argument(1))->isa_instptr();
+ const TypeInstPtr* elem_klass = gvn().type(argument(2))->isa_instptr();
+ const TypeInt* vlen = gvn().type(argument(3))->isa_int();
+ if (opr == NULL || vector_klass == NULL || elem_klass == NULL || vlen == NULL) {
+ return false; // dead code
+ }
if (!opr->is_con() || vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || !vlen->is_con()) {
if (C->print_intrinsics()) {
tty->print_cr(" ** missing constant: opr=%s vclass=%s etype=%s vlen=%s",
@@ -1213,7 +1244,19 @@ bool LibraryCallKit::inline_vector_broadcast_int() {
BasicType elem_bt = elem_type->basic_type();
int num_elem = vlen->get_con();
int opc = VectorSupport::vop2ideal(opr->get_con(), elem_bt);
+ if (opc == 0 || !VectorNode::is_shift_opcode(opc)) {
+ if (C->print_intrinsics()) {
+ tty->print_cr(" ** operation not supported: op=%d bt=%s", opr->get_con(), type2name(elem_bt));
+ }
+ return false; // operation not supported
+ }
int sopc = VectorNode::opcode(opc, elem_bt);
+ if (sopc == 0) {
+ if (C->print_intrinsics()) {
+ tty->print_cr(" ** operation not supported: opc=%s bt=%s", NodeClassNames[opc], type2name(elem_bt));
+ }
+ return false; // operation not supported
+ }
ciKlass* vbox_klass = vector_klass->const_oop()->as_instance()->java_lang_Class_klass();
const TypeInstPtr* vbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass);
@@ -1247,16 +1290,21 @@ bool LibraryCallKit::inline_vector_broadcast_int() {
// VectorConvertOp defaultImpl) {
//
bool LibraryCallKit::inline_vector_convert() {
- const TypeInt* opr = gvn().type(argument(0))->is_int();
+ const TypeInt* opr = gvn().type(argument(0))->isa_int();
- const TypeInstPtr* vector_klass_from = gvn().type(argument(1))->is_instptr();
- const TypeInstPtr* elem_klass_from = gvn().type(argument(2))->is_instptr();
- const TypeInt* vlen_from = gvn().type(argument(3))->is_int();
+ const TypeInstPtr* vector_klass_from = gvn().type(argument(1))->isa_instptr();
+ const TypeInstPtr* elem_klass_from = gvn().type(argument(2))->isa_instptr();
+ const TypeInt* vlen_from = gvn().type(argument(3))->isa_int();
- const TypeInstPtr* vector_klass_to = gvn().type(argument(4))->is_instptr();
- const TypeInstPtr* elem_klass_to = gvn().type(argument(5))->is_instptr();
- const TypeInt* vlen_to = gvn().type(argument(6))->is_int();
+ const TypeInstPtr* vector_klass_to = gvn().type(argument(4))->isa_instptr();
+ const TypeInstPtr* elem_klass_to = gvn().type(argument(5))->isa_instptr();
+ const TypeInt* vlen_to = gvn().type(argument(6))->isa_int();
+ if (opr == NULL ||
+ vector_klass_from == NULL || elem_klass_from == NULL || vlen_from == NULL ||
+ vector_klass_to == NULL || elem_klass_to == NULL || vlen_to == NULL) {
+ return false; // dead code
+ }
if (!opr->is_con() ||
vector_klass_from->const_oop() == NULL || elem_klass_from->const_oop() == NULL || !vlen_from->is_con() ||
vector_klass_to->const_oop() == NULL || elem_klass_to->const_oop() == NULL || !vlen_to->is_con()) {
@@ -1431,11 +1479,14 @@ bool LibraryCallKit::inline_vector_convert() {
// VecInsertOp defaultImpl) {
//
bool LibraryCallKit::inline_vector_insert() {
- const TypeInstPtr* vector_klass = gvn().type(argument(0))->is_instptr();
- const TypeInstPtr* elem_klass = gvn().type(argument(1))->is_instptr();
- const TypeInt* vlen = gvn().type(argument(2))->is_int();
- const TypeInt* idx = gvn().type(argument(4))->is_int();
+ const TypeInstPtr* vector_klass = gvn().type(argument(0))->isa_instptr();
+ const TypeInstPtr* elem_klass = gvn().type(argument(1))->isa_instptr();
+ const TypeInt* vlen = gvn().type(argument(2))->isa_int();
+ const TypeInt* idx = gvn().type(argument(4))->isa_int();
+ if (vector_klass == NULL || elem_klass == NULL || vlen == NULL || idx == NULL) {
+ return false; // dead code
+ }
if (vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || !vlen->is_con() || !idx->is_con()) {
if (C->print_intrinsics()) {
tty->print_cr(" ** missing constant: vclass=%s etype=%s vlen=%s idx=%s",
@@ -1521,11 +1572,14 @@ bool LibraryCallKit::inline_vector_insert() {
// VecExtractOp defaultImpl) {
//
bool LibraryCallKit::inline_vector_extract() {
- const TypeInstPtr* vector_klass = gvn().type(argument(0))->is_instptr();
- const TypeInstPtr* elem_klass = gvn().type(argument(1))->is_instptr();
- const TypeInt* vlen = gvn().type(argument(2))->is_int();
- const TypeInt* idx = gvn().type(argument(4))->is_int();
+ const TypeInstPtr* vector_klass = gvn().type(argument(0))->isa_instptr();
+ const TypeInstPtr* elem_klass = gvn().type(argument(1))->isa_instptr();
+ const TypeInt* vlen = gvn().type(argument(2))->isa_int();
+ const TypeInt* idx = gvn().type(argument(4))->isa_int();
+ if (vector_klass == NULL || elem_klass == NULL || vlen == NULL || idx == NULL) {
+ return false; // dead code
+ }
if (vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || !vlen->is_con() || !idx->is_con()) {
if (C->print_intrinsics()) {
tty->print_cr(" ** missing constant: vclass=%s etype=%s vlen=%s idx=%s",
diff --git a/src/hotspot/share/opto/vectornode.cpp b/src/hotspot/share/opto/vectornode.cpp
index 872701105dd5f..42f7a8b929051 100644
--- a/src/hotspot/share/opto/vectornode.cpp
+++ b/src/hotspot/share/opto/vectornode.cpp
@@ -43,17 +43,12 @@ int VectorNode::opcode(int sopc, BasicType bt) {
case T_CHAR:
case T_SHORT: return Op_AddVS;
case T_INT: return Op_AddVI;
- default: ShouldNotReachHere(); return 0;
+ default: return 0;
}
- case Op_AddL:
- assert(bt == T_LONG, "must be");
- return Op_AddVL;
- case Op_AddF:
- assert(bt == T_FLOAT, "must be");
- return Op_AddVF;
- case Op_AddD:
- assert(bt == T_DOUBLE, "must be");
- return Op_AddVD;
+ case Op_AddL: return (bt == T_LONG ? Op_AddVL : 0);
+ case Op_AddF: return (bt == T_FLOAT ? Op_AddVF : 0);
+ case Op_AddD: return (bt == T_DOUBLE ? Op_AddVD : 0);
+
case Op_SubI:
switch (bt) {
case T_BOOLEAN:
@@ -61,17 +56,12 @@ int VectorNode::opcode(int sopc, BasicType bt) {
case T_CHAR:
case T_SHORT: return Op_SubVS;
case T_INT: return Op_SubVI;
- default: ShouldNotReachHere(); return 0;
+ default: return 0;
}
- case Op_SubL:
- assert(bt == T_LONG, "must be");
- return Op_SubVL;
- case Op_SubF:
- assert(bt == T_FLOAT, "must be");
- return Op_SubVF;
- case Op_SubD:
- assert(bt == T_DOUBLE, "must be");
- return Op_SubVD;
+ case Op_SubL: return (bt == T_LONG ? Op_SubVL : 0);
+ case Op_SubF: return (bt == T_FLOAT ? Op_SubVF : 0);
+ case Op_SubD: return (bt == T_DOUBLE ? Op_SubVD : 0);
+
case Op_MulI:
switch (bt) {
case T_BOOLEAN:return 0;
@@ -79,35 +69,25 @@ int VectorNode::opcode(int sopc, BasicType bt) {
case T_CHAR:
case T_SHORT: return Op_MulVS;
case T_INT: return Op_MulVI;
- default: ShouldNotReachHere(); return 0;
+ default: return 0;
}
- case Op_MulL:
- assert(bt == T_LONG, "must be");
- return Op_MulVL;
+ case Op_MulL: return (bt == T_LONG ? Op_MulVL : 0);
case Op_MulF:
- assert(bt == T_FLOAT, "must be");
- return Op_MulVF;
+ return (bt == T_FLOAT ? Op_MulVF : 0);
case Op_MulD:
- assert(bt == T_DOUBLE, "must be");
- return Op_MulVD;
+ return (bt == T_DOUBLE ? Op_MulVD : 0);
case Op_FmaD:
- assert(bt == T_DOUBLE, "must be");
- return Op_FmaVD;
+ return (bt == T_DOUBLE ? Op_FmaVD : 0);
case Op_FmaF:
- assert(bt == T_FLOAT, "must be");
- return Op_FmaVF;
+ return (bt == T_FLOAT ? Op_FmaVF : 0);
case Op_CMoveF:
- assert(bt == T_FLOAT, "must be");
- return Op_CMoveVF;
+ return (bt == T_FLOAT ? Op_CMoveVF : 0);
case Op_CMoveD:
- assert(bt == T_DOUBLE, "must be");
- return Op_CMoveVD;
+ return (bt == T_DOUBLE ? Op_CMoveVD : 0);
case Op_DivF:
- assert(bt == T_FLOAT, "must be");
- return Op_DivVF;
+ return (bt == T_FLOAT ? Op_DivVF : 0);
case Op_DivD:
- assert(bt == T_DOUBLE, "must be");
- return Op_DivVD;
+ return (bt == T_DOUBLE ? Op_DivVD : 0);
case Op_AbsI:
switch (bt) {
case T_BOOLEAN:
@@ -115,11 +95,10 @@ int VectorNode::opcode(int sopc, BasicType bt) {
case T_BYTE: return Op_AbsVB;
case T_SHORT: return Op_AbsVS;
case T_INT: return Op_AbsVI;
- default: ShouldNotReachHere(); return 0;
+ default: return 0;
}
case Op_AbsL:
- assert(bt == T_LONG, "must be");
- return Op_AbsVL;
+ return (bt == T_LONG ? Op_AbsVL : 0);
case Op_MinI:
switch (bt) {
case T_BOOLEAN:
@@ -127,17 +106,14 @@ int VectorNode::opcode(int sopc, BasicType bt) {
case T_BYTE:
case T_SHORT:
case T_INT: return Op_MinV;
- default: ShouldNotReachHere(); return 0;
+ default: return 0;
}
case Op_MinL:
- assert(bt == T_LONG, "must be");
- return Op_MinV;
+ return (bt == T_LONG ? Op_MinV : 0);
case Op_MinF:
- assert(bt == T_FLOAT, "must be");
- return Op_MinV;
+ return (bt == T_FLOAT ? Op_MinV : 0);
case Op_MinD:
- assert(bt == T_DOUBLE, "must be");
- return Op_MinV;
+ return (bt == T_DOUBLE ? Op_MinV : 0);
case Op_MaxI:
switch (bt) {
case T_BOOLEAN:
@@ -145,54 +121,38 @@ int VectorNode::opcode(int sopc, BasicType bt) {
case T_BYTE:
case T_SHORT:
case T_INT: return Op_MaxV;
- default: ShouldNotReachHere(); return 0;
+ default: return 0;
}
case Op_MaxL:
- assert(bt == T_LONG, "must be");
- return Op_MaxV;
+ return (bt == T_LONG ? Op_MaxV : 0);
case Op_MaxF:
- assert(bt == T_FLOAT, "must be");
- return Op_MaxV;
+ return (bt == T_FLOAT ? Op_MaxV : 0);
case Op_MaxD:
- assert(bt == T_DOUBLE, "must be");
- return Op_MaxV;
+ return (bt == T_DOUBLE ? Op_MaxV : 0);
case Op_AbsF:
- assert(bt == T_FLOAT, "must be");
- return Op_AbsVF;
+ return (bt == T_FLOAT ? Op_AbsVF : 0);
case Op_AbsD:
- assert(bt == T_DOUBLE, "must be");
- return Op_AbsVD;
+ return (bt == T_DOUBLE ? Op_AbsVD : 0);
case Op_NegI:
- assert(bt == T_INT, "must be");
- return Op_NegVI;
+ return (bt == T_INT ? Op_NegVI : 0);
case Op_NegF:
- assert(bt == T_FLOAT, "must be");
- return Op_NegVF;
+ return (bt == T_FLOAT ? Op_NegVF : 0);
case Op_NegD:
- assert(bt == T_DOUBLE, "must be");
- return Op_NegVD;
+ return (bt == T_DOUBLE ? Op_NegVD : 0);
case Op_RoundDoubleMode:
- assert(bt == T_DOUBLE, "must be");
- return Op_RoundDoubleModeV;
+ return (bt == T_DOUBLE ? Op_RoundDoubleModeV : 0);
case Op_RotateLeft:
- assert(bt == T_LONG || bt == T_INT, "must be");
- return Op_RotateLeftV;
+ return (bt == T_LONG || bt == T_INT ? Op_RotateLeftV : 0);
case Op_RotateRight:
- assert(bt == T_LONG || bt == T_INT, "must be");
- return Op_RotateRightV;
+ return (bt == T_LONG || bt == T_INT ? Op_RotateRightV : 0);
case Op_SqrtF:
- assert(bt == T_FLOAT, "must be");
- return Op_SqrtVF;
+ return (bt == T_FLOAT ? Op_SqrtVF : 0);
case Op_SqrtD:
- assert(bt == T_DOUBLE, "must be");
- return Op_SqrtVD;
+ return (bt == T_DOUBLE ? Op_SqrtVD : 0);
case Op_PopCountI:
- if (bt == T_INT) {
- return Op_PopCountVI;
- }
// Unimplemented for subword types since bit count changes
// depending on size of lane (and sign bit).
- return 0;
+ return (bt == T_INT ? Op_PopCountVI : 0);
case Op_LShiftI:
switch (bt) {
case T_BOOLEAN:
@@ -200,11 +160,10 @@ int VectorNode::opcode(int sopc, BasicType bt) {
case T_CHAR:
case T_SHORT: return Op_LShiftVS;
case T_INT: return Op_LShiftVI;
- default: ShouldNotReachHere(); return 0;
+ default: return 0;
}
case Op_LShiftL:
- assert(bt == T_LONG, "must be");
- return Op_LShiftVL;
+ return (bt == T_LONG ? Op_LShiftVL : 0);
case Op_RShiftI:
switch (bt) {
case T_BOOLEAN:return Op_URShiftVB; // boolean is unsigned value
@@ -212,17 +171,14 @@ int VectorNode::opcode(int sopc, BasicType bt) {
case T_BYTE: return Op_RShiftVB;
case T_SHORT: return Op_RShiftVS;
case T_INT: return Op_RShiftVI;
- default: ShouldNotReachHere(); return 0;
+ default: return 0;
}
case Op_RShiftL:
- assert(bt == T_LONG, "must be");
- return Op_RShiftVL;
+ return (bt == T_LONG ? Op_RShiftVL : 0);
case Op_URShiftB:
- assert(bt == T_BYTE, "must be");
- return Op_URShiftVB;
+ return (bt == T_BYTE ? Op_URShiftVB : 0);
case Op_URShiftS:
- assert(bt == T_SHORT, "must be");
- return Op_URShiftVS;
+ return (bt == T_SHORT ? Op_URShiftVS : 0);
case Op_URShiftI:
switch (bt) {
case T_BOOLEAN:return Op_URShiftVB;
@@ -234,11 +190,10 @@ int VectorNode::opcode(int sopc, BasicType bt) {
// a short value into int value with sign
// extension before a shift.
case T_INT: return Op_URShiftVI;
- default: ShouldNotReachHere(); return 0;
+ default: return 0;
}
case Op_URShiftL:
- assert(bt == T_LONG, "must be");
- return Op_URShiftVL;
+ return (bt == T_LONG ? Op_URShiftVL : 0);
case Op_AndI:
case Op_AndL:
return Op_AndV;
@@ -372,12 +327,14 @@ bool VectorNode::is_vector_rotate_supported(int vopc, uint vlen, BasicType bt) {
}
}
-bool VectorNode::is_shift(Node* n) {
- switch (n->Opcode()) {
+bool VectorNode::is_shift_opcode(int opc) {
+ switch (opc) {
case Op_LShiftI:
case Op_LShiftL:
case Op_RShiftI:
case Op_RShiftL:
+ case Op_URShiftB:
+ case Op_URShiftS:
case Op_URShiftI:
case Op_URShiftL:
return true;
@@ -386,6 +343,10 @@ bool VectorNode::is_shift(Node* n) {
}
}
+bool VectorNode::is_shift(Node* n) {
+ return is_shift_opcode(n->Opcode());
+}
+
bool VectorNode::is_vshift_cnt(Node* n) {
switch (n->Opcode()) {
case Op_LShiftCntV:
diff --git a/src/hotspot/share/opto/vectornode.hpp b/src/hotspot/share/opto/vectornode.hpp
index d4b2fc83079d2..3203598ce863e 100644
--- a/src/hotspot/share/opto/vectornode.hpp
+++ b/src/hotspot/share/opto/vectornode.hpp
@@ -75,6 +75,8 @@ class VectorNode : public TypeNode {
static VectorNode* make(int opc, Node* n1, Node* n2, Node* n3, uint vlen, BasicType bt);
static VectorNode* make(int vopc, Node* n1, Node* n2, Node* n3, const TypeVect* vt);
+ static bool is_shift_opcode(int opc);
+
static int opcode(int opc, BasicType bt);
static int replicate_opcode(BasicType bt);
static bool implemented(int opc, uint vlen, BasicType bt);
From 417e7e631740761a380df78894eee48f350c8af8 Mon Sep 17 00:00:00 2001
From: Vladimir Ivanov
Date: Fri, 4 Dec 2020 07:55:04 +0000
Subject: [PATCH 065/504] 8257632: C2: Late inlining attempt on a call with a
dead memory crashes
Reviewed-by: neliasso, kvn, thartmann
---
src/hotspot/share/opto/callGenerator.cpp | 6 ++++++
src/hotspot/share/opto/graphKit.cpp | 1 +
2 files changed, 7 insertions(+)
diff --git a/src/hotspot/share/opto/callGenerator.cpp b/src/hotspot/share/opto/callGenerator.cpp
index 02fc4253f5257..f6a2ae3c73ceb 100644
--- a/src/hotspot/share/opto/callGenerator.cpp
+++ b/src/hotspot/share/opto/callGenerator.cpp
@@ -363,6 +363,12 @@ void LateInlineCallGenerator::do_late_inline() {
assert(Compile::current()->inlining_incrementally(), "shouldn't happen during parsing");
return;
}
+ if (call->in(TypeFunc::Memory)->is_MergeMem()) {
+ MergeMemNode* merge_mem = call->in(TypeFunc::Memory)->as_MergeMem();
+ if (merge_mem->base_memory() == merge_mem->empty_memory()) {
+ return; // dead path
+ }
+ }
// check for unreachable loop
CallProjections callprojs;
diff --git a/src/hotspot/share/opto/graphKit.cpp b/src/hotspot/share/opto/graphKit.cpp
index dc5c19fa6b3dd..14c3807d2e219 100644
--- a/src/hotspot/share/opto/graphKit.cpp
+++ b/src/hotspot/share/opto/graphKit.cpp
@@ -1460,6 +1460,7 @@ void GraphKit::replace_in_map(Node* old, Node* neww) {
Node* GraphKit::memory(uint alias_idx) {
MergeMemNode* mem = merged_memory();
Node* p = mem->memory_at(alias_idx);
+ assert(p != mem->empty_memory(), "empty");
_gvn.set_type(p, Type::MEMORY); // must be mapped
return p;
}
From f33808ffc92fc4af376cd4bf56577627113fd221 Mon Sep 17 00:00:00 2001
From: Vladimir Ivanov
Date: Fri, 4 Dec 2020 07:55:40 +0000
Subject: [PATCH 066/504] 8257631: C2: Assertion failure in
ArrayCopyNode::get_count() during late inlining
Reviewed-by: neliasso, kvn, thartmann
---
src/hotspot/share/opto/arraycopynode.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/hotspot/share/opto/arraycopynode.cpp b/src/hotspot/share/opto/arraycopynode.cpp
index 5fc4759497ecf..4fc21c9ac1f0d 100644
--- a/src/hotspot/share/opto/arraycopynode.cpp
+++ b/src/hotspot/share/opto/arraycopynode.cpp
@@ -136,8 +136,8 @@ int ArrayCopyNode::get_count(PhaseGVN *phase) const {
// length input to ArrayCopyNode is constant, length of input
// array must be too.
- assert((get_length_if_constant(phase) == -1) == !ary_src->size()->is_con() ||
- phase->is_IterGVN() || StressReflectiveCode, "inconsistent");
+ assert((get_length_if_constant(phase) == -1) != ary_src->size()->is_con() ||
+ phase->is_IterGVN() || phase->C->inlining_incrementally() || StressReflectiveCode, "inconsistent");
if (ary_src->size()->is_con()) {
return ary_src->size()->get_con();
From 4a855149636bcfd2aa68dc8bba19fc10b549c36e Mon Sep 17 00:00:00 2001
From: Christian Hagedorn
Date: Fri, 4 Dec 2020 08:10:31 +0000
Subject: [PATCH 067/504] 8257182: JCK test failures in integer / long rotation
tests
Reviewed-by: mdoerr, vlivanov, thartmann, kvn
---
src/hotspot/share/opto/mulnode.cpp | 20 +++--
.../c2/TestRotateNegativeEvenValues.java | 82 +++++++++++++++++++
2 files changed, 94 insertions(+), 8 deletions(-)
create mode 100644 test/hotspot/jtreg/compiler/c2/TestRotateNegativeEvenValues.java
diff --git a/src/hotspot/share/opto/mulnode.cpp b/src/hotspot/share/opto/mulnode.cpp
index 3bdfd45bb0d41..734cd2f131932 100644
--- a/src/hotspot/share/opto/mulnode.cpp
+++ b/src/hotspot/share/opto/mulnode.cpp
@@ -1506,8 +1506,9 @@ const Type* RotateLeftNode::Value(PhaseGVN* phase) const {
return r1;
}
if (r1->is_con() && r2->is_con()) {
- int shift = r2->get_con() & (BitsPerJavaInteger - 1); // semantics of Java shifts
- return TypeInt::make((r1->get_con() << shift) | (r1->get_con() >> (32 - shift)));
+ juint r1_con = (juint)r1->get_con();
+ juint shift = (juint)(r2->get_con()) & (juint)(BitsPerJavaInteger - 1); // semantics of Java shifts
+ return TypeInt::make((r1_con << shift) | (r1_con >> (32 - shift)));
}
return TypeInt::INT;
} else {
@@ -1524,8 +1525,9 @@ const Type* RotateLeftNode::Value(PhaseGVN* phase) const {
return r1;
}
if (r1->is_con() && r2->is_con()) {
- int shift = r2->get_con() & (BitsPerJavaLong - 1); // semantics of Java shifts
- return TypeLong::make((r1->get_con() << shift) | (r1->get_con() >> (64 - shift)));
+ julong r1_con = (julong)r1->get_con();
+ julong shift = (julong)(r2->get_con()) & (julong)(BitsPerJavaLong - 1); // semantics of Java shifts
+ return TypeLong::make((r1_con << shift) | (r1_con >> (64 - shift)));
}
return TypeLong::LONG;
}
@@ -1583,8 +1585,9 @@ const Type* RotateRightNode::Value(PhaseGVN* phase) const {
return r1;
}
if (r1->is_con() && r2->is_con()) {
- int shift = r2->get_con() & (BitsPerJavaInteger - 1); // semantics of Java shifts
- return TypeInt::make((r1->get_con() >> shift) | (r1->get_con() << (32 - shift)));
+ juint r1_con = (juint)r1->get_con();
+ juint shift = (juint)(r2->get_con()) & (juint)(BitsPerJavaInteger - 1); // semantics of Java shifts
+ return TypeInt::make((r1_con >> shift) | (r1_con << (32 - shift)));
}
return TypeInt::INT;
} else {
@@ -1600,8 +1603,9 @@ const Type* RotateRightNode::Value(PhaseGVN* phase) const {
return r1;
}
if (r1->is_con() && r2->is_con()) {
- int shift = r2->get_con() & (BitsPerJavaLong - 1); // semantics of Java shifts
- return TypeLong::make((r1->get_con() >> shift) | (r1->get_con() << (64 - shift)));
+ julong r1_con = (julong)r1->get_con();
+ julong shift = (julong)(r2->get_con()) & (julong)(BitsPerJavaLong - 1); // semantics of Java shifts
+ return TypeLong::make((r1_con >> shift) | (r1_con << (64 - shift)));
}
return TypeLong::LONG;
}
diff --git a/test/hotspot/jtreg/compiler/c2/TestRotateNegativeEvenValues.java b/test/hotspot/jtreg/compiler/c2/TestRotateNegativeEvenValues.java
new file mode 100644
index 0000000000000..edac80ae69b58
--- /dev/null
+++ b/test/hotspot/jtreg/compiler/c2/TestRotateNegativeEvenValues.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 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
+ * @bug 8257182
+ * @requires vm.compiler2.enabled
+ * @summary Test RotateLeftNode and RotateRightNode with negative even numbers which produces a wrong result due to
+ * applying an arithemtic instead of a logical shift.
+ * @run main/othervm -XX:CompileCommand=compileonly,compiler.c2.TestRotateNegativeEvenValues::run
+ * -XX:CompileCommand=inline,compiler.c2.TestRotateNegativeEvenValues::test
+ * -Xcomp -XX:-TieredCompilation compiler.c2.TestRotateNegativeEvenValues
+ */
+package compiler.c2;
+
+public class TestRotateNegativeEvenValues {
+
+ public static void run() {
+ test(1 << 31); // INT_MIN
+ test(1L << 63); // LONG_MIN
+ test(-1 << 10); // -1024
+ test(-1L << 10); // -1024
+ test(-1 << 20); // -1048576
+ test(-1L << 20); // -1048576
+ test(-2); // 111...10
+ test(-2L); // 111...10
+ test(-3546); // Random minus even number
+ test(-3546L); // Random minus even number
+ }
+
+ // Inlined such that negativeEvenNumber is a constant
+ public static void test(int negativeEvenNumber) {
+ for (int i = 1; i <= 1; i++) {
+ int leftShift = negativeEvenNumber << -i;
+ int rightShift = negativeEvenNumber >>> i;
+ if ((leftShift | rightShift) != (rightShift | leftShift)) {
+ int or1 = leftShift | rightShift;
+ int or2 = rightShift | leftShift;
+ throw new RuntimeException("Or operations are not equal:" + " " + or1 + " vs. "+ or2
+ + " - leftShift: " + leftShift + ", rightShift: " + rightShift);
+ }
+ }
+ }
+
+ // Inlined such that negativeEvenNumber is a constant
+ public static void test(long negativeEvenNumber) {
+ for (int i = 1; i <= 1; i++) {
+ long leftShift = negativeEvenNumber << -i;
+ long rightShift = negativeEvenNumber >>> i;
+ if ((leftShift | rightShift) != (rightShift | leftShift)) {
+ long or1 = leftShift | rightShift;
+ long or2 = rightShift | leftShift;
+ throw new RuntimeException("Or operations are not equal:" + " " + or1 + " vs. "+ or2
+ + " - leftShift: " + leftShift + ", rightShift: " + rightShift);
+ }
+ }
+ }
+
+ public static void main(String argv[]) {
+ run();
+ }
+}
From ca402671afd74003f0b68b1c94d956be3b10ed5f Mon Sep 17 00:00:00 2001
From: Thomas Schatzl
Date: Fri, 4 Dec 2020 08:40:12 +0000
Subject: [PATCH 068/504] 8257509: Strengthen requirements to call
G1HeapVerifier::verify(VerifyOption)
Reviewed-by: sjohanss, ayang
---
src/hotspot/share/gc/g1/g1HeapVerifier.cpp | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/src/hotspot/share/gc/g1/g1HeapVerifier.cpp b/src/hotspot/share/gc/g1/g1HeapVerifier.cpp
index ec97cb463d3b2..09c869f45822e 100644
--- a/src/hotspot/share/gc/g1/g1HeapVerifier.cpp
+++ b/src/hotspot/share/gc/g1/g1HeapVerifier.cpp
@@ -471,12 +471,7 @@ bool G1HeapVerifier::should_verify(G1VerifyType type) {
}
void G1HeapVerifier::verify(VerifyOption vo) {
- if (!SafepointSynchronize::is_at_safepoint()) {
- log_info(gc, verify)("Skipping verification. Not at safepoint.");
- }
-
- assert(Thread::current()->is_VM_thread(),
- "Expected to be executed serially by the VM thread at this point");
+ assert_at_safepoint_on_vm_thread();
log_debug(gc, verify)("Roots");
VerifyRootsClosure rootsCl(vo);
From 2b4a423fd70b729e70e3376c105a92fc99d6215b Mon Sep 17 00:00:00 2001
From: Alan Bateman
Date: Fri, 4 Dec 2020 08:59:14 +0000
Subject: [PATCH 069/504] 8255542: Attribute length of Module, ModulePackages
and other attributes is ignored
Reviewed-by: mchung, dfuchs, chegar
---
.../jdk/internal/module/ModuleInfo.java | 134 +++++++++++++++++-
.../BadModuleAttributeLength/Driver.java | 31 ++++
.../BadModuleAttributeLength/module-info.jcod | 98 +++++++++++++
.../BadModuleMainAttributeLength/Driver.java | 31 ++++
.../module-info.jcod | 98 +++++++++++++
.../Driver.java | 31 ++++
.../module-info.jcod | 98 +++++++++++++
.../module/badclasses/CheckBadModuleInfo.java | 50 +++++++
8 files changed, 566 insertions(+), 5 deletions(-)
create mode 100644 test/jdk/java/lang/module/badclasses/BadModuleAttributeLength/Driver.java
create mode 100644 test/jdk/java/lang/module/badclasses/BadModuleAttributeLength/module-info.jcod
create mode 100644 test/jdk/java/lang/module/badclasses/BadModuleMainAttributeLength/Driver.java
create mode 100644 test/jdk/java/lang/module/badclasses/BadModuleMainAttributeLength/module-info.jcod
create mode 100644 test/jdk/java/lang/module/badclasses/BadModulePackagesAttributeLength/Driver.java
create mode 100644 test/jdk/java/lang/module/badclasses/BadModulePackagesAttributeLength/module-info.jcod
create mode 100644 test/jdk/java/lang/module/badclasses/CheckBadModuleInfo.java
diff --git a/src/java.base/share/classes/jdk/internal/module/ModuleInfo.java b/src/java.base/share/classes/jdk/internal/module/ModuleInfo.java
index 46e22d544d65c..338fbeb9555ae 100644
--- a/src/java.base/share/classes/jdk/internal/module/ModuleInfo.java
+++ b/src/java.base/share/classes/jdk/internal/module/ModuleInfo.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -180,7 +180,8 @@ public static Attributes readIgnoringHashes(ByteBuffer bb, Supplier>
* because an identifier is not a legal Java identifier, duplicate
* exports, and many other reasons
*/
- private Attributes doRead(DataInput in) throws IOException {
+ private Attributes doRead(DataInput input) throws IOException {
+ var in = new CountingDataInput(input);
int magic = in.readInt();
if (magic != 0xCAFEBABE)
@@ -243,8 +244,9 @@ private Attributes doRead(DataInput in) throws IOException {
+ attribute_name + " attribute");
}
- switch (attribute_name) {
+ long initialPosition = in.count();
+ switch (attribute_name) {
case MODULE :
builder = readModuleAttribute(in, cpool, major_version);
break;
@@ -280,8 +282,15 @@ private Attributes doRead(DataInput in) throws IOException {
} else {
in.skipBytes(length);
}
+ }
+ long newPosition = in.count();
+ if ((newPosition - initialPosition) != length) {
+ // attribute length does not match actual attribute size
+ throw invalidModuleDescriptor("Attribute " + attribute_name
+ + " does not match its expected length");
}
+
}
// the Module attribute is required
@@ -1079,12 +1088,127 @@ public String readUTF() throws IOException {
}
}
+ /**
+ * A DataInput implementation that reads from another DataInput and counts
+ * the number of bytes read.
+ */
+ private static class CountingDataInput implements DataInput {
+ private final DataInput delegate;
+ private long count;
+
+ CountingDataInput(DataInput delegate) {
+ this.delegate = delegate;
+ }
+
+ long count() {
+ return count;
+ }
+
+ @Override
+ public void readFully(byte b[]) throws IOException {
+ delegate.readFully(b, 0, b.length);
+ count += b.length;
+ }
+
+ @Override
+ public void readFully(byte b[], int off, int len) throws IOException {
+ delegate.readFully(b, off, len);
+ count += len;
+ }
+
+ @Override
+ public int skipBytes(int n) throws IOException {
+ int skip = delegate.skipBytes(n);
+ count += skip;
+ return skip;
+ }
+
+ @Override
+ public boolean readBoolean() throws IOException {
+ boolean b = delegate.readBoolean();
+ count++;
+ return b;
+ }
+
+ @Override
+ public byte readByte() throws IOException {
+ byte b = delegate.readByte();
+ count++;
+ return b;
+ }
+
+ @Override
+ public int readUnsignedByte() throws IOException {
+ int i = delegate.readUnsignedByte();
+ count++;
+ return i;
+ }
+
+ @Override
+ public short readShort() throws IOException {
+ short s = delegate.readShort();
+ count += 2;
+ return s;
+ }
+
+ @Override
+ public int readUnsignedShort() throws IOException {
+ int s = delegate.readUnsignedShort();
+ count += 2;
+ return s;
+ }
+
+ @Override
+ public char readChar() throws IOException {
+ char c = delegate.readChar();
+ count += 2;
+ return c;
+ }
+
+ @Override
+ public int readInt() throws IOException {
+ int i = delegate.readInt();
+ count += 4;
+ return i;
+ }
+
+ @Override
+ public long readLong() throws IOException {
+ long l = delegate.readLong();
+ count += 8;
+ return l;
+ }
+
+ @Override
+ public float readFloat() throws IOException {
+ float f = delegate.readFloat();
+ count += 4;
+ return f;
+ }
+
+ @Override
+ public double readDouble() throws IOException {
+ double d = delegate.readDouble();
+ count += 8;
+ return d;
+ }
+
+ @Override
+ public String readLine() {
+ throw new RuntimeException("not implemented");
+ }
+
+ @Override
+ public String readUTF() throws IOException {
+ return DataInputStream.readUTF(this);
+ }
+ }
+
/**
* Returns an InvalidModuleDescriptorException with the given detail
* message
*/
- private static InvalidModuleDescriptorException
- invalidModuleDescriptor(String msg) {
+ private static InvalidModuleDescriptorException invalidModuleDescriptor(String msg) {
return new InvalidModuleDescriptorException(msg);
}
diff --git a/test/jdk/java/lang/module/badclasses/BadModuleAttributeLength/Driver.java b/test/jdk/java/lang/module/badclasses/BadModuleAttributeLength/Driver.java
new file mode 100644
index 0000000000000..36e28f87777ec
--- /dev/null
+++ b/test/jdk/java/lang/module/badclasses/BadModuleAttributeLength/Driver.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 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
+ * @bug 8255542
+ * @summary Module attribute has incorrect length
+ * @library ..
+ * @build module-info
+ * @run main CheckBadModuleInfo
+ */
diff --git a/test/jdk/java/lang/module/badclasses/BadModuleAttributeLength/module-info.jcod b/test/jdk/java/lang/module/badclasses/BadModuleAttributeLength/module-info.jcod
new file mode 100644
index 0000000000000..9940498583d13
--- /dev/null
+++ b/test/jdk/java/lang/module/badclasses/BadModuleAttributeLength/module-info.jcod
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 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.
+ */
+
+module {
+ 0xCAFEBABE;
+ 0; // minor version
+ 55; // version
+ [] { // Constant Pool
+ ; // first element is empty
+ Utf8 "module-info"; // #1
+ class #1; // #2
+ Utf8 "module-info.java"; // #3
+ Utf8 "m"; // #4
+ Module #4; // #5
+ Utf8 "ModuleMainClass"; // #6
+ Utf8 "p/C"; // #7
+ class #7; // #8
+ Utf8 "ModulePackages"; // #9
+ Utf8 "p"; // #10
+ Package #10; // #11
+ Utf8 "java.base"; // #12
+ Module #12; // #13
+ Utf8 "11.0.2"; // #14
+ Utf8 "SourceFile"; // #15
+ Utf8 "Module"; // #16
+ } // Constant Pool
+
+ 0x8000; // access
+ #2;// this_cpx
+ #0;// super_cpx
+
+ [] { // Interfaces
+ } // Interfaces
+
+ [] { // Fields
+ } // Fields
+
+ [] { // Methods
+ } // Methods
+
+ [] { // Attributes
+ Attr(#15) { // SourceFile
+ #3;
+ } // end SourceFile
+ ;
+ Attr(#16, 256) { // Module incorrect attribute length
+ #5; // name_index
+ 0x0000; // flags
+ #0; // version
+ [] { // requires
+ #13 0x8000 #14;
+ } // requires
+
+ [] { // exports
+ } // exports
+
+ [] { // opens
+ } // opens
+
+ [] { // uses
+ } // uses
+
+ [] { // provides
+ } // provides
+
+ } // end Module
+ ;
+ Attr(#6) { // ModuleMainClass
+ 0x0008;
+ } // end ModuleMainClass
+ ;
+ Attr(#9) { // ModulePackages
+ [] {
+ #11;
+ }
+ } // end ModulePackages
+ } // Attributes
+} // end module m
diff --git a/test/jdk/java/lang/module/badclasses/BadModuleMainAttributeLength/Driver.java b/test/jdk/java/lang/module/badclasses/BadModuleMainAttributeLength/Driver.java
new file mode 100644
index 0000000000000..5ea4261cc52a7
--- /dev/null
+++ b/test/jdk/java/lang/module/badclasses/BadModuleMainAttributeLength/Driver.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 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
+ * @bug 8255542
+ * @summary ModuleMain attribute has incorrect length
+ * @library ..
+ * @build module-info
+ * @run main CheckBadModuleInfo
+ */
diff --git a/test/jdk/java/lang/module/badclasses/BadModuleMainAttributeLength/module-info.jcod b/test/jdk/java/lang/module/badclasses/BadModuleMainAttributeLength/module-info.jcod
new file mode 100644
index 0000000000000..499e02d54cf77
--- /dev/null
+++ b/test/jdk/java/lang/module/badclasses/BadModuleMainAttributeLength/module-info.jcod
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 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.
+ */
+
+module {
+ 0xCAFEBABE;
+ 0; // minor version
+ 55; // version
+ [] { // Constant Pool
+ ; // first element is empty
+ Utf8 "module-info"; // #1
+ class #1; // #2
+ Utf8 "module-info.java"; // #3
+ Utf8 "m"; // #4
+ Module #4; // #5
+ Utf8 "ModuleMainClass"; // #6
+ Utf8 "p/C"; // #7
+ class #7; // #8
+ Utf8 "ModulePackages"; // #9
+ Utf8 "p"; // #10
+ Package #10; // #11
+ Utf8 "java.base"; // #12
+ Module #12; // #13
+ Utf8 "11.0.2"; // #14
+ Utf8 "SourceFile"; // #15
+ Utf8 "Module"; // #16
+ } // Constant Pool
+
+ 0x8000; // access
+ #2;// this_cpx
+ #0;// super_cpx
+
+ [] { // Interfaces
+ } // Interfaces
+
+ [] { // Fields
+ } // Fields
+
+ [] { // Methods
+ } // Methods
+
+ [] { // Attributes
+ Attr(#15) { // SourceFile
+ #3;
+ } // end SourceFile
+ ;
+ Attr(#16) { // Module
+ #5; // name_index
+ 0x0000; // flags
+ #0; // version
+ [] { // requires
+ #13 0x8000 #14;
+ } // requires
+
+ [] { // exports
+ } // exports
+
+ [] { // opens
+ } // opens
+
+ [] { // uses
+ } // uses
+
+ [] { // provides
+ } // provides
+
+ } // end Module
+ ;
+ Attr(#6, 3) { // ModuleMainClass attribute_length 3 instead of 2
+ 0x0008;
+ } // end ModuleMainClass
+ ;
+ Attr(#9) { // ModulePackages
+ [] {
+ #11;
+ }
+ } // end ModulePackages
+ } // Attributes
+} // end module m
diff --git a/test/jdk/java/lang/module/badclasses/BadModulePackagesAttributeLength/Driver.java b/test/jdk/java/lang/module/badclasses/BadModulePackagesAttributeLength/Driver.java
new file mode 100644
index 0000000000000..0df28a110d553
--- /dev/null
+++ b/test/jdk/java/lang/module/badclasses/BadModulePackagesAttributeLength/Driver.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 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
+ * @bug 8255542
+ * @summary ModulePackages attribute has incorrect length
+ * @library ..
+ * @build module-info
+ * @run main CheckBadModuleInfo
+ */
diff --git a/test/jdk/java/lang/module/badclasses/BadModulePackagesAttributeLength/module-info.jcod b/test/jdk/java/lang/module/badclasses/BadModulePackagesAttributeLength/module-info.jcod
new file mode 100644
index 0000000000000..c725085b87d64
--- /dev/null
+++ b/test/jdk/java/lang/module/badclasses/BadModulePackagesAttributeLength/module-info.jcod
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 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.
+ */
+
+module {
+ 0xCAFEBABE;
+ 0; // minor version
+ 55; // version
+ [] { // Constant Pool
+ ; // first element is empty
+ Utf8 "module-info"; // #1
+ class #1; // #2
+ Utf8 "module-info.java"; // #3
+ Utf8 "m"; // #4
+ Module #4; // #5
+ Utf8 "ModuleMainClass"; // #6
+ Utf8 "p/C"; // #7
+ class #7; // #8
+ Utf8 "ModulePackages"; // #9
+ Utf8 "p"; // #10
+ Package #10; // #11
+ Utf8 "java.base"; // #12
+ Module #12; // #13
+ Utf8 "11.0.2"; // #14
+ Utf8 "SourceFile"; // #15
+ Utf8 "Module"; // #16
+ } // Constant Pool
+
+ 0x8000; // access
+ #2;// this_cpx
+ #0;// super_cpx
+
+ [] { // Interfaces
+ } // Interfaces
+
+ [] { // Fields
+ } // Fields
+
+ [] { // Methods
+ } // Methods
+
+ [] { // Attributes
+ Attr(#15) { // SourceFile
+ #3;
+ } // end SourceFile
+ ;
+ Attr(#16) { // Module
+ #5; // name_index
+ 0x0000; // flags
+ #0; // version
+ [] { // requires
+ #13 0x8000 #14;
+ } // requires
+
+ [] { // exports
+ } // exports
+
+ [] { // opens
+ } // opens
+
+ [] { // uses
+ } // uses
+
+ [] { // provides
+ } // provides
+
+ } // end Module
+ ;
+ Attr(#6) { // ModuleMainClass
+ 0x0008;
+ } // end ModuleMainClass
+ ;
+ Attr(#9, 6) { // ModulePackages attribute_length 6 instead of 4
+ [] {
+ #11;
+ }
+ } // end ModulePackages
+ } // Attributes
+} // end module m
diff --git a/test/jdk/java/lang/module/badclasses/CheckBadModuleInfo.java b/test/jdk/java/lang/module/badclasses/CheckBadModuleInfo.java
new file mode 100644
index 0000000000000..d6e7d27c556fe
--- /dev/null
+++ b/test/jdk/java/lang/module/badclasses/CheckBadModuleInfo.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 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.
+ */
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.module.ModuleDescriptor;
+import java.lang.module.InvalidModuleDescriptorException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+/**
+ * Uses the ModuleDescriptor.read API to read the module-info.class in the
+ * ${test.classes} directory and expects InvalidModuleDescriptorException
+ * to be thrown.
+ */
+public class CheckBadModuleInfo {
+ public static void main(String[] args) throws IOException {
+ Path mi = Path.of(System.getProperty("test.classes"), "module-info.class");
+ try (InputStream in = Files.newInputStream(mi)) {
+ try {
+ ModuleDescriptor descriptor = ModuleDescriptor.read(in);
+ System.out.println(descriptor);
+ throw new RuntimeException("InvalidModuleDescriptorException expected");
+ } catch (InvalidModuleDescriptorException e) {
+ // expected
+ System.out.println(e);
+ }
+ }
+ }
+}
From d6dd440c767b351cda3f0f0eafa334f776a75a08 Mon Sep 17 00:00:00 2001
From: Alexander Scherbatiy
Date: Fri, 4 Dec 2020 09:02:20 +0000
Subject: [PATCH 070/504] 8256264: Printed GlyphVector outline with low DPI has
bad quality on Windows
Reviewed-by: serb
---
.../sun/awt/windows/WPathGraphics.java | 4 +-
.../classes/sun/awt/windows/WPrinterJob.java | 118 +++++++-
.../native/libawt/windows/awt_PrintJob.cpp | 105 ++++++++
.../PathPrecisionScaleFactorTest.java | 254 ++++++++++++++++++
4 files changed, 470 insertions(+), 11 deletions(-)
create mode 100644 test/jdk/java/awt/print/PathPrecisionScaleFactor/PathPrecisionScaleFactorTest.java
diff --git a/src/java.desktop/windows/classes/sun/awt/windows/WPathGraphics.java b/src/java.desktop/windows/classes/sun/awt/windows/WPathGraphics.java
index 6de773eb52e42..d642f73143383 100644
--- a/src/java.desktop/windows/classes/sun/awt/windows/WPathGraphics.java
+++ b/src/java.desktop/windows/classes/sun/awt/windows/WPathGraphics.java
@@ -1760,8 +1760,8 @@ private void convertToWPath(PathIterator pathIter) {
/* Convert the quad path to a bezier.
*/
case PathIterator.SEG_QUADTO:
- int lastX = wPrinterJob.getPenX();
- int lastY = wPrinterJob.getPenY();
+ float lastX = wPrinterJob.getPenX();
+ float lastY = wPrinterJob.getPenY();
float c1x = lastX + (segment[0] - lastX) * 2 / 3;
float c1y = lastY + (segment[1] - lastY) * 2 / 3;
float c2x = segment[2] - (segment[2] - segment[0]) * 2/ 3;
diff --git a/src/java.desktop/windows/classes/sun/awt/windows/WPrinterJob.java b/src/java.desktop/windows/classes/sun/awt/windows/WPrinterJob.java
index a2ca2b7ec8cac..403f960ffe730 100644
--- a/src/java.desktop/windows/classes/sun/awt/windows/WPrinterJob.java
+++ b/src/java.desktop/windows/classes/sun/awt/windows/WPrinterJob.java
@@ -362,6 +362,10 @@ public void dispose() {
private java.awt.peer.ComponentPeer dialogOwnerPeer = null;
+ private static final float precisionScale = 1000.0f;
+ private int graphicsMode;
+ private double[] worldTransform = new double[6];
+
/* Static Initializations */
static {
@@ -953,11 +957,33 @@ private void setDevNames(long mPrintHDevNames) {
}
protected void beginPath() {
+ precisionScaleBegin();
beginPath(getPrintDC());
}
protected void endPath() {
endPath(getPrintDC());
+ precisionScaleEnd();
+ }
+
+ protected float precisionScaleUp(float value) {
+ return value * precisionScale;
+ }
+
+ protected float precisionScaleDown(float value) {
+ return value / precisionScale;
+ }
+
+ protected void precisionScaleBegin() {
+ graphicsMode = setAdvancedGraphicsMode();
+ getWorldTransform(worldTransform);
+ float invPrecisionScale = 1.0f / precisionScale;
+ scale(invPrecisionScale, invPrecisionScale);
+ }
+
+ protected void precisionScaleEnd() {
+ setWorldTransform(worldTransform);
+ setGraphicsMode(graphicsMode);
}
protected void closeFigure() {
@@ -969,20 +995,23 @@ protected void fillPath() {
}
protected void moveTo(float x, float y) {
- moveTo(getPrintDC(), x, y);
+ moveTo(getPrintDC(),
+ precisionScaleUp(x), precisionScaleUp(y));
}
protected void lineTo(float x, float y) {
- lineTo(getPrintDC(), x, y);
+ lineTo(getPrintDC(),
+ precisionScaleUp(x), precisionScaleUp(y));
}
protected void polyBezierTo(float control1x, float control1y,
float control2x, float control2y,
float endX, float endY) {
- polyBezierTo(getPrintDC(), control1x, control1y,
- control2x, control2y,
- endX, endY);
+ polyBezierTo(getPrintDC(),
+ precisionScaleUp(control1x), precisionScaleUp(control1y),
+ precisionScaleUp(control2x), precisionScaleUp(control2y),
+ precisionScaleUp(endX), precisionScaleUp(endY));
}
/**
@@ -995,6 +1024,44 @@ protected void setPolyFillMode(int fillRule) {
setPolyFillMode(getPrintDC(), fillRule);
}
+ /**
+ * Set the GDI graphics mode to {@code GM_ADVANCED}.
+ */
+ private int setAdvancedGraphicsMode() {
+ return setAdvancedGraphicsMode(getPrintDC());
+ }
+
+ /**
+ * Set the GDI graphics mode.
+ * The {@code mode} should
+ * be one of the following Windows constants:
+ * {@code GM_COMPATIBLE} or {@code GM_ADVANCED}.
+ */
+ private int setGraphicsMode(int mode) {
+ return setGraphicsMode(getPrintDC(), mode);
+ }
+
+ /**
+ * Scale the GDI World Transform.
+ */
+ private void scale(double scaleX, double scaleY) {
+ scale(getPrintDC(), scaleX, scaleY);
+ }
+
+ /**
+ * Get the GDI World Transform.
+ */
+ private void getWorldTransform(double[] transform) {
+ getWorldTransform(getPrintDC(), transform);
+ }
+
+ /**
+ * Set the GDI World Transform.
+ */
+ private void setWorldTransform(double[] transform) {
+ setWorldTransform(getPrintDC(), transform);
+ }
+
/*
* Create a Window's solid brush for the color specified
* by {@code (red, green, blue)}. Once the brush
@@ -1020,9 +1087,9 @@ protected void selectSolidBrush(Color color) {
* Return the x coordinate of the current pen
* position in the print device context.
*/
- protected int getPenX() {
+ protected float getPenX() {
- return getPenX(getPrintDC());
+ return precisionScaleDown(getPenX(getPrintDC()));
}
@@ -1030,9 +1097,9 @@ protected int getPenX() {
* Return the y coordinate of the current pen
* position in the print device context.
*/
- protected int getPenY() {
+ protected float getPenY() {
- return getPenY(getPrintDC());
+ return precisionScaleDown(getPenY(getPrintDC()));
}
/**
@@ -1470,6 +1537,39 @@ protected native void polyBezierTo(long printDC,
*/
protected native void setPolyFillMode(long printDC, int fillRule);
+ /**
+ * Set the GDI graphics mode to {@code GM_ADVANCED}
+ * into the device context {@code printDC}.
+ */
+ protected native int setAdvancedGraphicsMode(long printDC);
+
+ /**
+ * Set the GDI graphics mode to {@code GM_ADVANCED}
+ * into the device context {@code printDC}.
+ * The {@code mode} should
+ * be one of the following Windows constants:
+ * {@code GM_COMPATIBLE} or {@code GM_ADVANCED}.
+ */
+ protected native int setGraphicsMode(long printDC, int mode);
+
+ /**
+ * Scale the GDI World Transform
+ * of the device context {@code printDC}.
+ */
+ protected native void scale(long printDC, double scaleX, double scaleY);
+
+ /**
+ * Get the GDI World Transform
+ * from the device context {@code printDC}.
+ */
+ protected native void getWorldTransform(long printDC, double[] transform);
+
+ /**
+ * Set the GDI World Transform
+ * into the device context {@code printDC}.
+ */
+ protected native void setWorldTransform(long printDC, double[] transform);
+
/**
* Create a Window's solid brush for the color specified
* by {@code (red, green, blue)}. Once the brush
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 618ae9e1a827a..925000c256b0e 100644
--- a/src/java.desktop/windows/native/libawt/windows/awt_PrintJob.cpp
+++ b/src/java.desktop/windows/native/libawt/windows/awt_PrintJob.cpp
@@ -1932,6 +1932,111 @@ JNIEXPORT void JNICALL Java_sun_awt_windows_WPrinterJob_setPolyFillMode
CATCH_BAD_ALLOC;
}
+/*
+ * Class: sun_awt_windows_WPrinterJob
+ * Method: setAdvancedGraphicsMode
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL Java_sun_awt_windows_WPrinterJob_setAdvancedGraphicsMode
+(JNIEnv *env, jobject self, jlong printDC) {
+ TRY;
+
+ return (jint) ::SetGraphicsMode((HDC)printDC, GM_ADVANCED);
+
+ CATCH_BAD_ALLOC_RET(0);
+}
+
+/*
+ * Class: sun_awt_windows_WPrinterJob
+ * Method: setGraphicsMode
+ * Signature: (JI)I
+ */
+JNIEXPORT jint JNICALL Java_sun_awt_windows_WPrinterJob_setGraphicsMode
+(JNIEnv *env, jobject self, jlong printDC, jint mode) {
+ TRY;
+
+ return (jint) ::SetGraphicsMode((HDC)printDC, mode);
+
+ CATCH_BAD_ALLOC_RET(0);
+}
+
+/*
+ * Class: sun_awt_windows_WPrinterJob
+ * Method: scale
+ * Signature: (JDD)V
+ */
+JNIEXPORT void JNICALL Java_sun_awt_windows_WPrinterJob_scale
+(JNIEnv *env, jobject self, jlong printDC, jdouble scaleX, jdouble scaleY) {
+ TRY;
+
+ XFORM xForm;
+
+ xForm.eM11 = (FLOAT) scaleX;
+ xForm.eM12 = (FLOAT) 0;
+ xForm.eM21 = (FLOAT) 0;
+ xForm.eM22 = (FLOAT) scaleY;
+ xForm.eDx = (FLOAT) 0;
+ xForm.eDy = (FLOAT) 0;
+
+ ::ModifyWorldTransform((HDC)printDC, &xForm, MWT_RIGHTMULTIPLY);
+
+ CATCH_BAD_ALLOC;
+}
+
+/*
+ * Class: sun_awt_windows_WPrinterJob
+ * Method: getWorldTransform
+ * Signature: (J[D)V
+ */
+JNIEXPORT void JNICALL Java_sun_awt_windows_WPrinterJob_getWorldTransform
+(JNIEnv* env, jobject self, jlong printDC, jdoubleArray transform) {
+ TRY;
+
+ double elems[6];
+ XFORM xForm;
+
+ ::GetWorldTransform((HDC)printDC, &xForm);
+
+ elems[0] = (double) xForm.eM11;
+ elems[1] = (double) xForm.eM12;
+ elems[2] = (double) xForm.eM21;
+ elems[3] = (double) xForm.eM22;
+ elems[4] = (double) xForm.eDx;
+ elems[5] = (double) xForm.eDy;
+
+ env->SetDoubleArrayRegion(transform, 0, 6, elems);
+
+ CATCH_BAD_ALLOC;
+}
+
+/*
+ * Class: sun_awt_windows_WPrinterJob
+ * Method: setWorldTransform
+ * Signature: (J[D)V
+ */
+JNIEXPORT void JNICALL Java_sun_awt_windows_WPrinterJob_setWorldTransform
+(JNIEnv* env, jobject self, jlong printDC, jdoubleArray transform) {
+ TRY;
+
+ double *elems;
+ XFORM xForm;
+
+ elems = env->GetDoubleArrayElements(transform, 0);
+
+ xForm.eM11 = (FLOAT) elems[0];
+ xForm.eM12 = (FLOAT) elems[1];
+ xForm.eM21 = (FLOAT) elems[2];
+ xForm.eM22 = (FLOAT) elems[3];
+ xForm.eDx = (FLOAT) elems[4];
+ xForm.eDy = (FLOAT) elems[5];
+
+ ::SetWorldTransform((HDC)printDC, &xForm);
+
+ env->ReleaseDoubleArrayElements(transform, elems, 0);
+
+ CATCH_BAD_ALLOC;
+}
+
/*
* Class: sun_awt_windows_WPrinterJob
* Method: selectSolidBrush
diff --git a/test/jdk/java/awt/print/PathPrecisionScaleFactor/PathPrecisionScaleFactorTest.java b/test/jdk/java/awt/print/PathPrecisionScaleFactor/PathPrecisionScaleFactorTest.java
new file mode 100644
index 0000000000000..2bf2e8e391ec2
--- /dev/null
+++ b/test/jdk/java/awt/print/PathPrecisionScaleFactor/PathPrecisionScaleFactorTest.java
@@ -0,0 +1,254 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, BELLSOFT. All rights reserved.
+ * 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 8256264
+ * @requires (os.family == "windows")
+ * @summary Check that a GlyphVector outline is printed with good quility on low dpi printers
+ * @run main/othervm/manual PathPrecisionScaleFactorTest
+ */
+
+import javax.print.PrintServiceLookup;
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphVector;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.print.PageFormat;
+import java.awt.print.Printable;
+import java.awt.print.PrinterException;
+import java.awt.print.PrinterJob;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class PathPrecisionScaleFactorTest {
+
+ private static final String DESCRIPTION =
+ " 1. Setup 'Microsoft Print to PDF' printer on Windows.\n" +
+ " 2. Press Print button to print the text to PDF.\n" +
+ " 3. Choose 'Microsoft Print to PDF' on the print dialog and press OK\n" +
+ " Two strings should be printed." +
+ " The first line is printed using drawString() method" +
+ " and the second line is printed using filling glyph vector outline.\n" +
+ " 3. Open the PDF file, zoom in the text and check that chars on the second line " +
+ " (especially 'a' and 's') are not distorted and have the similar quality" +
+ " as on the first line.\n" +
+ " 4. If so, press PASS button, otherwise press FAIL button.\n";
+
+ private static final CountDownLatch testEndedSignal = new CountDownLatch(1);
+ private static final int testTimeout = 300000;
+ private static volatile String testFailureMsg;
+ private static volatile boolean testPassed;
+ private static volatile boolean testFinished;
+
+ public static void main(String[] args) throws Exception {
+
+ SwingUtilities.invokeLater(() -> createAndShowTestDialog());
+
+ try {
+ if (!testEndedSignal.await(testTimeout, TimeUnit.MILLISECONDS)) {
+ throw new RuntimeException(String.format(
+ "Test timeout '%d ms' elapsed.", testTimeout));
+ }
+ if (!testPassed) {
+ String failureMsg = testFailureMsg;
+ if ((failureMsg != null) && (!failureMsg.trim().isEmpty())) {
+ throw new RuntimeException(failureMsg);
+ } else {
+ throw new RuntimeException("Test failed.");
+ }
+ }
+ } catch (InterruptedException ie) {
+ throw new RuntimeException(ie);
+ } finally {
+ testFinished = true;
+ }
+ }
+
+ private static void pass() {
+ testPassed = true;
+ testEndedSignal.countDown();
+ }
+
+ private static void fail(String failureMsg) {
+ testFailureMsg = failureMsg;
+ testPassed = false;
+ testEndedSignal.countDown();
+ }
+
+ private static String convertMillisToTimeStr(int millis) {
+ if (millis < 0) {
+ return "00:00:00";
+ }
+ int hours = millis / 3600000;
+ int minutes = (millis - hours * 3600000) / 60000;
+ int seconds = (millis - hours * 3600000 - minutes * 60000) / 1000;
+ return String.format("%02d:%02d:%02d", hours, minutes, seconds);
+ }
+
+ private static void createAndShowTestDialog() {
+
+ final JDialog dialog = new JDialog();
+ dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
+ dialog.addWindowListener(new WindowAdapter() {
+ @Override
+ public void windowClosing(WindowEvent e) {
+ dialog.dispose();
+ fail("Main dialog was closed.");
+ }
+ });
+
+ final JLabel testTimeoutLabel = new JLabel(String.format(
+ "Test timeout: %s", convertMillisToTimeStr(testTimeout)));
+ final long startTime = System.currentTimeMillis();
+ final Timer timer = new Timer(0, null);
+ timer.setDelay(1000);
+ timer.addActionListener((e) -> {
+ int leftTime = testTimeout - (int) (System.currentTimeMillis() - startTime);
+ if ((leftTime < 0) || testFinished) {
+ timer.stop();
+ dialog.dispose();
+ }
+ testTimeoutLabel.setText(String.format(
+ "Test timeout: %s", convertMillisToTimeStr(leftTime)));
+ });
+ timer.start();
+
+ JTextArea textArea = new JTextArea(DESCRIPTION);
+ textArea.setEditable(false);
+
+ final JButton testButton = new JButton("Print");
+ final JButton passButton = new JButton("PASS");
+ final JButton failButton = new JButton("FAIL");
+ testButton.addActionListener((e) -> {
+ testButton.setEnabled(false);
+ new Thread(() -> {
+ try {
+ doTest();
+
+ SwingUtilities.invokeLater(() -> {
+ passButton.setEnabled(true);
+ failButton.setEnabled(true);
+ });
+ } catch (Throwable t) {
+ t.printStackTrace();
+ dialog.dispose();
+ fail("Exception occurred in a thread executing the test.");
+ }
+ }).start();
+ });
+ passButton.setEnabled(false);
+ passButton.addActionListener((e) -> {
+ dialog.dispose();
+ pass();
+ });
+ failButton.setEnabled(false);
+ failButton.addActionListener((e) -> {
+ dialog.dispose();
+ fail("TitledBorder label is cut off");
+ });
+
+ JPanel mainPanel = new JPanel(new BorderLayout());
+ JPanel labelPanel = new JPanel(new FlowLayout());
+ labelPanel.add(testTimeoutLabel);
+ mainPanel.add(labelPanel, BorderLayout.NORTH);
+ mainPanel.add(textArea, BorderLayout.CENTER);
+ JPanel buttonPanel = new JPanel(new FlowLayout());
+ buttonPanel.add(testButton);
+ buttonPanel.add(passButton);
+ buttonPanel.add(failButton);
+ mainPanel.add(buttonPanel, BorderLayout.SOUTH);
+ dialog.add(mainPanel);
+
+ dialog.pack();
+ dialog.setVisible(true);
+ }
+
+ private static void doTest() throws Exception {
+ SwingUtilities.invokeAndWait(() -> {
+ try {
+ new PathPrecisionScaleFactorPrintable();
+ } catch (PrinterException e) {
+ throw new RuntimeException(e);
+ }
+ });
+ }
+
+ private static class PathPrecisionScaleFactorPrintable implements Printable {
+
+ PathPrecisionScaleFactorPrintable() throws PrinterException {
+ PrinterJob job = PrinterJob.getPrinterJob();
+ job.setPrintService(PrintServiceLookup.lookupDefaultPrintService());
+ job.setPrintable(this);
+
+ if (job.printDialog()) {
+ job.print();
+ } else {
+ throw new RuntimeException("Printing was canceled!");
+ }
+ }
+
+ void paint(Graphics2D g) {
+
+ String text = "abcdefghijklmnopqrstuvwxyz";
+ Font font = new Font("Times New Roman", Font.PLAIN, 8);
+ drawText(g, font, text);
+ }
+
+ private static void drawText(Graphics2D g, Font font, String text) {
+
+ g.setFont(font);
+ FontRenderContext frc = new FontRenderContext(new AffineTransform(), false, true);
+
+ Rectangle clip = g.getClipBounds();
+ int cx = (int) clip.getCenterX();
+ int cy = (int) clip.getCenterY();
+
+ FontMetrics metrics = g.getFontMetrics();
+ int w = metrics.stringWidth(text);
+ int h = metrics.getHeight();
+
+ int x = cx - w / 2;
+ int y = cy - h / 2;
+
+ g.drawString(text + " [draw string]", x, y);
+ GlyphVector gv = font.createGlyphVector(frc, text + " [glyph vector]");
+ g.fill(gv.getOutline(x, y + h));
+ }
+
+ @Override
+ public int print(Graphics graphics, PageFormat pageFormat, int index) {
+ if (index == 0) {
+ paint((Graphics2D) graphics);
+ return PAGE_EXISTS;
+ } else {
+ return NO_SUCH_PAGE;
+ }
+ }
+ }
+}
From af6b7f9c5570e7901bd841813e92b4aca9469968 Mon Sep 17 00:00:00 2001
From: Hao Sun
Date: Fri, 4 Dec 2020 09:12:30 +0000
Subject: [PATCH 071/504] 8257743: Minimal build on AArch64 failed with
--disable-precompiled-headers
Reviewed-by: shade
---
src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp
index c73b42579205f..2ab37dc37ef99 100644
--- a/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp
+++ b/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp
@@ -25,6 +25,7 @@
#include "precompiled.hpp"
#include "asm/macroAssembler.inline.hpp"
+#include "classfile/javaClasses.hpp"
#include "gc/shared/barrierSetAssembler.hpp"
#include "interpreter/bytecodeHistogram.hpp"
#include "interpreter/interpreter.hpp"
From fd6756ee2b4c4d459c20e2b2f60c8b717eda584f Mon Sep 17 00:00:00 2001
From: Vladimir Ivanov
Date: Fri, 4 Dec 2020 09:24:08 +0000
Subject: [PATCH 072/504] 8257634: C2: Introduce
IncrementalInliningForceCleanup diagnostic flag
Reviewed-by: kvn, adityam, thartmann
---
src/hotspot/share/compiler/compilerDirectives.hpp | 1 +
src/hotspot/share/compiler/compilerOracle.hpp | 1 +
src/hotspot/share/opto/c2_globals.hpp | 3 +++
src/hotspot/share/opto/compile.cpp | 4 +++-
4 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/src/hotspot/share/compiler/compilerDirectives.hpp b/src/hotspot/share/compiler/compilerDirectives.hpp
index 0b4516072db06..4fca75be79bfc 100644
--- a/src/hotspot/share/compiler/compilerDirectives.hpp
+++ b/src/hotspot/share/compiler/compilerDirectives.hpp
@@ -70,6 +70,7 @@ NOT_PRODUCT(cflags(PrintIdeal, bool, PrintIdeal, PrintIdeal)) \
cflags(CloneMapDebug, bool, false, CloneMapDebug) \
NOT_PRODUCT(cflags(IGVPrintLevel, intx, PrintIdealGraphLevel, IGVPrintLevel)) \
cflags(VectorizeDebug, uintx, 0, VectorizeDebug) \
+ cflags(IncrementalInlineForceCleanup, bool, IncrementalInlineForceCleanup, IncrementalInlineForceCleanup) \
cflags(MaxNodeLimit, intx, MaxNodeLimit, MaxNodeLimit)
#else
#define compilerdirectives_c2_flags(cflags)
diff --git a/src/hotspot/share/compiler/compilerOracle.hpp b/src/hotspot/share/compiler/compilerOracle.hpp
index e8f7c2097a420..23cfde6f0625b 100644
--- a/src/hotspot/share/compiler/compilerOracle.hpp
+++ b/src/hotspot/share/compiler/compilerOracle.hpp
@@ -83,6 +83,7 @@ class methodHandle;
option(Vectorize, "Vectorize", Bool) \
option(VectorizeDebug, "VectorizeDebug", Uintx) \
option(CloneMapDebug, "CloneMapDebug", Bool) \
+ option(IncrementalInlineForceCleanup, "IncrementalInlineForceCleanup", Bool) \
option(MaxNodeLimit, "MaxNodeLimit", Intx) \
NOT_PRODUCT(option(TestOptionInt, "TestOptionInt", Intx)) \
NOT_PRODUCT(option(TestOptionUint, "TestOptionUint", Uintx)) \
diff --git a/src/hotspot/share/opto/c2_globals.hpp b/src/hotspot/share/opto/c2_globals.hpp
index 287d02f20b794..c73696d6ca514 100644
--- a/src/hotspot/share/opto/c2_globals.hpp
+++ b/src/hotspot/share/opto/c2_globals.hpp
@@ -716,6 +716,9 @@
develop(bool, AlwaysIncrementalInline, false, \
"do all inlining incrementally") \
\
+ product(bool, IncrementalInlineForceCleanup, false, DIAGNOSTIC, \
+ "do cleanup after every iteration of incremental inlining") \
+ \
product(intx, LiveNodeCountInliningCutoff, 40000, \
"max number of live nodes in a method") \
range(0, max_juint / 8) \
diff --git a/src/hotspot/share/opto/compile.cpp b/src/hotspot/share/opto/compile.cpp
index f6f3e427c0efc..77be65465c473 100644
--- a/src/hotspot/share/opto/compile.cpp
+++ b/src/hotspot/share/opto/compile.cpp
@@ -1880,7 +1880,9 @@ bool Compile::inline_incrementally_one() {
set_inlining_progress(false);
set_do_cleanup(false);
- return (_late_inlines.length() > 0) && !needs_cleanup;
+
+ bool force_cleanup = directive()->IncrementalInlineForceCleanupOption;
+ return (_late_inlines.length() > 0) && !needs_cleanup && !force_cleanup;
}
void Compile::inline_incrementally_cleanup(PhaseIterGVN& igvn) {
From fbdc1877e241552755ea208b890029e60a8df08c Mon Sep 17 00:00:00 2001
From: Vladimir Ivanov
Date: Fri, 4 Dec 2020 09:37:18 +0000
Subject: [PATCH 073/504] 8257624: C2:
PhaseMacroExpand::eliminate_macro_nodes() crashes on out-of-bounds access
into macro node array
Reviewed-by: neliasso, kvn
---
src/hotspot/share/opto/macro.cpp | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/hotspot/share/opto/macro.cpp b/src/hotspot/share/opto/macro.cpp
index 47d0d073f99db..3b33547197479 100644
--- a/src/hotspot/share/opto/macro.cpp
+++ b/src/hotspot/share/opto/macro.cpp
@@ -2564,7 +2564,10 @@ void PhaseMacroExpand::eliminate_macro_nodes() {
while (progress) {
progress = false;
for (int i = C->macro_count(); i > 0; i--) {
- Node * n = C->macro_node(i-1);
+ if (i > C->macro_count()) {
+ i = C->macro_count(); // more than 1 element can be eliminated at once
+ }
+ Node* n = C->macro_node(i-1);
bool success = false;
DEBUG_ONLY(int old_macro_count = C->macro_count();)
if (n->is_AbstractLock()) {
@@ -2580,7 +2583,10 @@ void PhaseMacroExpand::eliminate_macro_nodes() {
while (progress) {
progress = false;
for (int i = C->macro_count(); i > 0; i--) {
- Node * n = C->macro_node(i-1);
+ if (i > C->macro_count()) {
+ i = C->macro_count(); // more than 1 element can be eliminated at once
+ }
+ Node* n = C->macro_node(i-1);
bool success = false;
DEBUG_ONLY(int old_macro_count = C->macro_count();)
switch (n->class_id()) {
From c6f93ec9f21f6db64ad7c15c284b39ab6b0a676e Mon Sep 17 00:00:00 2001
From: Andrey Turbanov
Date: Fri, 4 Dec 2020 10:19:30 +0000
Subject: [PATCH 074/504] 8257707: Fix incorrect format string in
Http1HeaderParser
Reviewed-by: shade
---
.../classes/jdk/internal/net/http/Http1HeaderParser.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Http1HeaderParser.java b/src/java.net.http/share/classes/jdk/internal/net/http/Http1HeaderParser.java
index 6de2bbfcf9fe8..2674f0c0ff3c6 100644
--- a/src/java.net.http/share/classes/jdk/internal/net/http/Http1HeaderParser.java
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http1HeaderParser.java
@@ -96,9 +96,9 @@ public String currentStateMessage() {
headerName = headerName.substring(0, headerName.indexOf(':')+1) + "...";
msg = format("parsing HTTP/1.1 header, receiving [%s]", headerName);
} else {
- msg =format("HTTP/1.1 parser receiving [%s]", state, sb.toString());
+ msg = format("HTTP/1.1 parser receiving [%s]", sb.toString());
}
- return format("%s, parser state [%s]", msg , state);
+ return format("%s, parser state [%s]", msg, state);
}
/**
From feabddee560499bfc4ab26cd14cdde33281280d4 Mon Sep 17 00:00:00 2001
From: Erik Gahlin
Date: Fri, 4 Dec 2020 10:37:59 +0000
Subject: [PATCH 075/504] 8251843: jfr/tool/TestPrintJSON.java fails
intermittently
Reviewed-by: mgronlun
---
test/jdk/jdk/jfr/tool/EndTicksComparator.java | 44 +++++++++++++++++++
test/jdk/jdk/jfr/tool/TestPrintJSON.java | 10 ++---
test/jdk/jdk/jfr/tool/TestPrintXML.java | 2 +-
3 files changed, 50 insertions(+), 6 deletions(-)
create mode 100644 test/jdk/jdk/jfr/tool/EndTicksComparator.java
diff --git a/test/jdk/jdk/jfr/tool/EndTicksComparator.java b/test/jdk/jdk/jfr/tool/EndTicksComparator.java
new file mode 100644
index 0000000000000..fb8d97d46e502
--- /dev/null
+++ b/test/jdk/jdk/jfr/tool/EndTicksComparator.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jfr.tool;
+
+import java.util.Comparator;
+import jdk.jfr.consumer.RecordedEvent;
+
+public class EndTicksComparator implements Comparator {
+ public long readEndTicks(RecordedEvent event) {
+ long timestamp = event.getLong("startTime");
+ if (event.hasField("duration")) {
+ timestamp += event.getLong("duration");
+ }
+ return timestamp;
+ }
+
+ @Override
+ public int compare(RecordedEvent a, RecordedEvent b) {
+ return Long.compare(readEndTicks(a), readEndTicks(b));
+ }
+}
diff --git a/test/jdk/jdk/jfr/tool/TestPrintJSON.java b/test/jdk/jdk/jfr/tool/TestPrintJSON.java
index 2e63a99d3271d..65cf0cff41e30 100644
--- a/test/jdk/jdk/jfr/tool/TestPrintJSON.java
+++ b/test/jdk/jdk/jfr/tool/TestPrintJSON.java
@@ -65,13 +65,13 @@ public static void main(String... args) throws Throwable {
JSONValue recording = o.get("recording");
JSONArray jsonEvents = recording.get("events").asArray();
List events = RecordingFile.readAllEvents(recordingFile);
- Collections.sort(events, (e1, e2) -> e1.getEndTime().compareTo(e2.getEndTime()));
+ Collections.sort(events, new EndTicksComparator());
// Verify events are equal
Iterator it = events.iterator();
for (JSONValue jsonEvent : jsonEvents) {
RecordedEvent recordedEvent = it.next();
String typeName = recordedEvent.getEventType().getName();
- Asserts.assertEquals(typeName, jsonEvent.get("type").asString());
+ Asserts.assertEquals(typeName, jsonEvent.get("type").asString());
assertEquals(jsonEvent, recordedEvent);
}
Asserts.assertFalse(events.size() != jsonEvents.size(), "Incorrect number of events");
@@ -80,7 +80,7 @@ public static void main(String... args) throws Throwable {
private static void assertEquals(Object jsonObject, Object jfrObject) throws Exception {
// Check object
if (jfrObject instanceof RecordedObject) {
- JSONValue values = ((JSONValue)jsonObject).get("values");
+ JSONValue values = ((JSONValue) jsonObject).get("values");
RecordedObject recObject = (RecordedObject) jfrObject;
Asserts.assertEquals(values.size(), recObject.getFields().size());
for (ValueDescriptor v : recObject.getFields()) {
@@ -89,7 +89,7 @@ private static void assertEquals(Object jsonObject, Object jfrObject) throws Exc
Object expectedValue = recObject.getValue(name);
if (v.getAnnotation(Timestamp.class) != null) {
// Make instant of OffsetDateTime
- String text = ((JSONValue)jsonValue).asString();
+ String text = ((JSONValue) jsonValue).asString();
jsonValue = OffsetDateTime.parse(text).toInstant().toString();
expectedValue = recObject.getInstant(name);
}
@@ -103,7 +103,7 @@ private static void assertEquals(Object jsonObject, Object jfrObject) throws Exc
// Check array
if (jfrObject != null && jfrObject.getClass().isArray()) {
Object[] jfrArray = (Object[]) jfrObject;
- JSONArray jsArray = ((JSONArray)jsonObject);
+ JSONArray jsArray = ((JSONArray) jsonObject);
for (int i = 0; i < jfrArray.length; i++) {
assertEquals(jsArray.get(i), jfrArray[i]);
}
diff --git a/test/jdk/jdk/jfr/tool/TestPrintXML.java b/test/jdk/jdk/jfr/tool/TestPrintXML.java
index f84ee1372c4ba..54b32e2b1674f 100644
--- a/test/jdk/jdk/jfr/tool/TestPrintXML.java
+++ b/test/jdk/jdk/jfr/tool/TestPrintXML.java
@@ -96,7 +96,7 @@ public static void main(String... args) throws Throwable {
// Verify that all data was written correctly
List events = RecordingFile.readAllEvents(recordingFile);
- Collections.sort(events, (e1, e2) -> e1.getEndTime().compareTo(e2.getEndTime()));
+ Collections.sort(events, new EndTicksComparator());
Iterator it = events.iterator();
for (XMLEvent xmlEvent : handler.events) {
RecordedEvent re = it.next();
From 1d2d9815d0f3ba6d42ac1a12b3af77876878bf01 Mon Sep 17 00:00:00 2001
From: Martin Doerr
Date: Fri, 4 Dec 2020 11:24:15 +0000
Subject: [PATCH 076/504] 8257423: [PPC64] Support -XX:-UseInlineCaches
Reviewed-by: stuefe, rrich
---
src/hotspot/cpu/ppc/macroAssembler_ppc.cpp | 23 ++++++++++++++++++----
src/hotspot/cpu/ppc/ppc.ad | 17 +++++-----------
2 files changed, 24 insertions(+), 16 deletions(-)
diff --git a/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp b/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp
index df1bc17e8934f..72b10dff4aa95 100644
--- a/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp
+++ b/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp
@@ -3153,10 +3153,25 @@ void MacroAssembler::store_klass_gap(Register dst_oop, Register val) {
}
int MacroAssembler::instr_size_for_decode_klass_not_null() {
- if (!UseCompressedClassPointers) return 0;
- int num_instrs = 1; // shift or move
- if (CompressedKlassPointers::base() != 0) num_instrs = 7; // shift + load const + add
- return num_instrs * BytesPerInstWord;
+ static int computed_size = -1;
+
+ // Not yet computed?
+ if (computed_size == -1) {
+
+ if (!UseCompressedClassPointers) {
+ computed_size = 0;
+ } else {
+ // Determine by scratch emit.
+ ResourceMark rm;
+ int code_size = 8 * BytesPerInstWord;
+ CodeBuffer cb("decode_klass_not_null scratch buffer", code_size, 0);
+ MacroAssembler* a = new MacroAssembler(&cb);
+ a->decode_klass_not_null(R11_scratch1);
+ computed_size = a->offset();
+ }
+ }
+
+ return computed_size;
}
void MacroAssembler::decode_klass_not_null(Register dst, Register src) {
diff --git a/src/hotspot/cpu/ppc/ppc.ad b/src/hotspot/cpu/ppc/ppc.ad
index 339242195f58d..82e0890a94193 100644
--- a/src/hotspot/cpu/ppc/ppc.ad
+++ b/src/hotspot/cpu/ppc/ppc.ad
@@ -1100,8 +1100,7 @@ int MachCallStaticJavaNode::ret_addr_offset() {
int MachCallDynamicJavaNode::ret_addr_offset() {
// Offset is 4 with postalloc expanded calls (bl is one instruction). We use
// postalloc expanded calls if we use inline caches and do not update method data.
- if (UseInlineCaches)
- return 4;
+ if (UseInlineCaches) return 4;
int vtable_index = this->_vtable_index;
if (vtable_index < 0) {
@@ -1109,8 +1108,7 @@ int MachCallDynamicJavaNode::ret_addr_offset() {
assert(vtable_index == Method::invalid_vtable_index, "correct sentinel value");
return 12;
} else {
- assert(!UseInlineCaches, "expect vtable calls only if not using ICs");
- return 24;
+ return 24 + MacroAssembler::instr_size_for_decode_klass_not_null();
}
}
@@ -3635,7 +3633,7 @@ encode %{
int start_offset = __ offset();
Register Rtoc = (ra_) ? $constanttablebase : R2_TOC;
-#if 0
+
int vtable_index = this->_vtable_index;
if (_vtable_index < 0) {
// Must be invalid_vtable_index, not nonvirtual_vtable_index.
@@ -3656,7 +3654,7 @@ encode %{
__ relocate(virtual_call_Relocation::spec(virtual_call_meta_addr));
emit_call_with_trampoline_stub(_masm, (address)$meth$$method, relocInfo::none);
assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset,
- "Fix constant in ret_addr_offset()");
+ "Fix constant in ret_addr_offset(), expected %d", __ offset() - start_offset);
} else {
assert(!UseInlineCaches, "expect vtable calls only if not using ICs");
// Go thru the vtable. Get receiver klass. Receiver already
@@ -3676,14 +3674,9 @@ encode %{
// Call target. Either compiled code or C2I adapter.
__ mtctr(R11_scratch1);
__ bctrl();
- if (((MachCallDynamicJavaNode*)this)->ret_addr_offset() != __ offset() - start_offset) {
- tty->print(" %d, %d\n", ((MachCallDynamicJavaNode*)this)->ret_addr_offset(),__ offset() - start_offset);
- }
assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset,
- "Fix constant in ret_addr_offset()");
+ "Fix constant in ret_addr_offset(), expected %d", __ offset() - start_offset);
}
-#endif
- Unimplemented(); // ret_addr_offset not yet fixed. Depends on compressed oops (load klass!).
%}
// a runtime call
From dede01eb2010c65419d352e1d45dd7a345247ff3 Mon Sep 17 00:00:00 2001
From: Maurizio Cimadamore
Date: Fri, 4 Dec 2020 11:46:06 +0000
Subject: [PATCH 077/504] 8257622: MemoryAccess methods are missing
@ForceInline annotations
Reviewed-by: jvernee, shade
---
.../jdk/incubator/foreign/MemoryAccess.java | 82 +++++++++++
.../foreign/LoopOverNonConstantFP.java | 131 ++++++++++++++++++
.../jdk/incubator/foreign/UnrolledAccess.java | 112 +++++++++++++++
3 files changed, 325 insertions(+)
create mode 100644 test/micro/org/openjdk/bench/jdk/incubator/foreign/LoopOverNonConstantFP.java
create mode 100644 test/micro/org/openjdk/bench/jdk/incubator/foreign/UnrolledAccess.java
diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryAccess.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryAccess.java
index 12543f1d7271a..9de681274fccb 100644
--- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryAccess.java
+++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryAccess.java
@@ -95,6 +95,7 @@ private static VarHandle unalignedHandle(ValueLayout elementLayout, Class> car
* @param offset offset in bytes (relative to {@code segment}). The final address of this read operation can be expressed as {@code segment.address().addOffset(offset)}.
* @return a byte value read from {@code segment}.
*/
+ @ForceInline
public static byte getByteAtOffset(MemorySegment segment, long offset) {
Objects.requireNonNull(segment);
return (byte)byte_handle.get(segment, offset);
@@ -107,6 +108,7 @@ public static byte getByteAtOffset(MemorySegment segment, long offset) {
* @param offset offset in bytes (relative to {@code segment}). The final address of this read operation can be expressed as {@code segment.address().addOffset(offset)}.
* @param value the byte value to be written.
*/
+ @ForceInline
public static void setByteAtOffset(MemorySegment segment, long offset, byte value) {
Objects.requireNonNull(segment);
byte_handle.set(segment, offset, value);
@@ -123,6 +125,7 @@ public static void setByteAtOffset(MemorySegment segment, long offset, byte valu
* @param offset offset in bytes (relative to {@code segment}). The final address of this read operation can be expressed as {@code segment.address().addOffset(offset)}.
* @return a char value read from {@code segment}.
*/
+ @ForceInline
public static char getCharAtOffset(MemorySegment segment, long offset) {
return getCharAtOffset(segment, offset, ByteOrder.nativeOrder());
}
@@ -138,6 +141,7 @@ public static char getCharAtOffset(MemorySegment segment, long offset) {
* @param offset offset in bytes (relative to {@code segment}). The final address of this read operation can be expressed as {@code segment.address().addOffset(offset)}.
* @param value the char value to be written.
*/
+ @ForceInline
public static void setCharAtOffset(MemorySegment segment, long offset, char value) {
setCharAtOffset(segment, offset, ByteOrder.nativeOrder(), value);
}
@@ -153,6 +157,7 @@ public static void setCharAtOffset(MemorySegment segment, long offset, char valu
* @param offset offset in bytes (relative to {@code segment}). The final address of this read operation can be expressed as {@code segment.address().addOffset(offset)}.
* @return a short value read from {@code segment}.
*/
+ @ForceInline
public static short getShortAtOffset(MemorySegment segment, long offset) {
return getShortAtOffset(segment, offset, ByteOrder.nativeOrder());
}
@@ -168,6 +173,7 @@ public static short getShortAtOffset(MemorySegment segment, long offset) {
* @param offset offset in bytes (relative to {@code segment}). The final address of this read operation can be expressed as {@code segment.address().addOffset(offset)}.
* @param value the short value to be written.
*/
+ @ForceInline
public static void setShortAtOffset(MemorySegment segment, long offset, short value) {
setShortAtOffset(segment, offset, ByteOrder.nativeOrder(), value);
}
@@ -183,6 +189,7 @@ public static void setShortAtOffset(MemorySegment segment, long offset, short va
* @param offset offset in bytes (relative to {@code segment}). The final address of this read operation can be expressed as {@code segment.address().addOffset(offset)}.
* @return an int value read from {@code segment}.
*/
+ @ForceInline
public static int getIntAtOffset(MemorySegment segment, long offset) {
return getIntAtOffset(segment, offset, ByteOrder.nativeOrder());
}
@@ -198,6 +205,7 @@ public static int getIntAtOffset(MemorySegment segment, long offset) {
* @param offset offset in bytes (relative to {@code segment}). The final address of this read operation can be expressed as {@code segment.address().addOffset(offset)}.
* @param value the int value to be written.
*/
+ @ForceInline
public static void setIntAtOffset(MemorySegment segment, long offset, int value) {
setIntAtOffset(segment, offset, ByteOrder.nativeOrder(), value);
}
@@ -213,6 +221,7 @@ public static void setIntAtOffset(MemorySegment segment, long offset, int value)
* @param offset offset in bytes (relative to {@code segment}). The final address of this read operation can be expressed as {@code segment.address().addOffset(offset)}.
* @return a float value read from {@code segment}.
*/
+ @ForceInline
public static float getFloatAtOffset(MemorySegment segment, long offset) {
return getFloatAtOffset(segment, offset, ByteOrder.nativeOrder());
}
@@ -228,6 +237,7 @@ public static float getFloatAtOffset(MemorySegment segment, long offset) {
* @param offset offset in bytes (relative to {@code segment}). The final address of this read operation can be expressed as {@code segment.address().addOffset(offset)}.
* @param value the float value to be written.
*/
+ @ForceInline
public static void setFloatAtOffset(MemorySegment segment, long offset, float value) {
setFloatAtOffset(segment, offset, ByteOrder.nativeOrder(), value);
}
@@ -243,6 +253,7 @@ public static void setFloatAtOffset(MemorySegment segment, long offset, float va
* @param offset offset in bytes (relative to {@code segment}). The final address of this read operation can be expressed as {@code segment.address().addOffset(offset)}.
* @return a long value read from {@code segment}.
*/
+ @ForceInline
public static long getLongAtOffset(MemorySegment segment, long offset) {
return getLongAtOffset(segment, offset, ByteOrder.nativeOrder());
}
@@ -258,6 +269,7 @@ public static long getLongAtOffset(MemorySegment segment, long offset) {
* @param offset offset in bytes (relative to {@code segment}). The final address of this read operation can be expressed as {@code segment.address().addOffset(offset)}.
* @param value the long value to be written.
*/
+ @ForceInline
public static void setLongAtOffset(MemorySegment segment, long offset, long value) {
setLongAtOffset(segment, offset, ByteOrder.nativeOrder(), value);
}
@@ -273,6 +285,7 @@ public static void setLongAtOffset(MemorySegment segment, long offset, long valu
* @param offset offset in bytes (relative to {@code segment}). The final address of this read operation can be expressed as {@code segment.address().addOffset(offset)}.
* @return a double value read from {@code segment}.
*/
+ @ForceInline
public static double getDoubleAtOffset(MemorySegment segment, long offset) {
return getDoubleAtOffset(segment, offset, ByteOrder.nativeOrder());
}
@@ -288,6 +301,7 @@ public static double getDoubleAtOffset(MemorySegment segment, long offset) {
* @param offset offset in bytes (relative to {@code segment}). The final address of this read operation can be expressed as {@code segment.address().addOffset(offset)}.
* @param value the double value to be written.
*/
+ @ForceInline
public static void setDoubleAtOffset(MemorySegment segment, long offset, double value) {
setDoubleAtOffset(segment, offset, ByteOrder.nativeOrder(), value);
}
@@ -304,6 +318,7 @@ public static void setDoubleAtOffset(MemorySegment segment, long offset, double
* @param offset offset in bytes (relative to {@code segment}). The final address of this read operation can be expressed as {@code segment.address().addOffset(offset)}.
* @return a memory address read from {@code segment}.
*/
+ @ForceInline
public static MemoryAddress getAddressAtOffset(MemorySegment segment, long offset) {
Objects.requireNonNull(segment);
return (MemoryAddress)address_handle.get(segment, offset);
@@ -321,6 +336,7 @@ public static MemoryAddress getAddressAtOffset(MemorySegment segment, long offse
* @param offset offset in bytes (relative to {@code segment}). The final address of this read operation can be expressed as {@code segment.address().addOffset(offset)}.
* @param value the memory address to be written (expressed as an {@link Addressable} instance).
*/
+ @ForceInline
public static void setAddressAtOffset(MemorySegment segment, long offset, Addressable value) {
Objects.requireNonNull(segment);
Objects.requireNonNull(value);
@@ -340,6 +356,7 @@ public static void setAddressAtOffset(MemorySegment segment, long offset, Addres
* @param order the specified byte order.
* @return a char value read from {@code segment}.
*/
+ @ForceInline
public static char getCharAtOffset(MemorySegment segment, long offset, ByteOrder order) {
Objects.requireNonNull(segment);
Objects.requireNonNull(order);
@@ -359,6 +376,7 @@ public static char getCharAtOffset(MemorySegment segment, long offset, ByteOrder
* @param order the specified byte order.
* @param value the char value to be written.
*/
+ @ForceInline
public static void setCharAtOffset(MemorySegment segment, long offset, ByteOrder order, char value) {
Objects.requireNonNull(segment);
Objects.requireNonNull(order);
@@ -378,6 +396,7 @@ public static void setCharAtOffset(MemorySegment segment, long offset, ByteOrder
* @param order the specified byte order.
* @return a short value read from {@code segment}.
*/
+ @ForceInline
public static short getShortAtOffset(MemorySegment segment, long offset, ByteOrder order) {
Objects.requireNonNull(segment);
Objects.requireNonNull(order);
@@ -397,6 +416,7 @@ public static short getShortAtOffset(MemorySegment segment, long offset, ByteOrd
* @param order the specified byte order.
* @param value the short value to be written.
*/
+ @ForceInline
public static void setShortAtOffset(MemorySegment segment, long offset, ByteOrder order, short value) {
Objects.requireNonNull(segment);
Objects.requireNonNull(order);
@@ -416,6 +436,7 @@ public static void setShortAtOffset(MemorySegment segment, long offset, ByteOrde
* @param order the specified byte order.
* @return an int value read from {@code segment}.
*/
+ @ForceInline
public static int getIntAtOffset(MemorySegment segment, long offset, ByteOrder order) {
Objects.requireNonNull(segment);
Objects.requireNonNull(order);
@@ -435,6 +456,7 @@ public static int getIntAtOffset(MemorySegment segment, long offset, ByteOrder o
* @param order the specified byte order.
* @param value the int value to be written.
*/
+ @ForceInline
public static void setIntAtOffset(MemorySegment segment, long offset, ByteOrder order, int value) {
Objects.requireNonNull(segment);
Objects.requireNonNull(order);
@@ -454,6 +476,7 @@ public static void setIntAtOffset(MemorySegment segment, long offset, ByteOrder
* @param order the specified byte order.
* @return a float value read from {@code segment}.
*/
+ @ForceInline
public static float getFloatAtOffset(MemorySegment segment, long offset, ByteOrder order) {
Objects.requireNonNull(segment);
Objects.requireNonNull(order);
@@ -473,6 +496,7 @@ public static float getFloatAtOffset(MemorySegment segment, long offset, ByteOrd
* @param order the specified byte order.
* @param value the float value to be written.
*/
+ @ForceInline
public static void setFloatAtOffset(MemorySegment segment, long offset, ByteOrder order, float value) {
Objects.requireNonNull(segment);
Objects.requireNonNull(order);
@@ -492,6 +516,7 @@ public static void setFloatAtOffset(MemorySegment segment, long offset, ByteOrde
* @param order the specified byte order.
* @return a long value read from {@code segment}.
*/
+ @ForceInline
public static long getLongAtOffset(MemorySegment segment, long offset, ByteOrder order) {
Objects.requireNonNull(segment);
Objects.requireNonNull(order);
@@ -511,6 +536,7 @@ public static long getLongAtOffset(MemorySegment segment, long offset, ByteOrder
* @param order the specified byte order.
* @param value the long value to be written.
*/
+ @ForceInline
public static void setLongAtOffset(MemorySegment segment, long offset, ByteOrder order, long value) {
Objects.requireNonNull(segment);
Objects.requireNonNull(order);
@@ -530,6 +556,7 @@ public static void setLongAtOffset(MemorySegment segment, long offset, ByteOrder
* @param order the specified byte order.
* @return a double value read from {@code segment}.
*/
+ @ForceInline
public static double getDoubleAtOffset(MemorySegment segment, long offset, ByteOrder order) {
Objects.requireNonNull(segment);
Objects.requireNonNull(order);
@@ -549,6 +576,7 @@ public static double getDoubleAtOffset(MemorySegment segment, long offset, ByteO
* @param order the specified byte order.
* @param value the double value to be written.
*/
+ @ForceInline
public static void setDoubleAtOffset(MemorySegment segment, long offset, ByteOrder order, double value) {
Objects.requireNonNull(segment);
Objects.requireNonNull(order);
@@ -566,6 +594,7 @@ public static void setDoubleAtOffset(MemorySegment segment, long offset, ByteOrd
* @param segment the segment to be dereferenced.
* @return a byte value read from {@code segment}.
*/
+ @ForceInline
public static byte getByte(MemorySegment segment) {
return getByteAtOffset(segment, 0L);
}
@@ -580,6 +609,7 @@ public static byte getByte(MemorySegment segment) {
* @param segment the segment to be dereferenced.
* @param value the byte value to be written.
*/
+ @ForceInline
public static void setByte(MemorySegment segment, byte value) {
setByteAtOffset(segment, 0L, value);
}
@@ -594,6 +624,7 @@ public static void setByte(MemorySegment segment, byte value) {
* @param segment the segment to be dereferenced.
* @return a char value read from {@code segment}.
*/
+ @ForceInline
public static char getChar(MemorySegment segment) {
return getCharAtOffset(segment, 0L);
}
@@ -608,6 +639,7 @@ public static char getChar(MemorySegment segment) {
* @param segment the segment to be dereferenced.
* @param value the char value to be written.
*/
+ @ForceInline
public static void setChar(MemorySegment segment, char value) {
setCharAtOffset(segment, 0L, value);
}
@@ -622,6 +654,7 @@ public static void setChar(MemorySegment segment, char value) {
* @param segment the segment to be dereferenced.
* @return a short value read from {@code segment}.
*/
+ @ForceInline
public static short getShort(MemorySegment segment) {
return getShortAtOffset(segment, 0L);
}
@@ -636,6 +669,7 @@ public static short getShort(MemorySegment segment) {
* @param segment the segment to be dereferenced.
* @param value the short value to be written.
*/
+ @ForceInline
public static void setShort(MemorySegment segment, short value) {
setShortAtOffset(segment, 0L, value);
}
@@ -650,6 +684,7 @@ public static void setShort(MemorySegment segment, short value) {
* @param segment the segment to be dereferenced.
* @return an int value read from {@code segment}.
*/
+ @ForceInline
public static int getInt(MemorySegment segment) {
return getIntAtOffset(segment, 0L);
}
@@ -664,6 +699,7 @@ public static int getInt(MemorySegment segment) {
* @param segment the segment to be dereferenced.
* @param value the int value to be written.
*/
+ @ForceInline
public static void setInt(MemorySegment segment, int value) {
setIntAtOffset(segment, 0L, value);
}
@@ -678,6 +714,7 @@ public static void setInt(MemorySegment segment, int value) {
* @param segment the segment to be dereferenced.
* @return a float value read from {@code segment}.
*/
+ @ForceInline
public static float getFloat(MemorySegment segment) {
return getFloatAtOffset(segment, 0L);
}
@@ -692,6 +729,7 @@ public static float getFloat(MemorySegment segment) {
* @param segment the segment to be dereferenced.
* @param value the float value to be written.
*/
+ @ForceInline
public static void setFloat(MemorySegment segment, float value) {
setFloatAtOffset(segment, 0L, value);
}
@@ -706,6 +744,7 @@ public static void setFloat(MemorySegment segment, float value) {
* @param segment the segment to be dereferenced.
* @return a long value read from {@code segment}.
*/
+ @ForceInline
public static long getLong(MemorySegment segment) {
return getLongAtOffset(segment, 0L);
}
@@ -720,6 +759,7 @@ public static long getLong(MemorySegment segment) {
* @param segment the segment to be dereferenced.
* @param value the long value to be written.
*/
+ @ForceInline
public static void setLong(MemorySegment segment, long value) {
setLongAtOffset(segment, 0L, value);
}
@@ -734,6 +774,7 @@ public static void setLong(MemorySegment segment, long value) {
* @param segment the segment to be dereferenced.
* @return a double value read from {@code segment}.
*/
+ @ForceInline
public static double getDouble(MemorySegment segment) {
return getDoubleAtOffset(segment, 0L);
}
@@ -748,6 +789,7 @@ public static double getDouble(MemorySegment segment) {
* @param segment the segment to be dereferenced.
* @param value the double value to be written.
*/
+ @ForceInline
public static void setDouble(MemorySegment segment, double value) {
setDoubleAtOffset(segment, 0L, value);
}
@@ -762,6 +804,7 @@ public static void setDouble(MemorySegment segment, double value) {
* @param segment the segment to be dereferenced.
* @return a memory address read from {@code segment}.
*/
+ @ForceInline
public static MemoryAddress getAddress(MemorySegment segment) {
return getAddressAtOffset(segment, 0L);
}
@@ -776,6 +819,7 @@ public static MemoryAddress getAddress(MemorySegment segment) {
* @param segment the segment to be dereferenced.
* @param value the memory address to be written (expressed as an {@link Addressable} instance).
*/
+ @ForceInline
public static void setAddress(MemorySegment segment, Addressable value) {
setAddressAtOffset(segment, 0L, value);
}
@@ -791,6 +835,7 @@ public static void setAddress(MemorySegment segment, Addressable value) {
* @param order the specified byte order.
* @return a char value read from {@code segment}.
*/
+ @ForceInline
public static char getChar(MemorySegment segment, ByteOrder order) {
return getCharAtOffset(segment, 0L, order);
}
@@ -806,6 +851,7 @@ public static char getChar(MemorySegment segment, ByteOrder order) {
* @param order the specified byte order.
* @param value the char value to be written.
*/
+ @ForceInline
public static void setChar(MemorySegment segment, ByteOrder order, char value) {
setCharAtOffset(segment, 0L, order, value);
}
@@ -821,6 +867,7 @@ public static void setChar(MemorySegment segment, ByteOrder order, char value) {
* @param order the specified byte order.
* @return a short value read from {@code segment}.
*/
+ @ForceInline
public static short getShort(MemorySegment segment, ByteOrder order) {
return getShortAtOffset(segment, 0L, order);
}
@@ -836,6 +883,7 @@ public static short getShort(MemorySegment segment, ByteOrder order) {
* @param order the specified byte order.
* @param value the short value to be written.
*/
+ @ForceInline
public static void setShort(MemorySegment segment, ByteOrder order, short value) {
setShortAtOffset(segment, 0L, order, value);
}
@@ -851,6 +899,7 @@ public static void setShort(MemorySegment segment, ByteOrder order, short value)
* @param order the specified byte order.
* @return an int value read from {@code segment}.
*/
+ @ForceInline
public static int getInt(MemorySegment segment, ByteOrder order) {
return getIntAtOffset(segment, 0L, order);
}
@@ -866,6 +915,7 @@ public static int getInt(MemorySegment segment, ByteOrder order) {
* @param order the specified byte order.
* @param value the int value to be written.
*/
+ @ForceInline
public static void setInt(MemorySegment segment, ByteOrder order, int value) {
setIntAtOffset(segment, 0L, order, value);
}
@@ -881,6 +931,7 @@ public static void setInt(MemorySegment segment, ByteOrder order, int value) {
* @param order the specified byte order.
* @return a float value read from {@code segment}.
*/
+ @ForceInline
public static float getFloat(MemorySegment segment, ByteOrder order) {
return getFloatAtOffset(segment, 0L, order);
}
@@ -896,6 +947,7 @@ public static float getFloat(MemorySegment segment, ByteOrder order) {
* @param order the specified byte order.
* @param value the float value to be written.
*/
+ @ForceInline
public static void setFloat(MemorySegment segment, ByteOrder order, float value) {
setFloatAtOffset(segment, 0L, order, value);
}
@@ -911,6 +963,7 @@ public static void setFloat(MemorySegment segment, ByteOrder order, float value)
* @param order the specified byte order.
* @return a long value read from {@code segment}.
*/
+ @ForceInline
public static long getLong(MemorySegment segment, ByteOrder order) {
return getLongAtOffset(segment, 0L, order);
}
@@ -926,6 +979,7 @@ public static long getLong(MemorySegment segment, ByteOrder order) {
* @param order the specified byte order.
* @param value the long value to be written.
*/
+ @ForceInline
public static void setLong(MemorySegment segment, ByteOrder order, long value) {
setLongAtOffset(segment, 0L, order, value);
}
@@ -941,6 +995,7 @@ public static void setLong(MemorySegment segment, ByteOrder order, long value) {
* @param order the specified byte order.
* @return a double value read from {@code segment}.
*/
+ @ForceInline
public static double getDouble(MemorySegment segment, ByteOrder order) {
return getDoubleAtOffset(segment, 0L, order);
}
@@ -956,6 +1011,7 @@ public static double getDouble(MemorySegment segment, ByteOrder order) {
* @param order the specified byte order.
* @param value the double value to be written.
*/
+ @ForceInline
public static void setDouble(MemorySegment segment, ByteOrder order, double value) {
setDoubleAtOffset(segment, 0L, order, value);
}
@@ -971,6 +1027,7 @@ public static void setDouble(MemorySegment segment, ByteOrder order, double valu
* @param index element index (relative to {@code segment}). The final address of this read operation can be expressed as {@code segment.address().addOffset(index * 2)}.
* @return a char value read from {@code segment} at the element index specified by {@code index}.
*/
+ @ForceInline
public static char getCharAtIndex(MemorySegment segment, long index) {
return getCharAtOffset(segment, scale(segment, index, 2));
}
@@ -986,6 +1043,7 @@ public static char getCharAtIndex(MemorySegment segment, long index) {
* @param index element index (relative to {@code segment}). The final address of this read operation can be expressed as {@code segment.address().addOffset(index * 2)}.
* @param value the char value to be written.
*/
+ @ForceInline
public static void setCharAtIndex(MemorySegment segment, long index, char value) {
setCharAtOffset(segment, scale(segment, index, 2), value);
}
@@ -1001,6 +1059,7 @@ public static void setCharAtIndex(MemorySegment segment, long index, char value)
* @param index element index (relative to {@code segment}). The final address of this read operation can be expressed as {@code segment.address().addOffset(index * 2)}.
* @return a short value read from {@code segment} at the element index specified by {@code index}.
*/
+ @ForceInline
public static short getShortAtIndex(MemorySegment segment, long index) {
return getShortAtOffset(segment, scale(segment, index, 2));
}
@@ -1016,6 +1075,7 @@ public static short getShortAtIndex(MemorySegment segment, long index) {
* @param index element index (relative to {@code segment}). The final address of this read operation can be expressed as {@code segment.address().addOffset(index * 2)}.
* @param value the short value to be written.
*/
+ @ForceInline
public static void setShortAtIndex(MemorySegment segment, long index, short value) {
setShortAtOffset(segment, scale(segment, index, 2), value);
}
@@ -1031,6 +1091,7 @@ public static void setShortAtIndex(MemorySegment segment, long index, short valu
* @param index element index (relative to {@code segment}). The final address of this read operation can be expressed as {@code segment.address().addOffset(index * 4)}.
* @return an int value read from {@code segment} at the element index specified by {@code index}.
*/
+ @ForceInline
public static int getIntAtIndex(MemorySegment segment, long index) {
return getIntAtOffset(segment, scale(segment, index, 4));
}
@@ -1046,6 +1107,7 @@ public static int getIntAtIndex(MemorySegment segment, long index) {
* @param index element index (relative to {@code segment}). The final address of this read operation can be expressed as {@code segment.address().addOffset(index * 4)}.
* @param value the int value to be written.
*/
+ @ForceInline
public static void setIntAtIndex(MemorySegment segment, long index, int value) {
setIntAtOffset(segment, scale(segment, index, 4), value);
}
@@ -1061,6 +1123,7 @@ public static void setIntAtIndex(MemorySegment segment, long index, int value) {
* @param index element index (relative to {@code segment}). The final address of this read operation can be expressed as {@code segment.address().addOffset(index * 4)}.
* @return a float value read from {@code segment} at the element index specified by {@code index}.
*/
+ @ForceInline
public static float getFloatAtIndex(MemorySegment segment, long index) {
return getFloatAtOffset(segment, scale(segment, index, 4));
}
@@ -1076,6 +1139,7 @@ public static float getFloatAtIndex(MemorySegment segment, long index) {
* @param index element index (relative to {@code segment}). The final address of this read operation can be expressed as {@code segment.address().addOffset(index * 4)}.
* @param value the float value to be written.
*/
+ @ForceInline
public static void setFloatAtIndex(MemorySegment segment, long index, float value) {
setFloatAtOffset(segment, scale(segment, index, 4), value);
}
@@ -1091,6 +1155,7 @@ public static void setFloatAtIndex(MemorySegment segment, long index, float valu
* @param index element index (relative to {@code segment}). The final address of this read operation can be expressed as {@code segment.address().addOffset(index * 8)}.
* @return a long value read from {@code segment} at the element index specified by {@code index}.
*/
+ @ForceInline
public static long getLongAtIndex(MemorySegment segment, long index) {
return getLongAtOffset(segment, scale(segment, index, 8));
}
@@ -1106,6 +1171,7 @@ public static long getLongAtIndex(MemorySegment segment, long index) {
* @param index element index (relative to {@code segment}). The final address of this read operation can be expressed as {@code segment.address().addOffset(index * 8)}.
* @param value the long value to be written.
*/
+ @ForceInline
public static void setLongAtIndex(MemorySegment segment, long index, long value) {
setLongAtOffset(segment, scale(segment, index, 8), value);
}
@@ -1121,6 +1187,7 @@ public static void setLongAtIndex(MemorySegment segment, long index, long value)
* @param index element index (relative to {@code segment}). The final address of this read operation can be expressed as {@code segment.address().addOffset(index * 8)}.
* @return a double value read from {@code segment} at the element index specified by {@code index}.
*/
+ @ForceInline
public static double getDoubleAtIndex(MemorySegment segment, long index) {
return getDoubleAtOffset(segment, scale(segment, index, 8));
}
@@ -1136,6 +1203,7 @@ public static double getDoubleAtIndex(MemorySegment segment, long index) {
* @param index element index (relative to {@code segment}). The final address of this read operation can be expressed as {@code segment.address().addOffset(index * 8)}.
* @param value the double value to be written.
*/
+ @ForceInline
public static void setDoubleAtIndex(MemorySegment segment, long index, double value) {
setDoubleAtOffset(segment, scale(segment, index, 8), value);
}
@@ -1151,6 +1219,7 @@ public static void setDoubleAtIndex(MemorySegment segment, long index, double va
* @param index element index (relative to {@code segment}). The final address of this read operation can be expressed as {@code segment.address().addOffset(index * 8)}.
* @return a memory address read from {@code segment} at the element index specified by {@code index}.
*/
+ @ForceInline
public static MemoryAddress getAddressAtIndex(MemorySegment segment, long index) {
return getAddressAtOffset(segment, scale(segment, index, (int)MemoryLayouts.ADDRESS.byteSize()));
}
@@ -1166,6 +1235,7 @@ public static MemoryAddress getAddressAtIndex(MemorySegment segment, long index)
* @param index element index (relative to {@code segment}). The final address of this read operation can be expressed as {@code segment.address().addOffset(index * 8)}.
* @param value the memory address to be written (expressed as an {@link Addressable} instance).
*/
+ @ForceInline
public static void setAddressAtIndex(MemorySegment segment, long index, Addressable value) {
setAddressAtOffset(segment, scale(segment, index, (int)MemoryLayouts.ADDRESS.byteSize()), value);
}
@@ -1182,6 +1252,7 @@ public static void setAddressAtIndex(MemorySegment segment, long index, Addressa
* @param order the specified byte order.
* @return a char value read from {@code segment} at the element index specified by {@code index}.
*/
+ @ForceInline
public static char getCharAtIndex(MemorySegment segment, long index, ByteOrder order) {
return getCharAtOffset(segment, scale(segment, index, 2), order);
}
@@ -1198,6 +1269,7 @@ public static char getCharAtIndex(MemorySegment segment, long index, ByteOrder o
* @param order the specified byte order.
* @param value the char value to be written.
*/
+ @ForceInline
public static void setCharAtIndex(MemorySegment segment, long index, ByteOrder order, char value) {
setCharAtOffset(segment, scale(segment, index, 2), order, value);
}
@@ -1214,6 +1286,7 @@ public static void setCharAtIndex(MemorySegment segment, long index, ByteOrder o
* @param order the specified byte order.
* @return a short value read from {@code segment} at the element index specified by {@code index}.
*/
+ @ForceInline
public static short getShortAtIndex(MemorySegment segment, long index, ByteOrder order) {
return getShortAtOffset(segment, scale(segment, index, 2), order);
}
@@ -1230,6 +1303,7 @@ public static short getShortAtIndex(MemorySegment segment, long index, ByteOrder
* @param order the specified byte order.
* @param value the short value to be written.
*/
+ @ForceInline
public static void setShortAtIndex(MemorySegment segment, long index, ByteOrder order, short value) {
setShortAtOffset(segment, scale(segment, index, 2), order, value);
}
@@ -1246,6 +1320,7 @@ public static void setShortAtIndex(MemorySegment segment, long index, ByteOrder
* @param order the specified byte order.
* @return an int value read from {@code segment} at the element index specified by {@code index}.
*/
+ @ForceInline
public static int getIntAtIndex(MemorySegment segment, long index, ByteOrder order) {
return getIntAtOffset(segment, scale(segment, index, 4), order);
}
@@ -1262,6 +1337,7 @@ public static int getIntAtIndex(MemorySegment segment, long index, ByteOrder ord
* @param order the specified byte order.
* @param value the int value to be written.
*/
+ @ForceInline
public static void setIntAtIndex(MemorySegment segment, long index, ByteOrder order, int value) {
setIntAtOffset(segment, scale(segment, index, 4), order, value);
}
@@ -1278,6 +1354,7 @@ public static void setIntAtIndex(MemorySegment segment, long index, ByteOrder or
* @param order the specified byte order.
* @return a float value read from {@code segment} at the element index specified by {@code index}.
*/
+ @ForceInline
public static float getFloatAtIndex(MemorySegment segment, long index, ByteOrder order) {
return getFloatAtOffset(segment, scale(segment, index, 4), order);
}
@@ -1294,6 +1371,7 @@ public static float getFloatAtIndex(MemorySegment segment, long index, ByteOrder
* @param order the specified byte order.
* @param value the float value to be written.
*/
+ @ForceInline
public static void setFloatAtIndex(MemorySegment segment, long index, ByteOrder order, float value) {
setFloatAtOffset(segment, scale(segment, index, 4), order, value);
}
@@ -1310,6 +1388,7 @@ public static void setFloatAtIndex(MemorySegment segment, long index, ByteOrder
* @param order the specified byte order.
* @return a long value read from {@code segment} at the element index specified by {@code index}.
*/
+ @ForceInline
public static long getLongAtIndex(MemorySegment segment, long index, ByteOrder order) {
return getLongAtOffset(segment, scale(segment, index, 8), order);
}
@@ -1326,6 +1405,7 @@ public static long getLongAtIndex(MemorySegment segment, long index, ByteOrder o
* @param order the specified byte order.
* @param value the long value to be written.
*/
+ @ForceInline
public static void setLongAtIndex(MemorySegment segment, long index, ByteOrder order, long value) {
setLongAtOffset(segment, scale(segment, index, 8), order, value);
}
@@ -1342,6 +1422,7 @@ public static void setLongAtIndex(MemorySegment segment, long index, ByteOrder o
* @param order the specified byte order.
* @return a double value read from {@code segment} at the element index specified by {@code index}.
*/
+ @ForceInline
public static double getDoubleAtIndex(MemorySegment segment, long index, ByteOrder order) {
return getDoubleAtOffset(segment, scale(segment, index, 8), order);
}
@@ -1358,6 +1439,7 @@ public static double getDoubleAtIndex(MemorySegment segment, long index, ByteOrd
* @param order the specified byte order.
* @param value the double value to be written.
*/
+ @ForceInline
public static void setDoubleAtIndex(MemorySegment segment, long index, ByteOrder order, double value) {
setDoubleAtOffset(segment, scale(segment, index, 8), order, value);
}
diff --git a/test/micro/org/openjdk/bench/jdk/incubator/foreign/LoopOverNonConstantFP.java b/test/micro/org/openjdk/bench/jdk/incubator/foreign/LoopOverNonConstantFP.java
new file mode 100644
index 0000000000000..d4325c7c5fe41
--- /dev/null
+++ b/test/micro/org/openjdk/bench/jdk/incubator/foreign/LoopOverNonConstantFP.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 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.
+ */
+package org.openjdk.bench.jdk.incubator.foreign;
+
+import jdk.incubator.foreign.MemoryAccess;
+import jdk.incubator.foreign.MemoryAddress;
+import jdk.incubator.foreign.MemoryLayout;
+import jdk.incubator.foreign.MemorySegment;
+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.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+import org.openjdk.jmh.annotations.Warmup;
+import sun.misc.Unsafe;
+
+import java.lang.invoke.VarHandle;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.concurrent.TimeUnit;
+
+import static jdk.incubator.foreign.MemoryLayout.PathElement.sequenceElement;
+import static jdk.incubator.foreign.MemoryLayouts.JAVA_DOUBLE;
+
+@BenchmarkMode(Mode.AverageTime)
+@Warmup(iterations = 5, time = 500, timeUnit = TimeUnit.MILLISECONDS)
+@Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS)
+@State(org.openjdk.jmh.annotations.Scope.Thread)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@Fork(3)
+public class LoopOverNonConstantFP {
+
+ static final Unsafe unsafe = Utils.unsafe;
+
+ static final int ELEM_SIZE = 1_000_000;
+ static final int CARRIER_SIZE = (int)JAVA_DOUBLE.byteSize();
+ static final int ALLOC_SIZE = ELEM_SIZE * CARRIER_SIZE;
+
+ MemorySegment segmentIn, segmentOut;
+ long unsafe_addrIn, unsafe_addrOut;
+ ByteBuffer byteBufferIn, byteBufferOut;
+
+ @Setup
+ public void setup() {
+ unsafe_addrIn = unsafe.allocateMemory(ALLOC_SIZE);
+ unsafe_addrOut = unsafe.allocateMemory(ALLOC_SIZE);
+ for (int i = 0; i < ELEM_SIZE; i++) {
+ unsafe.putDouble(unsafe_addrIn + (i * CARRIER_SIZE), i);
+ }
+ for (int i = 0; i < ELEM_SIZE; i++) {
+ unsafe.putDouble(unsafe_addrOut + (i * CARRIER_SIZE), i);
+ }
+ segmentIn = MemorySegment.allocateNative(ALLOC_SIZE);
+ segmentOut = MemorySegment.allocateNative(ALLOC_SIZE);
+ for (int i = 0; i < ELEM_SIZE; i++) {
+ MemoryAccess.setDoubleAtIndex(segmentIn, i, i);
+ }
+ for (int i = 0; i < ELEM_SIZE; i++) {
+ MemoryAccess.setDoubleAtIndex(segmentOut, i, i);
+ }
+ byteBufferIn = ByteBuffer.allocateDirect(ALLOC_SIZE).order(ByteOrder.nativeOrder());
+ byteBufferOut = ByteBuffer.allocateDirect(ALLOC_SIZE).order(ByteOrder.nativeOrder());
+ for (int i = 0; i < ELEM_SIZE; i++) {
+ byteBufferIn.putDouble(i * CARRIER_SIZE , i);
+ }
+ for (int i = 0; i < ELEM_SIZE; i++) {
+ byteBufferOut.putDouble(i * CARRIER_SIZE , i);
+ }
+ }
+
+ @TearDown
+ public void tearDown() {
+ segmentIn.close();
+ segmentOut.close();
+ unsafe.invokeCleaner(byteBufferIn);
+ unsafe.invokeCleaner(byteBufferOut);
+ unsafe.freeMemory(unsafe_addrIn);
+ unsafe.freeMemory(unsafe_addrOut);
+ }
+
+ @Benchmark
+ public void unsafe_loop() {
+ for (int i = 0; i < ELEM_SIZE; i ++) {
+ unsafe.putDouble(unsafe_addrOut + (i * CARRIER_SIZE),
+ unsafe.getDouble(unsafe_addrIn + (i * CARRIER_SIZE)) +
+ unsafe.getDouble(unsafe_addrOut + (i * CARRIER_SIZE)));
+ }
+ }
+
+ @Benchmark
+ public void segment_loop() {
+ for (int i = 0; i < ELEM_SIZE; i ++) {
+ MemoryAccess.setDoubleAtIndex(segmentOut, i,
+ MemoryAccess.getDoubleAtIndex(segmentIn, i) +
+ MemoryAccess.getDoubleAtIndex(segmentOut, i));
+ }
+ }
+
+ @Benchmark
+ public void BB_loop() {
+ for (int i = 0; i < ELEM_SIZE; i++) {
+ byteBufferOut.putDouble(i * CARRIER_SIZE,
+ byteBufferIn.getDouble(i * CARRIER_SIZE) +
+ byteBufferOut.getDouble(i * CARRIER_SIZE));
+ }
+ }
+}
diff --git a/test/micro/org/openjdk/bench/jdk/incubator/foreign/UnrolledAccess.java b/test/micro/org/openjdk/bench/jdk/incubator/foreign/UnrolledAccess.java
new file mode 100644
index 0000000000000..8b1374b97a44d
--- /dev/null
+++ b/test/micro/org/openjdk/bench/jdk/incubator/foreign/UnrolledAccess.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 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.
+ */
+
+package org.openjdk.bench.jdk.incubator.foreign;
+
+import static jdk.incubator.foreign.MemoryAccess.*;
+import jdk.incubator.foreign.*;
+import org.openjdk.jmh.annotations.*;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+import sun.misc.Unsafe;
+import java.util.concurrent.TimeUnit;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.lang.reflect.Field;
+
+@BenchmarkMode(Mode.AverageTime)
+@Warmup(iterations = 5, time = 500, timeUnit = TimeUnit.MILLISECONDS)
+@Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS)
+@State(org.openjdk.jmh.annotations.Scope.Thread)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@Fork(3)
+public class UnrolledAccess {
+
+ static final Unsafe U = Utils.unsafe;
+
+ final static int SIZE = 1024;
+
+ static final VarHandle LONG_HANDLE = MemoryLayout.ofSequence(SIZE, MemoryLayouts.JAVA_LONG)
+ .varHandle(long.class, MemoryLayout.PathElement.sequenceElement());
+
+ @State(Scope.Benchmark)
+ public static class Data {
+
+ final double[] inputArray;
+ final double[] outputArray;
+ final long inputAddress;
+ final long outputAddress;
+ final MemorySegment inputSegment;
+ final MemorySegment outputSegment;
+
+
+ public Data() {
+ this.inputArray = new double[SIZE];
+ this.outputArray = new double[SIZE];
+ this.inputAddress = U.allocateMemory(8 * SIZE);
+ this.outputAddress = U.allocateMemory(8 * SIZE);
+ this.inputSegment = MemoryAddress.ofLong(inputAddress).asSegmentRestricted(8*SIZE);
+ this.outputSegment = MemoryAddress.ofLong(outputAddress).asSegmentRestricted(8*SIZE);
+ }
+ }
+
+ @Benchmark
+ public void unsafe_loop(Data state) {
+ final long ia = state.inputAddress;
+ final long oa = state.outputAddress;
+ for(int i = 0; i < SIZE; i+=4) {
+ U.putLong(oa + 8*i, U.getLong(ia + 8*i) + U.getLong(oa + 8*i));
+ U.putLong(oa + 8*(i+1), U.getLong(ia + 8*(i+1)) + U.getLong(oa + 8*(i+1)));
+ U.putLong(oa + 8*(i+2), U.getLong(ia + 8*(i+2)) + U.getLong(oa + 8*(i+2)));
+ U.putLong(oa + 8*(i+3), U.getLong(ia + 8*(i+3)) + U.getLong(oa + 8*(i+3)));
+ }
+ }
+
+ @Benchmark
+ public void handle_loop(Data state) {
+ final MemorySegment is = state.inputSegment;
+ final MemorySegment os = state.outputSegment;
+
+ for(int i = 0; i < SIZE; i+=4) {
+ LONG_HANDLE.set(os, (long) (i), (long) LONG_HANDLE.get(is, (long) (i)) + (long) LONG_HANDLE.get(os, (long) (i)));
+ LONG_HANDLE.set(os, (long) (i+1), (long) LONG_HANDLE.get(is, (long) (i+1)) + (long) LONG_HANDLE.get(os, (long) (i+1)));
+ LONG_HANDLE.set(os, (long) (i+2), (long) LONG_HANDLE.get(is, (long) (i+2)) + (long) LONG_HANDLE.get(os, (long) (i+2)));
+ LONG_HANDLE.set(os, (long) (i+3), (long) LONG_HANDLE.get(is, (long) (i+3)) + (long) LONG_HANDLE.get(os, (long) (i+3)));
+ }
+ }
+
+ @Benchmark
+ public void static_handle_loop(Data state) {
+ final MemorySegment is = state.inputSegment;
+ final MemorySegment os = state.outputSegment;
+
+ for(int i = 0; i < SIZE; i+=4) {
+ setLongAtIndex(os, i,getLongAtIndex(is, i) + MemoryAccess.getLongAtIndex(os, i));
+ setLongAtIndex(os, i+1,getLongAtIndex(is, i+1) + getLongAtIndex(os, i+1));
+ setLongAtIndex(os, i+2,getLongAtIndex(is, i+2) + getLongAtIndex(os, i+2));
+ setLongAtIndex(os, i+3,getLongAtIndex(is, i+3) + getLongAtIndex(os, i+3));
+ }
+ }
+}
From 86b65756cbebf1df422b11a72be6c9762b85a702 Mon Sep 17 00:00:00 2001
From: Roland Westrelin
Date: Fri, 4 Dec 2020 12:01:53 +0000
Subject: [PATCH 078/504] 8257574: C2: "failed: parsing found no loops but
there are some" assert failure
Reviewed-by: thartmann, neliasso, chagedorn
---
src/hotspot/share/opto/loopnode.cpp | 30 ++++++------
.../TestInfiniteLoopNotInnerMost.java | 46 +++++++++++++++++++
2 files changed, 60 insertions(+), 16 deletions(-)
create mode 100644 test/hotspot/jtreg/compiler/loopopts/TestInfiniteLoopNotInnerMost.java
diff --git a/src/hotspot/share/opto/loopnode.cpp b/src/hotspot/share/opto/loopnode.cpp
index dfff14a5d0f1e..0ed49439af000 100644
--- a/src/hotspot/share/opto/loopnode.cpp
+++ b/src/hotspot/share/opto/loopnode.cpp
@@ -3663,25 +3663,23 @@ bool PhaseIdealLoop::process_expensive_nodes() {
#ifdef ASSERT
bool PhaseIdealLoop::only_has_infinite_loops() {
- for (LoopTreeIterator iter(_ltree_root); !iter.done(); iter.next()) {
- IdealLoopTree* lpt = iter.current();
- if (lpt->is_innermost()) {
- uint i = 1;
- for (; i < C->root()->req(); i++) {
- Node* in = C->root()->in(i);
- if (in != NULL &&
- in->Opcode() == Op_Halt &&
- in->in(0)->is_Proj() &&
- in->in(0)->in(0)->Opcode() == Op_NeverBranch &&
- in->in(0)->in(0)->in(0) == lpt->_head) {
- break;
- }
- }
- if (i == C->root()->req()) {
- return false;
+ for (IdealLoopTree* l = _ltree_root->_child; l != NULL; l = l->_next) {
+ uint i = 1;
+ for (; i < C->root()->req(); i++) {
+ Node* in = C->root()->in(i);
+ if (in != NULL &&
+ in->Opcode() == Op_Halt &&
+ in->in(0)->is_Proj() &&
+ in->in(0)->in(0)->Opcode() == Op_NeverBranch &&
+ in->in(0)->in(0)->in(0) == l->_head) {
+ break;
}
}
+ if (i == C->root()->req()) {
+ return false;
+ }
}
+
return true;
}
#endif
diff --git a/test/hotspot/jtreg/compiler/loopopts/TestInfiniteLoopNotInnerMost.java b/test/hotspot/jtreg/compiler/loopopts/TestInfiniteLoopNotInnerMost.java
new file mode 100644
index 0000000000000..4e6a897361579
--- /dev/null
+++ b/test/hotspot/jtreg/compiler/loopopts/TestInfiniteLoopNotInnerMost.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2020, 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 8257574
+ * @summary C2: "failed: parsing found no loops but there are some" assert failure
+ *
+ * @run main/othervm -Xcomp -XX:CompileOnly=TestInfiniteLoopNotInnerMost::test TestInfiniteLoopNotInnerMost
+ *
+ */
+public class TestInfiniteLoopNotInnerMost {
+ public static void main(String[] args) {
+ test(false);
+ }
+
+ private static void test(boolean flag) {
+ if (flag) {
+ while (true) {
+ for (int i = 1; i < 100; i *= 2) {
+
+ }
+ }
+ }
+ }
+}
From ac54900849304761b8e8a49ed312103eeef92b9c Mon Sep 17 00:00:00 2001
From: Kartik Ohri
Date: Fri, 4 Dec 2020 15:15:56 +0000
Subject: [PATCH 079/504] 8257401: Use switch expressions in
jdk.internal.net.http and java.net.http
Reviewed-by: chegar, dfuchs, pconcannon
---
.../internal/net/http/Http1HeaderParser.java | 59 +++++--------------
.../jdk/internal/net/http/Http1Response.java | 11 ++--
.../internal/net/http/Http2Connection.java | 20 ++-----
.../jdk/internal/net/http/MultiExchange.java | 11 ++--
.../jdk/internal/net/http/RedirectFilter.java | 54 ++++++-----------
.../classes/jdk/internal/net/http/Stream.java | 17 ++----
.../net/http/common/SSLFlowDelegate.java | 12 ++--
.../internal/net/http/frame/DataFrame.java | 13 ++--
.../net/http/frame/FramesEncoder.java | 38 +++++-------
.../internal/net/http/frame/HeaderFrame.java | 13 ++--
.../internal/net/http/frame/HeadersFrame.java | 16 +++--
.../internal/net/http/frame/Http2Frame.java | 38 +++++-------
.../internal/net/http/frame/PingFrame.java | 9 ++-
.../net/http/frame/PushPromiseFrame.java | 13 ++--
.../net/http/frame/SettingsFrame.java | 34 +++++------
.../jdk/internal/net/http/hpack/Decoder.java | 28 +++------
.../net/http/websocket/StatusCodes.java | 30 +++-------
17 files changed, 147 insertions(+), 269 deletions(-)
diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Http1HeaderParser.java b/src/java.net.http/share/classes/jdk/internal/net/http/Http1HeaderParser.java
index 2674f0c0ff3c6..669c173e3f825 100644
--- a/src/java.net.http/share/classes/jdk/internal/net/http/Http1HeaderParser.java
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http1HeaderParser.java
@@ -116,42 +116,17 @@ boolean parse(ByteBuffer input) throws ProtocolException {
while (canContinueParsing(input)) {
switch (state) {
- case INITIAL:
- state = State.STATUS_LINE;
- break;
- case STATUS_LINE:
- readResumeStatusLine(input);
- break;
- // fallthrough
- case STATUS_LINE_FOUND_CR:
- case STATUS_LINE_FOUND_LF:
- readStatusLineFeed(input);
- break;
- case STATUS_LINE_END:
- maybeStartHeaders(input);
- break;
- // fallthrough
- case STATUS_LINE_END_CR:
- case STATUS_LINE_END_LF:
- maybeEndHeaders(input);
- break;
- case HEADER:
- readResumeHeader(input);
- break;
- // fallthrough
- case HEADER_FOUND_CR:
- case HEADER_FOUND_LF:
- resumeOrLF(input);
- break;
- case HEADER_FOUND_CR_LF:
- resumeOrSecondCR(input);
- break;
- case HEADER_FOUND_CR_LF_CR:
- resumeOrEndHeaders(input);
- break;
- default:
- throw new InternalError(
- "Unexpected state: " + String.valueOf(state));
+ case INITIAL -> state = State.STATUS_LINE;
+ case STATUS_LINE -> readResumeStatusLine(input);
+ case STATUS_LINE_FOUND_CR, STATUS_LINE_FOUND_LF -> readStatusLineFeed(input);
+ case STATUS_LINE_END -> maybeStartHeaders(input);
+ case STATUS_LINE_END_CR, STATUS_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);
}
}
@@ -161,13 +136,11 @@ boolean parse(ByteBuffer input) throws ProtocolException {
private boolean canContinueParsing(ByteBuffer buffer) {
// some states don't require any input to transition
// to the next state.
- switch (state) {
- case FINISHED: return false;
- case STATUS_LINE_FOUND_LF: return true;
- case STATUS_LINE_END_LF: return true;
- case HEADER_FOUND_LF: return true;
- default: return buffer.hasRemaining();
- }
+ return switch (state) {
+ case FINISHED -> false;
+ case STATUS_LINE_FOUND_LF, STATUS_LINE_END_LF, HEADER_FOUND_LF -> true;
+ default -> buffer.hasRemaining();
+ };
}
/**
diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Http1Response.java b/src/java.net.http/share/classes/jdk/internal/net/http/Http1Response.java
index 5cb0b8644076e..8090568c4e451 100644
--- a/src/java.net.http/share/classes/jdk/internal/net/http/Http1Response.java
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http1Response.java
@@ -576,11 +576,12 @@ private State advance(State previous) {
}
Receiver> receiver(State state) {
- switch(state) {
- case READING_HEADERS: return headersReader;
- case READING_BODY: return bodyReader;
- default: return null;
- }
+ return switch (state) {
+ case READING_HEADERS -> headersReader;
+ case READING_BODY -> bodyReader;
+
+ default -> null;
+ };
}
diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java b/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java
index 9cfc3d3f95ab1..d0a47316970eb 100644
--- a/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java
@@ -866,20 +866,12 @@ private void handleConnectionFrame(Http2Frame frame)
throws IOException
{
switch (frame.type()) {
- case SettingsFrame.TYPE:
- handleSettings((SettingsFrame)frame);
- break;
- case PingFrame.TYPE:
- handlePing((PingFrame)frame);
- break;
- case GoAwayFrame.TYPE:
- handleGoAway((GoAwayFrame)frame);
- break;
- case WindowUpdateFrame.TYPE:
- handleWindowUpdate((WindowUpdateFrame)frame);
- break;
- default:
- protocolError(ErrorFrame.PROTOCOL_ERROR);
+ case SettingsFrame.TYPE -> handleSettings((SettingsFrame) frame);
+ case PingFrame.TYPE -> handlePing((PingFrame) frame);
+ case GoAwayFrame.TYPE -> handleGoAway((GoAwayFrame) frame);
+ case WindowUpdateFrame.TYPE -> handleWindowUpdate((WindowUpdateFrame) frame);
+
+ default -> protocolError(ErrorFrame.PROTOCOL_ERROR);
}
}
diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/MultiExchange.java b/src/java.net.http/share/classes/jdk/internal/net/http/MultiExchange.java
index 12eed08a154da..c1f03190380cc 100644
--- a/src/java.net.http/share/classes/jdk/internal/net/http/MultiExchange.java
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/MultiExchange.java
@@ -476,13 +476,10 @@ private static boolean disableRetryConnect() {
/** Returns true is given request has an idempotent method. */
private static boolean isIdempotentRequest(HttpRequest request) {
String method = request.method();
- switch (method) {
- case "GET" :
- case "HEAD" :
- return true;
- default :
- return false;
- }
+ return switch (method) {
+ case "GET", "HEAD" -> true;
+ default -> false;
+ };
}
/** Returns true if the given request can be automatically retried. */
diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/RedirectFilter.java b/src/java.net.http/share/classes/jdk/internal/net/http/RedirectFilter.java
index 79e2a2fbfc335..32eece7603fe8 100644
--- a/src/java.net.http/share/classes/jdk/internal/net/http/RedirectFilter.java
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/RedirectFilter.java
@@ -74,19 +74,13 @@ public synchronized HttpRequestImpl response(Response r) throws IOException {
}
private static String redirectedMethod(int statusCode, String orig) {
- switch (statusCode) {
- case 301:
- case 302:
- return orig.equals("POST") ? "GET" : orig;
- case 303:
- return "GET";
- case 307:
- case 308:
- return orig;
- default:
- // unexpected but return orig
- return orig;
- }
+ return switch (statusCode) {
+ case 301, 302 -> orig.equals("POST") ? "GET" : orig;
+ case 303 -> "GET";
+ case 307, 308 -> orig;
+
+ default -> orig; // unexpected but return orig
+ };
}
private static boolean isRedirecting(int statusCode) {
@@ -95,23 +89,16 @@ private static boolean isRedirecting(int statusCode) {
// 309-399 Unassigned => don't follow
// > 399: not a redirect code
if (statusCode > 308) return false;
- switch (statusCode) {
+
+ return switch (statusCode) {
// 300: MultipleChoice => don't follow
- case 300:
- return false;
// 304: Not Modified => don't follow
- case 304:
- return false;
// 305: Proxy Redirect => don't follow.
- case 305:
- return false;
// 306: Unused => don't follow
- case 306:
- return false;
+ case 300, 304, 305, 306 -> false;
// 301, 302, 303, 307, 308: OK to follow.
- default:
- return true;
- }
+ default -> true;
+ };
}
/**
@@ -158,16 +145,11 @@ private URI getRedirectedURI(HttpHeaders headers) {
private boolean canRedirect(URI redir) {
String newScheme = redir.getScheme();
String oldScheme = uri.getScheme();
- switch (policy) {
- case ALWAYS:
- return true;
- case NEVER:
- return false;
- case NORMAL:
- return newScheme.equalsIgnoreCase(oldScheme)
- || newScheme.equalsIgnoreCase("https");
- default:
- throw new InternalError();
- }
+ return switch (policy) {
+ case ALWAYS -> true;
+ case NEVER -> false;
+ case NORMAL -> newScheme.equalsIgnoreCase(oldScheme)
+ || newScheme.equalsIgnoreCase("https");
+ };
}
}
diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java b/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java
index b288d67ff92a8..1508df73224d6 100644
--- a/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java
@@ -451,18 +451,11 @@ void incoming(Http2Frame frame) throws IOException {
void otherFrame(Http2Frame frame) throws IOException {
switch (frame.type()) {
- case WindowUpdateFrame.TYPE:
- incoming_windowUpdate((WindowUpdateFrame) frame);
- break;
- case ResetFrame.TYPE:
- incoming_reset((ResetFrame) frame);
- break;
- case PriorityFrame.TYPE:
- incoming_priority((PriorityFrame) frame);
- break;
- default:
- String msg = "Unexpected frame: " + frame.toString();
- throw new IOException(msg);
+ case WindowUpdateFrame.TYPE -> incoming_windowUpdate((WindowUpdateFrame) frame);
+ case ResetFrame.TYPE -> incoming_reset((ResetFrame) frame);
+ case PriorityFrame.TYPE -> incoming_priority((PriorityFrame) frame);
+
+ default -> throw new IOException("Unexpected frame: " + frame.toString());
}
}
diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/common/SSLFlowDelegate.java b/src/java.net.http/share/classes/jdk/internal/net/http/common/SSLFlowDelegate.java
index 573ac85899d5b..a9d3ee967ea42 100644
--- a/src/java.net.http/share/classes/jdk/internal/net/http/common/SSLFlowDelegate.java
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/common/SSLFlowDelegate.java
@@ -1021,14 +1021,10 @@ private static String states(AtomicInteger state) {
StringBuilder sb = new StringBuilder();
int x = s & ~TASK_BITS;
switch (x) {
- case NOT_HANDSHAKING:
- sb.append(" NOT_HANDSHAKING ");
- break;
- case HANDSHAKING:
- sb.append(" HANDSHAKING ");
- break;
- default:
- throw new InternalError();
+ case NOT_HANDSHAKING -> sb.append(" NOT_HANDSHAKING ");
+ case HANDSHAKING -> sb.append(" HANDSHAKING ");
+
+ default -> throw new InternalError();
}
if ((s & DOING_TASKS) > 0)
sb.append("|DOING_TASKS");
diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/frame/DataFrame.java b/src/java.net.http/share/classes/jdk/internal/net/http/frame/DataFrame.java
index 4f17547103e3c..635ab44679fd3 100644
--- a/src/java.net.http/share/classes/jdk/internal/net/http/frame/DataFrame.java
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/frame/DataFrame.java
@@ -71,13 +71,12 @@ int length() {
@Override
public String flagAsString(int flag) {
- switch (flag) {
- case END_STREAM:
- return "END_STREAM";
- case PADDED:
- return "PADDED";
- }
- return super.flagAsString(flag);
+ return switch (flag) {
+ case END_STREAM -> "END_STREAM";
+ case PADDED -> "PADDED";
+
+ default -> super.flagAsString(flag);
+ };
}
public List