From a06585af49979e34525c02cfeb6af8d3e5f54ea6 Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Sat, 9 May 2020 13:42:16 -0700 Subject: [PATCH 001/143] 8244673: Add periods to SourceVersion.isName javadoc Reviewed-by: jjg --- .../share/classes/javax/lang/model/SourceVersion.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/java.compiler/share/classes/javax/lang/model/SourceVersion.java b/src/java.compiler/share/classes/javax/lang/model/SourceVersion.java index 6a1143ea5ef..aa7f31e3c68 100644 --- a/src/java.compiler/share/classes/javax/lang/model/SourceVersion.java +++ b/src/java.compiler/share/classes/javax/lang/model/SourceVersion.java @@ -325,7 +325,7 @@ public enum SourceVersion { * literal in any segment. * * This method returns {@code true} for restricted - * keywords and restricted identifiers + * keywords and restricted identifiers. * * @param name the string to check * @return {@code true} if this string is a @@ -351,7 +351,7 @@ public enum SourceVersion { * literal in any segment. * * This method returns {@code true} for restricted - * keywords and restricted identifiers + * keywords and restricted identifiers. * * @param name the string to check * @param version the version to use From ceda3089db75e07b9c2e85a555c16ef7601b3de8 Mon Sep 17 00:00:00 2001 From: Claes Redestad Date: Mon, 11 May 2020 10:37:54 +0200 Subject: [PATCH 002/143] 8244624: Improve handling of JarFile META-INF resources Reviewed-by: lancea, weijun, martin --- .../share/classes/java/util/jar/JarFile.java | 83 ++++----- .../share/classes/java/util/zip/ZipFile.java | 161 +++++++++++++----- .../access/JavaUtilZipFileAccess.java | 4 +- .../security/util/SignatureFileVerifier.java | 1 + .../bench/java/util/jar/JarFileMeta.java | 155 +++++++++++++++++ 5 files changed, 312 insertions(+), 92 deletions(-) create mode 100644 test/micro/org/openjdk/bench/java/util/jar/JarFileMeta.java diff --git a/src/java.base/share/classes/java/util/jar/JarFile.java b/src/java.base/share/classes/java/util/jar/JarFile.java index ae9a743c506..a71e13d8bff 100644 --- a/src/java.base/share/classes/java/util/jar/JarFile.java +++ b/src/java.base/share/classes/java/util/jar/JarFile.java @@ -715,21 +715,14 @@ public class JarFile extends ZipFile { } if (verify) { - String[] names = JUZFA.getMetaInfEntryNames(this); - if (names != null) { - for (String nameLower : names) { - String name = nameLower.toUpperCase(Locale.ENGLISH); - if (name.endsWith(".DSA") || - name.endsWith(".RSA") || - name.endsWith(".EC") || - name.endsWith(".SF")) { - // Assume since we found a signature-related file - // that the jar is signed and that we therefore - // need a JarVerifier and Manifest - getManifest(); - return; - } - } + // Gets the manifest name, but only if there are + // signature-related files. If so we can assume + // that the jar is signed and that we therefore + // need a JarVerifier and Manifest + String name = JUZFA.getManifestName(this, true); + if (name != null) { + getManifest(); + return; } // No signature-related files; don't instantiate a // verifier @@ -746,30 +739,24 @@ public class JarFile extends ZipFile { // Verify "META-INF/" entries... try { - String[] names = JUZFA.getMetaInfEntryNames(this); - if (names != null) { - for (String name : names) { - String uname = name.toUpperCase(Locale.ENGLISH); - if (MANIFEST_NAME.equals(uname) - || SignatureFileVerifier.isBlockOrSF(uname)) { - JarEntry e = getJarEntry(name); - if (e == null) { - throw new JarException("corrupted jar file"); - } - if (mev == null) { - mev = new ManifestEntryVerifier - (getManifestFromReference()); - } - byte[] b = getBytes(e); - if (b != null && b.length > 0) { - jv.beginEntry(e, mev); - jv.update(b.length, b, 0, b.length, mev); - jv.update(-1, null, 0, 0, mev); - } - } + List names = JUZFA.getManifestAndSignatureRelatedFiles(this); + for (String name : names) { + JarEntry e = getJarEntry(name); + if (e == null) { + throw new JarException("corrupted jar file"); + } + if (mev == null) { + mev = new ManifestEntryVerifier + (getManifestFromReference()); + } + byte[] b = getBytes(e); + if (b != null && b.length > 0) { + jv.beginEntry(e, mev); + jv.update(b.length, b, 0, b.length, mev); + jv.update(-1, null, 0, 0, mev); } } - } catch (IOException ex) { + } catch (IOException | IllegalArgumentException ex) { // if we had an error parsing any blocks, just // treat the jar file as being unsigned jv = null; @@ -935,22 +922,12 @@ public class JarFile extends ZipFile { private JarEntry getManEntry() { if (manEntry == null) { - // First look up manifest entry using standard name - JarEntry manEntry = getEntry0(MANIFEST_NAME); - if (manEntry == null) { - // If not found, then iterate through all the "META-INF/" - // entries to find a match. - String[] names = JUZFA.getMetaInfEntryNames(this); - if (names != null) { - for (String name : names) { - if (MANIFEST_NAME.equals(name.toUpperCase(Locale.ENGLISH))) { - manEntry = getEntry0(name); - break; - } - } - } + // The manifest entry position is resolved during + // initialization + String name = JUZFA.getManifestName(this, false); + if (name != null) { + this.manEntry = getEntry0(name); } - this.manEntry = manEntry; } return manEntry; } @@ -1213,7 +1190,7 @@ public class JarFile extends ZipFile { ensureInitialization(); if (jv != null) { if (jv.eagerValidation) { - CodeSource cs = null; + CodeSource cs; JarEntry je = getJarEntry(name); if (je != null) { cs = jv.getCodeSource(url, this, je); diff --git a/src/java.base/share/classes/java/util/zip/ZipFile.java b/src/java.base/share/classes/java/util/zip/ZipFile.java index bb05e19454d..1b028199434 100644 --- a/src/java.base/share/classes/java/util/zip/ZipFile.java +++ b/src/java.base/share/classes/java/util/zip/ZipFile.java @@ -45,6 +45,8 @@ import java.util.Deque; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; +import java.util.List; +import java.util.Locale; import java.util.Objects; import java.util.NoSuchElementException; import java.util.Set; @@ -66,6 +68,7 @@ import jdk.internal.perf.PerfCounter; import jdk.internal.ref.CleanerFactory; import jdk.internal.vm.annotation.Stable; import sun.nio.cs.UTF_8; +import sun.security.util.SignatureFileVerifier; import static java.util.zip.ZipConstants64.*; import static java.util.zip.ZipUtils.*; @@ -1010,31 +1013,51 @@ public class ZipFile implements ZipConstants, Closeable { } /** - * Returns the names of all non-directory entries that begin with - * "META-INF/" (case ignored). This method is used in JarFile, via - * SharedSecrets, as an optimization when looking up manifest and - * signature file entries. Returns null if no entries were found. + * Returns the names of the META-INF/MANIFEST.MF entry - if exists - + * and any signature-related files under META-INF. This method is used in + * JarFile, via SharedSecrets, as an optimization. */ - private String[] getMetaInfEntryNames() { + private List getManifestAndSignatureRelatedFiles() { synchronized (this) { ensureOpen(); Source zsrc = res.zsrc; - if (zsrc.metanames == null) { - return null; + int[] metanames = zsrc.signatureMetaNames; + List files = null; + if (zsrc.manifestPos >= 0) { + files = new ArrayList<>(); + files.add(getEntryName(zsrc.manifestPos)); } - String[] names = new String[zsrc.metanames.length]; - byte[] cen = zsrc.cen; - for (int i = 0; i < names.length; i++) { - int pos = zsrc.metanames[i]; - // This will only be invoked on JarFile, which is guaranteed - // to use (or be compatible with) UTF-8 encoding. - names[i] = new String(cen, pos + CENHDR, CENNAM(cen, pos), - UTF_8.INSTANCE); + if (metanames != null) { + if (files == null) { + files = new ArrayList<>(); + } + for (int i = 0; i < metanames.length; i++) { + files.add(getEntryName(metanames[i])); + } } - return names; + return files == null ? List.of() : files; } } + /** + * Returns the name of the META-INF/MANIFEST.MF entry, ignoring + * case. If {@code onlyIfSignatureRelatedFiles} is true, we only return the + * manifest if there is also at least one signature-related file. + * This method is used in JarFile, via SharedSecrets, as an optimization + * when looking up the manifest file. + */ + private String getManifestName(boolean onlyIfSignatureRelatedFiles) { + synchronized (this) { + ensureOpen(); + Source zsrc = res.zsrc; + int pos = zsrc.manifestPos; + if (pos >= 0 && (!onlyIfSignatureRelatedFiles || zsrc.signatureMetaNames != null)) { + return getEntryName(pos); + } + } + return null; + } + /** * Returns the versions for which there exists a non-directory * entry that begin with "META-INF/versions/" (case ignored). @@ -1059,8 +1082,12 @@ public class ZipFile implements ZipConstants, Closeable { return zip.res.zsrc.startsWithLoc; } @Override - public String[] getMetaInfEntryNames(JarFile jar) { - return ((ZipFile)jar).getMetaInfEntryNames(); + public List getManifestAndSignatureRelatedFiles(JarFile jar) { + return ((ZipFile)jar).getManifestAndSignatureRelatedFiles(); + } + @Override + public String getManifestName(JarFile jar, boolean onlyIfHasSignatureRelatedFiles) { + return ((ZipFile)jar).getManifestName(onlyIfHasSignatureRelatedFiles); } @Override public int[] getMetaInfVersions(JarFile jar) { @@ -1105,7 +1132,8 @@ public class ZipFile implements ZipConstants, Closeable { private long locpos; // position of first LOC header (usually 0) private byte[] comment; // zip file comment // list of meta entries in META-INF dir - private int[] metanames; + private int manifestPos = -1; // position of the META-INF/MANIFEST.MF, if exists + private int[] signatureMetaNames; // positions of signature related entries, if such exist private int[] metaVersions; // list of unique versions found in META-INF/versions/ private final boolean startsWithLoc; // true, if zip file starts with LOCSIG (usually true) @@ -1254,7 +1282,8 @@ public class ZipFile implements ZipConstants, Closeable { cen = null; entries = null; table = null; - metanames = null; + manifestPos = -1; + signatureMetaNames = null; metaVersions = EMPTY_META_VERSIONS; } @@ -1438,7 +1467,7 @@ public class ZipFile implements ZipConstants, Closeable { int next; // list for all meta entries - ArrayList metanamesList = null; + ArrayList signatureNames = null; // Set of all version numbers seen in META-INF/versions/ Set metaVersionsSet = null; @@ -1476,19 +1505,27 @@ public class ZipFile implements ZipConstants, Closeable { idx = addEntry(idx, hash, next, pos); // Adds name to metanames. if (isMetaName(cen, entryPos, nlen)) { - if (metanamesList == null) - metanamesList = new ArrayList<>(4); - metanamesList.add(pos); + // nlen is at least META_INF_LENGTH + if (isManifestName(cen, entryPos + META_INF_LENGTH, + nlen - META_INF_LENGTH)) { + manifestPos = pos; + } else { + if (isSignatureRelated(cen, entryPos, nlen)) { + if (signatureNames == null) + signatureNames = new ArrayList<>(4); + signatureNames.add(pos); + } - // If this is a versioned entry, parse the version - // and store it for later. This optimizes lookup - // performance in multi-release jar files - int version = getMetaVersion(cen, - entryPos + META_INF_LENGTH, nlen - META_INF_LENGTH); - if (version > 0) { - if (metaVersionsSet == null) - metaVersionsSet = new TreeSet<>(); - metaVersionsSet.add(version); + // If this is a versioned entry, parse the version + // and store it for later. This optimizes lookup + // performance in multi-release jar files + int version = getMetaVersion(cen, + entryPos + META_INF_LENGTH, nlen - META_INF_LENGTH); + if (version > 0) { + if (metaVersionsSet == null) + metaVersionsSet = new TreeSet<>(); + metaVersionsSet.add(version); + } } } // skip ext and comment @@ -1497,10 +1534,11 @@ public class ZipFile implements ZipConstants, Closeable { i++; } total = i; - if (metanamesList != null) { - metanames = new int[metanamesList.size()]; - for (int j = 0, len = metanames.length; j < len; j++) { - metanames[j] = metanamesList.get(j); + if (signatureNames != null) { + int len = signatureNames.size(); + signatureMetaNames = new int[len]; + for (int j = 0; j < len; j++) { + signatureMetaNames[j] = signatureNames.get(j); } } if (metaVersionsSet != null) { @@ -1580,7 +1618,8 @@ public class ZipFile implements ZipConstants, Closeable { * beginning with "META-INF/", disregarding ASCII case. */ private static boolean isMetaName(byte[] name, int off, int len) { - // Use the "oldest ASCII trick in the book" + // Use the "oldest ASCII trick in the book": + // ch | 0x20 == Character.toLowerCase(ch) return len > META_INF_LENGTH // "META-INF/".length() && name[off + len - 1] != '/' // non-directory && (name[off++] | 0x20) == 'm' @@ -1594,6 +1633,52 @@ public class ZipFile implements ZipConstants, Closeable { && (name[off] ) == '/'; } + /* + * Check if the bytes represents a name equals to MANIFEST.MF + */ + private static boolean isManifestName(byte[] name, int off, int len) { + return (len == 11 // "MANIFEST.MF".length() + && (name[off++] | 0x20) == 'm' + && (name[off++] | 0x20) == 'a' + && (name[off++] | 0x20) == 'n' + && (name[off++] | 0x20) == 'i' + && (name[off++] | 0x20) == 'f' + && (name[off++] | 0x20) == 'e' + && (name[off++] | 0x20) == 's' + && (name[off++] | 0x20) == 't' + && (name[off++] ) == '.' + && (name[off++] | 0x20) == 'm' + && (name[off] | 0x20) == 'f'); + } + + private static boolean isSignatureRelated(byte[] name, int off, int len) { + // Only called when isMetaName(name, off, len) is true, which means + // len is at least META_INF_LENGTH + // assert isMetaName(name, off, len) + boolean signatureRelated = false; + if (name[off + len - 3] == '.') { + // Check if entry ends with .EC and .SF + int b1 = name[off + len - 2] | 0x20; + int b2 = name[off + len - 1] | 0x20; + if ((b1 == 'e' && b2 == 'c') || (b1 == 's' && b2 == 'f')) { + signatureRelated = true; + } + } else if (name[off + len - 4] == '.') { + // Check if entry ends with .DSA and .RSA + int b1 = name[off + len - 3] | 0x20; + int b2 = name[off + len - 2] | 0x20; + int b3 = name[off + len - 1] | 0x20; + if ((b1 == 'r' || b1 == 'd') && b2 == 's' && b3 == 'a') { + signatureRelated = true; + } + } + // Above logic must match SignatureFileVerifier.isBlockOrSF + assert(signatureRelated == SignatureFileVerifier + .isBlockOrSF(new String(name, off, len, UTF_8.INSTANCE) + .toUpperCase(Locale.ENGLISH))); + return signatureRelated; + } + /* * If the bytes represents a non-directory name beginning * with "versions/", continuing with a positive integer, diff --git a/src/java.base/share/classes/jdk/internal/access/JavaUtilZipFileAccess.java b/src/java.base/share/classes/jdk/internal/access/JavaUtilZipFileAccess.java index da470fc2c9a..8a0a95dcedc 100644 --- a/src/java.base/share/classes/jdk/internal/access/JavaUtilZipFileAccess.java +++ b/src/java.base/share/classes/jdk/internal/access/JavaUtilZipFileAccess.java @@ -26,6 +26,7 @@ package jdk.internal.access; import java.util.Enumeration; +import java.util.List; import java.util.function.Function; import java.util.jar.JarEntry; import java.util.jar.JarFile; @@ -34,7 +35,8 @@ import java.util.zip.ZipFile; public interface JavaUtilZipFileAccess { public boolean startsWithLocHeader(ZipFile zip); - public String[] getMetaInfEntryNames(JarFile zip); + public List getManifestAndSignatureRelatedFiles(JarFile zip); + public String getManifestName(JarFile zip, boolean onlyIfSignatureRelatedFiles); public int[] getMetaInfVersions(JarFile zip); public JarEntry getEntry(ZipFile zip, String name, Function func); public Enumeration entries(ZipFile zip, Function func); diff --git a/src/java.base/share/classes/sun/security/util/SignatureFileVerifier.java b/src/java.base/share/classes/sun/security/util/SignatureFileVerifier.java index 5015c743bdf..dd68ef84349 100644 --- a/src/java.base/share/classes/sun/security/util/SignatureFileVerifier.java +++ b/src/java.base/share/classes/sun/security/util/SignatureFileVerifier.java @@ -175,6 +175,7 @@ public class SignatureFileVerifier { * Signature File or PKCS7 block file name */ public static boolean isBlockOrSF(String s) { + // Note: keep this in sync with j.u.z.ZipFile.Source#isSignatureRelated // we currently only support DSA and RSA PKCS7 blocks return s.endsWith(".SF") || s.endsWith(".DSA") diff --git a/test/micro/org/openjdk/bench/java/util/jar/JarFileMeta.java b/test/micro/org/openjdk/bench/java/util/jar/JarFileMeta.java new file mode 100644 index 00000000000..38508cecbe0 --- /dev/null +++ b/test/micro/org/openjdk/bench/java/util/jar/JarFileMeta.java @@ -0,0 +1,155 @@ +/* + * 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.java.util.jar; + +import org.openjdk.jmh.annotations.*; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.util.Random; +import java.util.concurrent.TimeUnit; +import java.util.jar.JarFile; +import java.util.jar.JarOutputStream; +import java.util.jar.Manifest; +import java.util.zip.ZipEntry; + +/** + * Simple benchmark measuring cost of various operations relating to jar + * meta-inf and manifests, especially costs incurred during opening of the + * file, and when opening an input stream (which runs + * JarFile.maybeInstantiateVerifier) + * + * Before JDK-8244624: + * Benchmark (size) Mode Cnt Score Error Units + * getManifestFromJarWithManifest 1024 avgt 5 232.437 31.535 us/op + * gc.alloc.rate.norm 1024 avgt 5 206410.627 2.833 B/op + * getStreamFromJarWithManifest 1024 avgt 5 277.696 32.078 us/op + * gc.alloc.rate.norm 1024 avgt 5 250454.252 2.452 B/op + * getStreamFromJarWithNoManifest 1024 avgt 5 312.432 58.663 us/op + * gc.alloc.rate.norm 1024 avgt 5 301802.644 13.276 B/op + * getStreamFromJarWithSignatureFiles 1024 avgt 5 315.752 55.048 us/op + * gc.alloc.rate.norm 1024 avgt 5 305354.934 14.093 B/op + * + * With JDK-8244624: + * Benchmark (size) Mode Cnt Score Error Units + * getManifestFromJarWithManifest 1024 avgt 5 215.242 32.085 us/op + * gc.alloc.rate.norm 1024 avgt 5 196609.220 14.788 B/op + * getStreamFromJarWithManifest 1024 avgt 5 216.435 10.876 us/op + * gc.alloc.rate.norm 1024 avgt 5 187960.147 9.026 B/op + * getStreamFromJarWithNoManifest 1024 avgt 5 204.256 25.744 us/op + * gc.alloc.rate.norm 1024 avgt 5 186784.347 1.841 B/op + * getStreamFromJarWithSignatureFiles 1024 avgt 5 247.972 38.574 us/op + * gc.alloc.rate.norm 1024 avgt 5 211577.268 15.109 B/op + */ +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +@State(Scope.Thread) +@Warmup(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS) +@Measurement(iterations = 5, time = 1000, timeUnit = TimeUnit.MILLISECONDS) +@Fork(3) +public class JarFileMeta { + + @Param({"512", "1024"}) + private int size; + + public File jarManifest; + public File jarNoManifest; + public File jarManifestSignature; + + public int index = 0; + + @Setup(Level.Trial) + public void beforeRun() throws IOException { + jarNoManifest = createJar(false, false); + jarManifest = createJar(true, false); + jarManifestSignature = createJar(true, true); + } + + private File createJar(boolean manifest, boolean signatureFiles) throws IOException { + // Create a test Zip file with the number of entries. + File tempFile = Files.createTempFile("jar-micro", ".jar").toFile(); + tempFile.deleteOnExit(); + + try (FileOutputStream fos = new FileOutputStream(tempFile); + JarOutputStream zos = manifest + ? new JarOutputStream(fos, new Manifest()) + : new JarOutputStream(fos)) { + + // Always add this + zos.putNextEntry(new ZipEntry("README")); + + Random random = new Random(4711); + for (int i = 0; i < size; i++) { + String ename = "directory-" + (random.nextInt(90000) + 10000) + "-" + i + "/"; + if (random.nextInt(100) > 70) { + ename = "META-INF/" + ename; + + } + zos.putNextEntry(new ZipEntry(ename)); + + ename += "entry-" + (random.nextInt(90000) + 10000) + "-" + i; + if (signatureFiles && random.nextInt(100) > 95) { + ename += ".DSA"; + } + zos.putNextEntry(new ZipEntry(ename)); + } + } + return tempFile; + } + + private InputStream openGetStreamAndClose(File file) throws IOException { + JarFile jf = new JarFile(file); + InputStream is = jf.getInputStream(jf.getEntry("README")); + jf.close(); + // we'll never actually read from the closed stream, rather just + // return it to avoid DCE + return is; + } + + @Benchmark + public InputStream getStreamFromJarWithManifest() throws IOException { + return openGetStreamAndClose(jarManifest); + } + + @Benchmark + public InputStream getStreamFromJarWithNoManifest() throws IOException { + return openGetStreamAndClose(jarNoManifest); + } + + @Benchmark + public InputStream getStreamFromJarWithSignatureFiles() throws IOException { + return openGetStreamAndClose(jarManifestSignature); + } + + @Benchmark + public Manifest getManifestFromJarWithManifest() throws IOException { + JarFile jf = new JarFile(jarManifest); + Manifest mf = jf.getManifest(); + jf.close(); + return mf; + } +} From 3887904c164976772a9c40162a07dd0ca056bed2 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Mon, 11 May 2020 12:57:39 +0200 Subject: [PATCH 003/143] 8244207: Simplify usage of Compile::print_method() when debugging with gdb and enable its use with rr Improve debugging with usage of Compile::print_method() for IGV at breakpoints from gdb and rr. Reviewed-by: kvn, thartmann --- src/hotspot/share/opto/compile.cpp | 77 ++++++++- src/hotspot/share/opto/compile.hpp | 13 +- src/hotspot/share/opto/idealGraphPrinter.cpp | 162 +++++++++++-------- src/hotspot/share/opto/idealGraphPrinter.hpp | 10 +- src/hotspot/share/opto/phasetype.hpp | 2 + 5 files changed, 195 insertions(+), 69 deletions(-) diff --git a/src/hotspot/share/opto/compile.cpp b/src/hotspot/share/opto/compile.cpp index 01aaef49138..b26a4d2b600 100644 --- a/src/hotspot/share/opto/compile.cpp +++ b/src/hotspot/share/opto/compile.cpp @@ -4545,7 +4545,6 @@ void CloneMap::dump(node_idx_t key) const { } } - // Move Allocate nodes to the start of the list void Compile::sort_macro_nodes() { int count = macro_count(); @@ -4562,3 +4561,79 @@ void Compile::sort_macro_nodes() { } } } + + +#ifndef PRODUCT +IdealGraphPrinter* Compile::_debug_file_printer = NULL; +IdealGraphPrinter* Compile::_debug_network_printer = NULL; + +// Called from debugger. Prints method to the default file with the default phase name. +// This works regardless of any Ideal Graph Visualizer flags set or not. +void igv_print() { + Compile::current()->igv_print_method_to_file(); +} + +// Same as igv_print() above but with a specified phase name. +void igv_print(const char* phase_name) { + Compile::current()->igv_print_method_to_file(phase_name); +} + +// Called from debugger. Prints method with the default phase name to the default network or the one specified with +// the network flags for the Ideal Graph Visualizer, or to the default file depending on the 'network' argument. +// This works regardless of any Ideal Graph Visualizer flags set or not. +void igv_print(bool network) { + if (network) { + Compile::current()->igv_print_method_to_network(); + } else { + Compile::current()->igv_print_method_to_file(); + } +} + +// Same as igv_print(bool network) above but with a specified phase name. +void igv_print(bool network, const char* phase_name) { + if (network) { + Compile::current()->igv_print_method_to_network(phase_name); + } else { + Compile::current()->igv_print_method_to_file(phase_name); + } +} + +// Called from debugger. Normal write to the default _printer. Only works if Ideal Graph Visualizer printing flags are set. +void igv_print_default() { + Compile::current()->print_method(PHASE_DEBUG, 0, 0); +} + +// Called from debugger, especially when replaying a trace in which the program state cannot be altered like with rr replay. +// A method is appended to an existing default file with the default phase name. This means that igv_append() must follow +// an earlier igv_print(*) call which sets up the file. This works regardless of any Ideal Graph Visualizer flags set or not. +void igv_append() { + Compile::current()->igv_print_method_to_file("Debug", true); +} + +// Same as igv_append() above but with a specified phase name. +void igv_append(const char* phase_name) { + Compile::current()->igv_print_method_to_file(phase_name, true); +} + +void Compile::igv_print_method_to_file(const char* phase_name, bool append) { + const char* file_name = "custom_debug.xml"; + if (_debug_file_printer == NULL) { + _debug_file_printer = new IdealGraphPrinter(C, file_name, append); + } else { + _debug_file_printer->update_compiled_method(C->method()); + } + tty->print_cr("Method %s to %s", append ? "appended" : "printed", file_name); + _debug_file_printer->print_method(phase_name, 0); +} + +void Compile::igv_print_method_to_network(const char* phase_name) { + if (_debug_network_printer == NULL) { + _debug_network_printer = new IdealGraphPrinter(C); + } else { + _debug_network_printer->update_compiled_method(C->method()); + } + tty->print_cr("Method printed over network stream to IGV"); + _debug_network_printer->print_method(phase_name, 0); +} +#endif + diff --git a/src/hotspot/share/opto/compile.hpp b/src/hotspot/share/opto/compile.hpp index 164bcfd45a1..5bdf9bb9a69 100644 --- a/src/hotspot/share/opto/compile.hpp +++ b/src/hotspot/share/opto/compile.hpp @@ -317,6 +317,8 @@ class Compile : public Phase { ConnectionGraph* _congraph; #ifndef PRODUCT IdealGraphPrinter* _printer; + static IdealGraphPrinter* _debug_file_printer; + static IdealGraphPrinter* _debug_network_printer; #endif @@ -639,9 +641,9 @@ class Compile : public Phase { if (should_print(level)) { char output[1024]; if (idx != 0) { - sprintf(output, "%s:%d", CompilerPhaseTypeHelper::to_string(cpt), idx); + jio_snprintf(output, sizeof(output), "%s:%d", CompilerPhaseTypeHelper::to_string(cpt), idx); } else { - sprintf(output, "%s", CompilerPhaseTypeHelper::to_string(cpt)); + jio_snprintf(output, sizeof(output), "%s", CompilerPhaseTypeHelper::to_string(cpt)); } _printer->print_method(output, level); } @@ -649,6 +651,13 @@ class Compile : public Phase { C->_latest_stage_start_counter.stamp(); } +#ifndef PRODUCT + void igv_print_method_to_file(const char* phase_name = "Debug", bool append = false); + void igv_print_method_to_network(const char* phase_name = "Debug"); + static IdealGraphPrinter* debug_file_printer() { return _debug_file_printer; } + static IdealGraphPrinter* debug_network_printer() { return _debug_network_printer; } +#endif + void end_method(int level = 1) { EventCompilerPhase event; if (event.should_commit()) { diff --git a/src/hotspot/share/opto/idealGraphPrinter.cpp b/src/hotspot/share/opto/idealGraphPrinter.cpp index 9d98c92ad7e..2c2fe061630 100644 --- a/src/hotspot/share/opto/idealGraphPrinter.cpp +++ b/src/hotspot/share/opto/idealGraphPrinter.cpp @@ -92,21 +92,47 @@ IdealGraphPrinter *IdealGraphPrinter::printer() { } void IdealGraphPrinter::clean_up() { - for (JavaThreadIteratorWithHandle jtiwh; JavaThread *p = jtiwh.next(); ) { + for (JavaThreadIteratorWithHandle jtiwh; JavaThread* p = jtiwh.next(); ) { if (p->is_Compiler_thread()) { - CompilerThread *c = (CompilerThread *)p; - IdealGraphPrinter *printer = c->ideal_graph_printer(); + CompilerThread* c = (CompilerThread*)p; + IdealGraphPrinter* printer = c->ideal_graph_printer(); if (printer) { delete printer; } c->set_ideal_graph_printer(NULL); } } + IdealGraphPrinter* debug_file_printer = Compile::debug_file_printer(); + if (debug_file_printer != NULL) { + delete debug_file_printer; + } + IdealGraphPrinter* debug_network_printer = Compile::debug_network_printer(); + if (debug_network_printer != NULL) { + delete debug_network_printer; + } } -// Constructor, either file or network output +// Either print methods to file specified with PrintIdealGraphFile or otherwise over the network to the IGV IdealGraphPrinter::IdealGraphPrinter() { + init(PrintIdealGraphFile, true, false); +} +// Either print methods to the specified file 'file_name' or if NULL over the network to the IGV. If 'append' +// is set, the next phase is directly appended to the specified file 'file_name'. This is useful when doing +// replay compilation with a tool like rr that cannot alter the current program state but only the file. +IdealGraphPrinter::IdealGraphPrinter(Compile* compile, const char* file_name, bool append) { + assert(!append || (append && file_name != NULL), "can only use append flag when printing to file"); + init(file_name, false, append); + C = compile; + if (append) { + // When directly appending the next graph, we only need to set _current_method and not set up a new method + _current_method = C->method(); + } else { + begin_method(); + } +} + +void IdealGraphPrinter::init(const char* file_name, bool use_multiple_files, bool append) { // By default dump both ins and outs since dead or unreachable code // needs to appear in the graph. There are also some special cases // in the mach where kill projections have no users but should @@ -117,60 +143,21 @@ IdealGraphPrinter::IdealGraphPrinter() { buffer[0] = 0; _depth = 0; _current_method = NULL; - assert(!_current_method, "current method must be initialized to NULL"); - _stream = NULL; + _network_stream = NULL; - if (PrintIdealGraphFile != NULL) { - ThreadCritical tc; - // User wants all output to go to files - if (_file_count != 0) { - ResourceMark rm; - stringStream st; - const char* dot = strrchr(PrintIdealGraphFile, '.'); - if (dot) { - st.write(PrintIdealGraphFile, dot - PrintIdealGraphFile); - st.print("%d%s", _file_count, dot); - } else { - st.print("%s%d", PrintIdealGraphFile, _file_count); - } - fileStream *stream = new (ResourceObj::C_HEAP, mtCompiler) fileStream(st.as_string()); - _output = stream; - } else { - fileStream *stream = new (ResourceObj::C_HEAP, mtCompiler) fileStream(PrintIdealGraphFile); - _output = stream; - } - _file_count++; + if (file_name != NULL) { + init_file_stream(file_name, use_multiple_files, append); } else { - _stream = new (ResourceObj::C_HEAP, mtCompiler) networkStream(); - - // Try to connect to visualizer - if (_stream->connect(PrintIdealGraphAddress, PrintIdealGraphPort)) { - char c = 0; - _stream->read(&c, 1); - if (c != 'y') { - tty->print_cr("Client available, but does not want to receive data!"); - _stream->close(); - delete _stream; - _stream = NULL; - return; - } - _output = _stream; - } else { - // It would be nice if we could shut down cleanly but it should - // be an error if we can't connect to the visualizer. - fatal("Couldn't connect to visualizer at %s:" INTX_FORMAT, - PrintIdealGraphAddress, PrintIdealGraphPort); - } + init_network_stream(); } - _xml = new (ResourceObj::C_HEAP, mtCompiler) xmlStream(_output); - - head(TOP_ELEMENT); + if (!append) { + head(TOP_ELEMENT); + } } // Destructor, close file or network stream IdealGraphPrinter::~IdealGraphPrinter() { - tail(TOP_ELEMENT); // tty->print_cr("Walk time: %d", (int)_walk_time.milliseconds()); @@ -182,12 +169,12 @@ IdealGraphPrinter::~IdealGraphPrinter() { _xml = NULL; } - if (_stream) { - delete _stream; - if (_stream == _output) { + if (_network_stream) { + delete _network_stream; + if (_network_stream == _output) { _output = NULL; } - _stream = NULL; + _network_stream = NULL; } if (_output) { @@ -285,12 +272,9 @@ void IdealGraphPrinter::print_method(ciMethod *method, int bci, InlineTree *tree } void IdealGraphPrinter::print_inline_tree(InlineTree *tree) { - - if (tree == NULL) return; - - ciMethod *method = tree->method(); - print_method(tree->method(), tree->caller_bci(), tree); - + if (tree != NULL) { + print_method(tree->method(), tree->caller_bci(), tree); + } } void IdealGraphPrinter::print_inlining() { @@ -342,9 +326,6 @@ void IdealGraphPrinter::begin_method() { // Has to be called whenever a method has finished compilation void IdealGraphPrinter::end_method() { - - nmethod* method = (nmethod*)this->_current_method->code(); - tail(GROUP_ELEMENT); _current_method = NULL; _xml->flush(); @@ -715,6 +696,61 @@ bool IdealGraphPrinter::should_print(int level) { return C->directive()->IGVPrintLevelOption >= level; } +void IdealGraphPrinter::init_file_stream(const char* file_name, bool use_multiple_files, bool append) { + ThreadCritical tc; + if (use_multiple_files && _file_count != 0) { + assert(!append, "append should only be used for debugging with a single file"); + ResourceMark rm; + stringStream st; + const char* dot = strrchr(file_name, '.'); + if (dot) { + st.write(file_name, dot - file_name); + st.print("%d%s", _file_count, dot); + } else { + st.print("%s%d", file_name, _file_count); + } + _output = new (ResourceObj::C_HEAP, mtCompiler) fileStream(st.as_string(), "w"); + } else { + _output = new (ResourceObj::C_HEAP, mtCompiler) fileStream(file_name, append ? "a" : "w"); + } + if (use_multiple_files) { + assert(!append, "append should only be used for debugging with a single file"); + _file_count++; + } +} + +void IdealGraphPrinter::init_network_stream() { + _network_stream = new (ResourceObj::C_HEAP, mtCompiler) networkStream(); + // Try to connect to visualizer + if (_network_stream->connect(PrintIdealGraphAddress, PrintIdealGraphPort)) { + char c = 0; + _network_stream->read(&c, 1); + if (c != 'y') { + tty->print_cr("Client available, but does not want to receive data!"); + _network_stream->close(); + delete _network_stream; + _network_stream = NULL; + return; + } + _output = _network_stream; + } else { + // It would be nice if we could shut down cleanly but it should + // be an error if we can't connect to the visualizer. + fatal("Couldn't connect to visualizer at %s:" INTX_FORMAT, + PrintIdealGraphAddress, PrintIdealGraphPort); + } +} + +void IdealGraphPrinter::update_compiled_method(ciMethod* current_method) { + assert(C != NULL, "must already be set"); + if (current_method != _current_method) { + // If a different method, end the old and begin with the new one. + end_method(); + _current_method = NULL; + begin_method(); + } +} + extern const char *NodeClassNames[]; #endif diff --git a/src/hotspot/share/opto/idealGraphPrinter.hpp b/src/hotspot/share/opto/idealGraphPrinter.hpp index a7dbe882255..71c1bb9a964 100644 --- a/src/hotspot/share/opto/idealGraphPrinter.hpp +++ b/src/hotspot/share/opto/idealGraphPrinter.hpp @@ -81,8 +81,8 @@ class IdealGraphPrinter : public CHeapObj { static const char *METHOD_SHORT_NAME_PROPERTY; static const char *ASSEMBLY_ELEMENT; - static int _file_count; - networkStream *_stream; + static int _file_count; + networkStream *_network_stream; xmlStream *_xml; outputStream *_output; ciMethod *_current_method; @@ -108,11 +108,14 @@ class IdealGraphPrinter : public CHeapObj { void tail(const char *name); void head(const char *name); void text(const char *s); + void init(const char* file_name, bool use_multiple_files, bool append); + void init_file_stream(const char* file_name, bool use_multiple_files, bool append); + void init_network_stream(); IdealGraphPrinter(); ~IdealGraphPrinter(); public: - + IdealGraphPrinter(Compile* compile, const char* file_name = NULL, bool append = false); static void clean_up(); static IdealGraphPrinter *printer(); @@ -125,6 +128,7 @@ class IdealGraphPrinter : public CHeapObj { void print(const char *name, Node *root); bool should_print(int level); void set_compile(Compile* compile) {C = compile; } + void update_compiled_method(ciMethod* current_method); }; #endif diff --git a/src/hotspot/share/opto/phasetype.hpp b/src/hotspot/share/opto/phasetype.hpp index d5b69d41e97..fcfe894182a 100644 --- a/src/hotspot/share/opto/phasetype.hpp +++ b/src/hotspot/share/opto/phasetype.hpp @@ -59,6 +59,7 @@ enum CompilerPhaseType { PHASE_ADD_UNSAFE_BARRIER, PHASE_END, PHASE_FAILURE, + PHASE_DEBUG, PHASE_NUM_TYPES }; @@ -100,6 +101,7 @@ class CompilerPhaseTypeHelper { case PHASE_ADD_UNSAFE_BARRIER: return "Add barrier to unsafe op"; case PHASE_END: return "End"; case PHASE_FAILURE: return "Failure"; + case PHASE_DEBUG: return "Debug"; default: ShouldNotReachHere(); return NULL; From 39670b0e57fedf0c7ebccfc74a9bedb21ee03d7b Mon Sep 17 00:00:00 2001 From: Harold Seigel Date: Mon, 11 May 2020 15:00:16 +0000 Subject: [PATCH 004/143] 8241934: Simplify parse_stream() and remove has_class_mirror_holder_cld() Added paramter to register_loader() which allowed removing of has_class_mirror_holder_cld() Reviewed-by: coleenp, lfoltan --- .../share/classfile/classLoaderData.cpp | 6 --- .../share/classfile/classLoaderData.hpp | 1 - .../share/classfile/classLoaderDataGraph.hpp | 2 +- .../share/classfile/systemDictionary.cpp | 39 +++++++++---------- .../share/classfile/systemDictionary.hpp | 2 +- 5 files changed, 20 insertions(+), 30 deletions(-) diff --git a/src/hotspot/share/classfile/classLoaderData.cpp b/src/hotspot/share/classfile/classLoaderData.cpp index 43e332eab13..c70accfb7e3 100644 --- a/src/hotspot/share/classfile/classLoaderData.cpp +++ b/src/hotspot/share/classfile/classLoaderData.cpp @@ -877,12 +877,6 @@ void ClassLoaderData::free_deallocate_list_C_heap_structures() { } } -// These CLDs are to contain non-strong hidden classes or unsafe anonymous classes used for JSR292 -ClassLoaderData* ClassLoaderData::has_class_mirror_holder_cld(Handle loader) { - // Add a new class loader data to the graph. - return ClassLoaderDataGraph::add(loader, true); -} - // Caller needs ResourceMark // If the class loader's _name has not been explicitly set, the class loader's // qualified class name is returned. diff --git a/src/hotspot/share/classfile/classLoaderData.hpp b/src/hotspot/share/classfile/classLoaderData.hpp index 1b898abcc3d..651cec764f5 100644 --- a/src/hotspot/share/classfile/classLoaderData.hpp +++ b/src/hotspot/share/classfile/classLoaderData.hpp @@ -316,7 +316,6 @@ class ClassLoaderData : public CHeapObj { static ClassLoaderData* class_loader_data(oop loader); static ClassLoaderData* class_loader_data_or_null(oop loader); - static ClassLoaderData* has_class_mirror_holder_cld(Handle loader); // Returns Klass* of associated class loader, or NULL if associated loader is 'bootstrap'. // Also works if unloading. diff --git a/src/hotspot/share/classfile/classLoaderDataGraph.hpp b/src/hotspot/share/classfile/classLoaderDataGraph.hpp index ef466e102fd..4251afab3dc 100644 --- a/src/hotspot/share/classfile/classLoaderDataGraph.hpp +++ b/src/hotspot/share/classfile/classLoaderDataGraph.hpp @@ -57,10 +57,10 @@ class ClassLoaderDataGraph : public AllStatic { static volatile size_t _num_array_classes; static ClassLoaderData* add_to_graph(Handle class_loader, bool has_class_mirror_holder); - static ClassLoaderData* add(Handle class_loader, bool has_class_mirror_holder); public: static ClassLoaderData* find_or_create(Handle class_loader); + static ClassLoaderData* add(Handle class_loader, bool has_class_mirror_holder); static void clean_module_and_package_info(); static void purge(); static void clear_claimed_marks(); diff --git a/src/hotspot/share/classfile/systemDictionary.cpp b/src/hotspot/share/classfile/systemDictionary.cpp index b7fb8bc2d86..4c9e01d998e 100644 --- a/src/hotspot/share/classfile/systemDictionary.cpp +++ b/src/hotspot/share/classfile/systemDictionary.cpp @@ -182,9 +182,14 @@ void SystemDictionary::compute_java_loaders(TRAPS) { _java_platform_loader = (oop)result.get_jobject(); } -ClassLoaderData* SystemDictionary::register_loader(Handle class_loader) { - if (class_loader.is_null()) return ClassLoaderData::the_null_class_loader_data(); - return ClassLoaderDataGraph::find_or_create(class_loader); +ClassLoaderData* SystemDictionary::register_loader(Handle class_loader, bool create_mirror_cld) { + if (create_mirror_cld) { + // Add a new class loader data to the graph. + return ClassLoaderDataGraph::add(class_loader, true); + } else { + return (class_loader() == NULL) ? ClassLoaderData::the_null_class_loader_data() : + ClassLoaderDataGraph::find_or_create(class_loader); + } } // ---------------------------------------------------------------------------- @@ -1031,27 +1036,19 @@ InstanceKlass* SystemDictionary::parse_stream(Symbol* class_name, TRAPS) { EventClassLoad class_load_start_event; - ClassLoaderData* loader_data; - bool is_unsafe_anon_class = cl_info.unsafe_anonymous_host() != NULL; - if (is_unsafe_anon_class) { - // - for unsafe anonymous class: create a new CLD whith a class holder that uses - // the same class loader as the unsafe_anonymous_host. - guarantee(cl_info.unsafe_anonymous_host()->class_loader() == class_loader(), - "should be the same"); - loader_data = ClassLoaderData::has_class_mirror_holder_cld(class_loader); - } else if (cl_info.is_hidden()) { - // - for hidden classes that are not strong: create a new CLD that has a class holder and - // whose loader is the Lookup class' loader. - // - for hidden class: add the class to the Lookup class' loader's CLD. - if (!cl_info.is_strong_hidden()) { - loader_data = ClassLoaderData::has_class_mirror_holder_cld(class_loader); - } else { - // This hidden class goes into the regular CLD pool for this loader. - loader_data = register_loader(class_loader); - } + // - for unsafe anonymous class: create a new CLD whith a class holder that uses + // the same class loader as the unsafe_anonymous_host. + // - for hidden classes that are not strong: create a new CLD that has a class holder and + // whose loader is the Lookup class's loader. + // - for hidden class: add the class to the Lookup class's loader's CLD. + if (is_unsafe_anon_class || cl_info.is_hidden()) { + guarantee(!is_unsafe_anon_class || cl_info.unsafe_anonymous_host()->class_loader() == class_loader(), + "should be NULL or the same"); + bool create_mirror_cld = is_unsafe_anon_class || !cl_info.is_strong_hidden(); + loader_data = register_loader(class_loader, create_mirror_cld); } else { loader_data = ClassLoaderData::class_loader_data(class_loader()); } diff --git a/src/hotspot/share/classfile/systemDictionary.hpp b/src/hotspot/share/classfile/systemDictionary.hpp index 65882854539..531434078b4 100644 --- a/src/hotspot/share/classfile/systemDictionary.hpp +++ b/src/hotspot/share/classfile/systemDictionary.hpp @@ -482,7 +482,7 @@ public: static void compute_java_loaders(TRAPS); // Register a new class loader - static ClassLoaderData* register_loader(Handle class_loader); + static ClassLoaderData* register_loader(Handle class_loader, bool create_mirror_cld = false); protected: // Mirrors for primitive classes (created eagerly) static oop check_mirror(oop m) { From 68e55bdf72f82ecf48041dc34a82723d14622d84 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Mon, 11 May 2020 18:33:18 +0200 Subject: [PATCH 005/143] 8244730: Shenandoah: gc/shenandoah/options/TestHeuristicsUnlock.java should only verify the heuristics Reviewed-by: rkennke --- .../gc/shenandoah/options/TestHeuristicsUnlock.java | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/test/hotspot/jtreg/gc/shenandoah/options/TestHeuristicsUnlock.java b/test/hotspot/jtreg/gc/shenandoah/options/TestHeuristicsUnlock.java index 24bd5f73510..16024bcbbe2 100644 --- a/test/hotspot/jtreg/gc/shenandoah/options/TestHeuristicsUnlock.java +++ b/test/hotspot/jtreg/gc/shenandoah/options/TestHeuristicsUnlock.java @@ -45,14 +45,10 @@ public class TestHeuristicsUnlock { } public static void main(String[] args) throws Exception { - testWith("-XX:ShenandoahGCHeuristics=adaptive", Mode.PRODUCT); - testWith("-XX:ShenandoahGCHeuristics=static", Mode.PRODUCT); - testWith("-XX:ShenandoahGCHeuristics=compact", Mode.PRODUCT); - - testWith("-XX:ShenandoahGCMode=iu", Mode.EXPERIMENTAL); - + testWith("-XX:ShenandoahGCHeuristics=adaptive", Mode.PRODUCT); + testWith("-XX:ShenandoahGCHeuristics=static", Mode.PRODUCT); + testWith("-XX:ShenandoahGCHeuristics=compact", Mode.PRODUCT); testWith("-XX:ShenandoahGCHeuristics=aggressive", Mode.DIAGNOSTIC); - testWith("-XX:ShenandoahGCHeuristics=passive", Mode.DIAGNOSTIC); } private static void testWith(String h, Mode mode) throws Exception { From f37b72c0ee0b65beae7db35ba59fb266c3e69c5d Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Mon, 11 May 2020 18:33:24 +0200 Subject: [PATCH 006/143] 8244732: Shenandoah: move heuristics code to gc/shenandoah/heuristics Reviewed-by: rkennke --- .../gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp | 2 +- .../x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp | 2 +- .../share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp | 2 +- .../shenandoah/heuristics/shenandoahAdaptiveHeuristics.hpp | 2 +- .../heuristics/shenandoahAggressiveHeuristics.hpp | 2 +- .../shenandoah/heuristics/shenandoahCompactHeuristics.hpp | 2 +- .../gc/shenandoah/{ => heuristics}/shenandoahHeuristics.cpp | 2 +- .../gc/shenandoah/{ => heuristics}/shenandoahHeuristics.hpp | 6 +++--- .../shenandoah/heuristics/shenandoahPassiveHeuristics.hpp | 2 +- .../gc/shenandoah/heuristics/shenandoahStaticHeuristics.hpp | 2 +- src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp | 2 +- src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp | 2 +- src/hotspot/share/gc/shenandoah/shenandoahMarkCompact.cpp | 2 +- src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.cpp | 2 +- .../share/gc/shenandoah/shenandoahRootProcessor.inline.hpp | 2 +- src/hotspot/share/gc/shenandoah/shenandoahUtils.cpp | 2 +- 16 files changed, 18 insertions(+), 18 deletions(-) rename src/hotspot/share/gc/shenandoah/{ => heuristics}/shenandoahHeuristics.cpp (99%) rename src/hotspot/share/gc/shenandoah/{ => heuristics}/shenandoahHeuristics.hpp (96%) diff --git a/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp index 795966754d0..9bdaf586505 100644 --- a/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp @@ -28,9 +28,9 @@ #include "gc/shenandoah/shenandoahForwarding.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" #include "gc/shenandoah/shenandoahHeapRegion.hpp" -#include "gc/shenandoah/shenandoahHeuristics.hpp" #include "gc/shenandoah/shenandoahRuntime.hpp" #include "gc/shenandoah/shenandoahThreadLocalData.hpp" +#include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp" #include "interpreter/interpreter.hpp" #include "interpreter/interp_masm.hpp" #include "runtime/sharedRuntime.hpp" diff --git a/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp b/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp index 03c45fc11a4..d5a99a73ff0 100644 --- a/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp @@ -28,9 +28,9 @@ #include "gc/shenandoah/shenandoahForwarding.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" #include "gc/shenandoah/shenandoahHeapRegion.hpp" -#include "gc/shenandoah/shenandoahHeuristics.hpp" #include "gc/shenandoah/shenandoahRuntime.hpp" #include "gc/shenandoah/shenandoahThreadLocalData.hpp" +#include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp" #include "interpreter/interpreter.hpp" #include "interpreter/interp_masm.hpp" #include "runtime/sharedRuntime.hpp" diff --git a/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp b/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp index f9daff6d616..0951bff5d53 100644 --- a/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp +++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp @@ -27,11 +27,11 @@ #include "gc/shenandoah/shenandoahBarrierSet.hpp" #include "gc/shenandoah/shenandoahForwarding.hpp" #include "gc/shenandoah/shenandoahHeap.hpp" -#include "gc/shenandoah/shenandoahHeuristics.hpp" #include "gc/shenandoah/shenandoahRuntime.hpp" #include "gc/shenandoah/shenandoahThreadLocalData.hpp" #include "gc/shenandoah/c2/shenandoahBarrierSetC2.hpp" #include "gc/shenandoah/c2/shenandoahSupport.hpp" +#include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp" #include "opto/arraycopynode.hpp" #include "opto/escape.hpp" #include "opto/graphKit.hpp" diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.hpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.hpp index 9ef14d51dee..1a05275c966 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.hpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.hpp @@ -25,7 +25,7 @@ #ifndef SHARE_GC_SHENANDOAH_HEURISTICS_SHENANDOAHADAPTIVEHEURISTICS_HPP #define SHARE_GC_SHENANDOAH_HEURISTICS_SHENANDOAHADAPTIVEHEURISTICS_HPP -#include "gc/shenandoah/shenandoahHeuristics.hpp" +#include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp" #include "gc/shenandoah/shenandoahPhaseTimings.hpp" #include "utilities/numberSeq.hpp" diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.hpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.hpp index d27de82a52e..6239aa1c3f3 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.hpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.hpp @@ -25,7 +25,7 @@ #ifndef SHARE_GC_SHENANDOAH_HEURISTICS_SHENANDOAHAGGRESSIVEHEURISTICS_HPP #define SHARE_GC_SHENANDOAH_HEURISTICS_SHENANDOAHAGGRESSIVEHEURISTICS_HPP -#include "gc/shenandoah/shenandoahHeuristics.hpp" +#include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp" class ShenandoahAggressiveHeuristics : public ShenandoahHeuristics { public: diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahCompactHeuristics.hpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahCompactHeuristics.hpp index a37d84fa95a..a32638ff11a 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahCompactHeuristics.hpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahCompactHeuristics.hpp @@ -25,7 +25,7 @@ #ifndef SHARE_GC_SHENANDOAH_HEURISTICS_SHENANDOAHCOMPACTHEURISTICS_HPP #define SHARE_GC_SHENANDOAH_HEURISTICS_SHENANDOAHCOMPACTHEURISTICS_HPP -#include "gc/shenandoah/shenandoahHeuristics.hpp" +#include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp" class ShenandoahCompactHeuristics : public ShenandoahHeuristics { public: diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeuristics.cpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.cpp similarity index 99% rename from src/hotspot/share/gc/shenandoah/shenandoahHeuristics.cpp rename to src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.cpp index de9da0902fe..b64bf975ad6 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeuristics.cpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.cpp @@ -29,8 +29,8 @@ #include "gc/shenandoah/shenandoahCollectorPolicy.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" #include "gc/shenandoah/shenandoahHeapRegion.inline.hpp" -#include "gc/shenandoah/shenandoahHeuristics.hpp" #include "gc/shenandoah/shenandoahMarkingContext.inline.hpp" +#include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp" #include "logging/log.hpp" #include "logging/logTag.hpp" diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeuristics.hpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.hpp similarity index 96% rename from src/hotspot/share/gc/shenandoah/shenandoahHeuristics.hpp rename to src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.hpp index a6d321833f8..573b2585ce0 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeuristics.hpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.hpp @@ -22,8 +22,8 @@ * */ -#ifndef SHARE_GC_SHENANDOAH_SHENANDOAHHEURISTICS_HPP -#define SHARE_GC_SHENANDOAH_SHENANDOAHHEURISTICS_HPP +#ifndef SHARE_GC_SHENANDOAH_HEURISTICS_SHENANDOAHHEURISTICS_HPP +#define SHARE_GC_SHENANDOAH_HEURISTICS_SHENANDOAHHEURISTICS_HPP #include "gc/shenandoah/shenandoahHeap.hpp" #include "gc/shenandoah/shenandoahPhaseTimings.hpp" @@ -135,4 +135,4 @@ public: double time_since_last_gc() const; }; -#endif // SHARE_GC_SHENANDOAH_SHENANDOAHHEURISTICS_HPP +#endif // SHARE_GC_SHENANDOAH_HEURISTICS_SHENANDOAHHEURISTICS_HPP diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahPassiveHeuristics.hpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahPassiveHeuristics.hpp index 4cd94ca1363..09512a7be43 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahPassiveHeuristics.hpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahPassiveHeuristics.hpp @@ -25,7 +25,7 @@ #ifndef SHARE_GC_SHENANDOAH_HEURISTICS_SHENANDOAHPASSIVEHEURISTICS_HPP #define SHARE_GC_SHENANDOAH_HEURISTICS_SHENANDOAHPASSIVEHEURISTICS_HPP -#include "gc/shenandoah/shenandoahHeuristics.hpp" +#include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp" class ShenandoahPassiveHeuristics : public ShenandoahHeuristics { public: diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahStaticHeuristics.hpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahStaticHeuristics.hpp index 8779a0e6150..1e53d33b76e 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahStaticHeuristics.hpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahStaticHeuristics.hpp @@ -25,7 +25,7 @@ #ifndef SHARE_GC_SHENANDOAH_HEURISTICS_SHENANDOAHSTATICHEURISTICS_HPP #define SHARE_GC_SHENANDOAH_HEURISTICS_SHENANDOAHSTATICHEURISTICS_HPP -#include "gc/shenandoah/shenandoahHeuristics.hpp" +#include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp" class ShenandoahStaticHeuristics : public ShenandoahHeuristics { public: diff --git a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp index b8f03440e03..4927e452014 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp @@ -31,7 +31,7 @@ #include "gc/shenandoah/shenandoahCollectorPolicy.hpp" #include "gc/shenandoah/shenandoahConcurrentRoots.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" -#include "gc/shenandoah/shenandoahHeuristics.hpp" +#include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp" #include "memory/iterator.inline.hpp" #include "runtime/interfaceSupport.inline.hpp" #ifdef COMPILER1 diff --git a/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp b/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp index 5c37f8bf86b..47584b80e49 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp @@ -30,12 +30,12 @@ #include "gc/shenandoah/shenandoahFreeSet.hpp" #include "gc/shenandoah/shenandoahPhaseTimings.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" -#include "gc/shenandoah/shenandoahHeuristics.hpp" #include "gc/shenandoah/shenandoahMonitoringSupport.hpp" #include "gc/shenandoah/shenandoahRootProcessor.inline.hpp" #include "gc/shenandoah/shenandoahUtils.hpp" #include "gc/shenandoah/shenandoahVMOperations.hpp" #include "gc/shenandoah/shenandoahWorkerPolicy.hpp" +#include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp" #include "memory/iterator.hpp" #include "memory/universe.hpp" #include "runtime/atomic.hpp" diff --git a/src/hotspot/share/gc/shenandoah/shenandoahMarkCompact.cpp b/src/hotspot/share/gc/shenandoah/shenandoahMarkCompact.cpp index 970c2988def..1566057c3ad 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahMarkCompact.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahMarkCompact.cpp @@ -37,7 +37,6 @@ #include "gc/shenandoah/shenandoahHeapRegionSet.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" #include "gc/shenandoah/shenandoahHeapRegion.inline.hpp" -#include "gc/shenandoah/shenandoahHeuristics.hpp" #include "gc/shenandoah/shenandoahMarkingContext.inline.hpp" #include "gc/shenandoah/shenandoahRootProcessor.inline.hpp" #include "gc/shenandoah/shenandoahTaskqueue.inline.hpp" @@ -45,6 +44,7 @@ #include "gc/shenandoah/shenandoahVerifier.hpp" #include "gc/shenandoah/shenandoahVMOperations.hpp" #include "gc/shenandoah/shenandoahWorkerPolicy.hpp" +#include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp" #include "memory/metaspace.hpp" #include "memory/universe.hpp" #include "oops/compressedOops.inline.hpp" diff --git a/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.cpp b/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.cpp index af6ed59b95d..ddfd1e66737 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.cpp @@ -28,8 +28,8 @@ #include "gc/shenandoah/shenandoahCollectorPolicy.hpp" #include "gc/shenandoah/shenandoahPhaseTimings.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" -#include "gc/shenandoah/shenandoahHeuristics.hpp" #include "gc/shenandoah/shenandoahUtils.hpp" +#include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp" #include "runtime/orderAccess.hpp" #include "utilities/ostream.hpp" diff --git a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp index 33da3b00ea8..28e1efb1986 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp @@ -31,11 +31,11 @@ #include "gc/shared/oopStorageParState.inline.hpp" #include "gc/shenandoah/shenandoahClosures.inline.hpp" #include "gc/shenandoah/shenandoahConcurrentRoots.hpp" -#include "gc/shenandoah/shenandoahHeuristics.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" #include "gc/shenandoah/shenandoahPhaseTimings.hpp" #include "gc/shenandoah/shenandoahRootProcessor.hpp" #include "gc/shenandoah/shenandoahUtils.hpp" +#include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp" #include "memory/resourceArea.hpp" #include "prims/resolvedMethodTable.hpp" #include "runtime/safepoint.hpp" diff --git a/src/hotspot/share/gc/shenandoah/shenandoahUtils.cpp b/src/hotspot/share/gc/shenandoah/shenandoahUtils.cpp index 5fd2d933240..726a1022392 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahUtils.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahUtils.cpp @@ -31,8 +31,8 @@ #include "gc/shenandoah/shenandoahCollectorPolicy.hpp" #include "gc/shenandoah/shenandoahMarkCompact.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" -#include "gc/shenandoah/shenandoahHeuristics.hpp" #include "gc/shenandoah/shenandoahUtils.hpp" +#include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp" #include "utilities/debug.hpp" ShenandoahPhaseTimings::Phase ShenandoahTimingsTracker::_current_phase = ShenandoahPhaseTimings::_invalid_phase; From e3138f8cba92fcc072f0973a276c25fb57bec52d Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Mon, 11 May 2020 18:33:33 +0200 Subject: [PATCH 007/143] 8244737: Shenandoah: move mode code to gc/shenandoah/mode Reviewed-by: rkennke --- .../share/gc/shenandoah/{ => mode}/shenandoahIUMode.cpp | 2 +- .../share/gc/shenandoah/{ => mode}/shenandoahIUMode.hpp | 8 ++++---- .../share/gc/shenandoah/{ => mode}/shenandoahMode.hpp | 6 +++--- .../gc/shenandoah/{ => mode}/shenandoahNormalMode.cpp | 2 +- .../gc/shenandoah/{ => mode}/shenandoahNormalMode.hpp | 8 ++++---- .../gc/shenandoah/{ => mode}/shenandoahPassiveMode.cpp | 2 +- .../gc/shenandoah/{ => mode}/shenandoahPassiveMode.hpp | 8 ++++---- src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp | 6 +++--- 8 files changed, 21 insertions(+), 21 deletions(-) rename src/hotspot/share/gc/shenandoah/{ => mode}/shenandoahIUMode.cpp (97%) rename src/hotspot/share/gc/shenandoah/{ => mode}/shenandoahIUMode.hpp (86%) rename src/hotspot/share/gc/shenandoah/{ => mode}/shenandoahMode.hpp (93%) rename src/hotspot/share/gc/shenandoah/{ => mode}/shenandoahNormalMode.cpp (98%) rename src/hotspot/share/gc/shenandoah/{ => mode}/shenandoahNormalMode.hpp (86%) rename src/hotspot/share/gc/shenandoah/{ => mode}/shenandoahPassiveMode.cpp (97%) rename src/hotspot/share/gc/shenandoah/{ => mode}/shenandoahPassiveMode.hpp (85%) diff --git a/src/hotspot/share/gc/shenandoah/shenandoahIUMode.cpp b/src/hotspot/share/gc/shenandoah/mode/shenandoahIUMode.cpp similarity index 97% rename from src/hotspot/share/gc/shenandoah/shenandoahIUMode.cpp rename to src/hotspot/share/gc/shenandoah/mode/shenandoahIUMode.cpp index df6fb3d4e28..b31d475b495 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahIUMode.cpp +++ b/src/hotspot/share/gc/shenandoah/mode/shenandoahIUMode.cpp @@ -24,11 +24,11 @@ #include "precompiled.hpp" #include "gc/shenandoah/shenandoahConcurrentRoots.hpp" -#include "gc/shenandoah/shenandoahIUMode.hpp" #include "gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.hpp" #include "gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.hpp" #include "gc/shenandoah/heuristics/shenandoahCompactHeuristics.hpp" #include "gc/shenandoah/heuristics/shenandoahStaticHeuristics.hpp" +#include "gc/shenandoah/mode/shenandoahIUMode.hpp" #include "logging/log.hpp" #include "logging/logTag.hpp" diff --git a/src/hotspot/share/gc/shenandoah/shenandoahIUMode.hpp b/src/hotspot/share/gc/shenandoah/mode/shenandoahIUMode.hpp similarity index 86% rename from src/hotspot/share/gc/shenandoah/shenandoahIUMode.hpp rename to src/hotspot/share/gc/shenandoah/mode/shenandoahIUMode.hpp index 9b145e99941..95fbee8343d 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahIUMode.hpp +++ b/src/hotspot/share/gc/shenandoah/mode/shenandoahIUMode.hpp @@ -22,10 +22,10 @@ * */ -#ifndef SHARE_GC_SHENANDOAH_SHENANDOAHIUMODE_HPP -#define SHARE_GC_SHENANDOAH_SHENANDOAHIUMODE_HPP +#ifndef SHARE_GC_SHENANDOAH_MODE_SHENANDOAHIUMODE_HPP +#define SHARE_GC_SHENANDOAH_MODE_SHENANDOAHIUMODE_HPP -#include "gc/shenandoah/shenandoahNormalMode.hpp" +#include "gc/shenandoah/mode/shenandoahNormalMode.hpp" class ShenandoahHeuristics; @@ -38,4 +38,4 @@ public: virtual bool is_experimental() { return true; } }; -#endif // SHARE_GC_SHENANDOAH_SHENANDOAHIUMODE_HPP +#endif // SHARE_GC_SHENANDOAH_MODE_SHENANDOAHIUMODE_HPP diff --git a/src/hotspot/share/gc/shenandoah/shenandoahMode.hpp b/src/hotspot/share/gc/shenandoah/mode/shenandoahMode.hpp similarity index 93% rename from src/hotspot/share/gc/shenandoah/shenandoahMode.hpp rename to src/hotspot/share/gc/shenandoah/mode/shenandoahMode.hpp index 2c2104aabfd..5af6fa826d5 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahMode.hpp +++ b/src/hotspot/share/gc/shenandoah/mode/shenandoahMode.hpp @@ -22,8 +22,8 @@ * */ -#ifndef SHARE_GC_SHENANDOAH_SHENANDOAHMODE_HPP -#define SHARE_GC_SHENANDOAH_SHENANDOAHMODE_HPP +#ifndef SHARE_GC_SHENANDOAH_MODE_SHENANDOAHMODE_HPP +#define SHARE_GC_SHENANDOAH_MODE_SHENANDOAHMODE_HPP #include "memory/allocation.hpp" @@ -54,4 +54,4 @@ public: virtual bool is_experimental() = 0; }; -#endif // SHARE_GC_SHENANDOAH_SHENANDOAHMODE_HPP +#endif // SHARE_GC_SHENANDOAH_MODE_SHENANDOAHMODE_HPP diff --git a/src/hotspot/share/gc/shenandoah/shenandoahNormalMode.cpp b/src/hotspot/share/gc/shenandoah/mode/shenandoahNormalMode.cpp similarity index 98% rename from src/hotspot/share/gc/shenandoah/shenandoahNormalMode.cpp rename to src/hotspot/share/gc/shenandoah/mode/shenandoahNormalMode.cpp index 03e4b9dc4e9..c21ecad3860 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahNormalMode.cpp +++ b/src/hotspot/share/gc/shenandoah/mode/shenandoahNormalMode.cpp @@ -24,11 +24,11 @@ #include "precompiled.hpp" #include "gc/shenandoah/shenandoahConcurrentRoots.hpp" -#include "gc/shenandoah/shenandoahNormalMode.hpp" #include "gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.hpp" #include "gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.hpp" #include "gc/shenandoah/heuristics/shenandoahCompactHeuristics.hpp" #include "gc/shenandoah/heuristics/shenandoahStaticHeuristics.hpp" +#include "gc/shenandoah/mode/shenandoahNormalMode.hpp" #include "logging/log.hpp" #include "logging/logTag.hpp" diff --git a/src/hotspot/share/gc/shenandoah/shenandoahNormalMode.hpp b/src/hotspot/share/gc/shenandoah/mode/shenandoahNormalMode.hpp similarity index 86% rename from src/hotspot/share/gc/shenandoah/shenandoahNormalMode.hpp rename to src/hotspot/share/gc/shenandoah/mode/shenandoahNormalMode.hpp index 3758477dc77..8f6275773f9 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahNormalMode.hpp +++ b/src/hotspot/share/gc/shenandoah/mode/shenandoahNormalMode.hpp @@ -22,10 +22,10 @@ * */ -#ifndef SHARE_GC_SHENANDOAH_SHENANDOAHNORMALMODE_HPP -#define SHARE_GC_SHENANDOAH_SHENANDOAHNORMALMODE_HPP +#ifndef SHARE_GC_SHENANDOAH_MODE_SHENANDOAHNORMALMODE_HPP +#define SHARE_GC_SHENANDOAH_MODE_SHENANDOAHNORMALMODE_HPP -#include "gc/shenandoah/shenandoahMode.hpp" +#include "gc/shenandoah/mode/shenandoahMode.hpp" class ShenandoahHeuristics; @@ -38,4 +38,4 @@ public: virtual bool is_experimental() { return false; } }; -#endif // SHARE_GC_SHENANDOAH_SHENANDOAHNORMALMODE_HPP +#endif // SHARE_GC_SHENANDOAH_MODE_SHENANDOAHNORMALMODE_HPP diff --git a/src/hotspot/share/gc/shenandoah/shenandoahPassiveMode.cpp b/src/hotspot/share/gc/shenandoah/mode/shenandoahPassiveMode.cpp similarity index 97% rename from src/hotspot/share/gc/shenandoah/shenandoahPassiveMode.cpp rename to src/hotspot/share/gc/shenandoah/mode/shenandoahPassiveMode.cpp index 1879496dc00..1d5005f70b4 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahPassiveMode.cpp +++ b/src/hotspot/share/gc/shenandoah/mode/shenandoahPassiveMode.cpp @@ -23,8 +23,8 @@ */ #include "precompiled.hpp" -#include "gc/shenandoah/shenandoahPassiveMode.hpp" #include "gc/shenandoah/heuristics/shenandoahPassiveHeuristics.hpp" +#include "gc/shenandoah/mode/shenandoahPassiveMode.hpp" #include "logging/log.hpp" #include "logging/logTag.hpp" diff --git a/src/hotspot/share/gc/shenandoah/shenandoahPassiveMode.hpp b/src/hotspot/share/gc/shenandoah/mode/shenandoahPassiveMode.hpp similarity index 85% rename from src/hotspot/share/gc/shenandoah/shenandoahPassiveMode.hpp rename to src/hotspot/share/gc/shenandoah/mode/shenandoahPassiveMode.hpp index 850d3f31d04..c485f11595d 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahPassiveMode.hpp +++ b/src/hotspot/share/gc/shenandoah/mode/shenandoahPassiveMode.hpp @@ -22,10 +22,10 @@ * */ -#ifndef SHARE_GC_SHENANDOAH_SHENANDOAHPASSIVEMODE_HPP -#define SHARE_GC_SHENANDOAH_SHENANDOAHPASSIVEMODE_HPP +#ifndef SHARE_GC_SHENANDOAH_MODE_SHENANDOAHPASSIVEMODE_HPP +#define SHARE_GC_SHENANDOAH_MODE_SHENANDOAHPASSIVEMODE_HPP -#include "gc/shenandoah/shenandoahNormalMode.hpp" +#include "gc/shenandoah/mode/shenandoahNormalMode.hpp" class ShenandoahPassiveMode : public ShenandoahNormalMode { public: @@ -37,4 +37,4 @@ public: virtual bool is_experimental() { return false; } }; -#endif // SHARE_GC_SHENANDOAH_SHENANDOAHNORMALMODE_HPP +#endif // SHARE_GC_SHENANDOAH_MODE_SHENANDOAHPASSIVEMODE_HPP diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp index 12ef8dff7f4..be29c3ea749 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp @@ -46,18 +46,15 @@ #include "gc/shenandoah/shenandoahHeap.inline.hpp" #include "gc/shenandoah/shenandoahHeapRegion.inline.hpp" #include "gc/shenandoah/shenandoahHeapRegionSet.hpp" -#include "gc/shenandoah/shenandoahIUMode.hpp" #include "gc/shenandoah/shenandoahMarkCompact.hpp" #include "gc/shenandoah/shenandoahMarkingContext.inline.hpp" #include "gc/shenandoah/shenandoahMemoryPool.hpp" #include "gc/shenandoah/shenandoahMetrics.hpp" #include "gc/shenandoah/shenandoahMonitoringSupport.hpp" -#include "gc/shenandoah/shenandoahNormalMode.hpp" #include "gc/shenandoah/shenandoahOopClosures.inline.hpp" #include "gc/shenandoah/shenandoahPacer.inline.hpp" #include "gc/shenandoah/shenandoahPadding.hpp" #include "gc/shenandoah/shenandoahParallelCleaning.inline.hpp" -#include "gc/shenandoah/shenandoahPassiveMode.hpp" #include "gc/shenandoah/shenandoahRootProcessor.inline.hpp" #include "gc/shenandoah/shenandoahStringDedup.hpp" #include "gc/shenandoah/shenandoahTaskqueue.hpp" @@ -67,6 +64,9 @@ #include "gc/shenandoah/shenandoahVMOperations.hpp" #include "gc/shenandoah/shenandoahWorkGroup.hpp" #include "gc/shenandoah/shenandoahWorkerPolicy.hpp" +#include "gc/shenandoah/mode/shenandoahIUMode.hpp" +#include "gc/shenandoah/mode/shenandoahNormalMode.hpp" +#include "gc/shenandoah/mode/shenandoahPassiveMode.hpp" #if INCLUDE_JFR #include "gc/shenandoah/shenandoahJfrSupport.hpp" #endif From 4016667300a9b46402d0fd8a16e7bd8d06a7b996 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Mon, 11 May 2020 18:33:42 +0200 Subject: [PATCH 008/143] 8244739: Shenandoah: break superclass dependency on ShenandoahNormalMode Reviewed-by: rkennke --- .../gc/shenandoah/mode/shenandoahIUMode.cpp | 18 ++++++++++++++++++ .../gc/shenandoah/mode/shenandoahIUMode.hpp | 5 +++-- .../shenandoah/mode/shenandoahPassiveMode.hpp | 4 ++-- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/hotspot/share/gc/shenandoah/mode/shenandoahIUMode.cpp b/src/hotspot/share/gc/shenandoah/mode/shenandoahIUMode.cpp index b31d475b495..12916344f5c 100644 --- a/src/hotspot/share/gc/shenandoah/mode/shenandoahIUMode.cpp +++ b/src/hotspot/share/gc/shenandoah/mode/shenandoahIUMode.cpp @@ -55,3 +55,21 @@ void ShenandoahIUMode::initialize_flags() const { SHENANDOAH_CHECK_FLAG_SET(ShenandoahCASBarrier); SHENANDOAH_CHECK_FLAG_SET(ShenandoahCloneBarrier); } + +ShenandoahHeuristics* ShenandoahIUMode::initialize_heuristics() const { + if (ShenandoahGCHeuristics != NULL) { + if (strcmp(ShenandoahGCHeuristics, "aggressive") == 0) { + return new ShenandoahAggressiveHeuristics(); + } else if (strcmp(ShenandoahGCHeuristics, "static") == 0) { + return new ShenandoahStaticHeuristics(); + } else if (strcmp(ShenandoahGCHeuristics, "adaptive") == 0) { + return new ShenandoahAdaptiveHeuristics(); + } else if (strcmp(ShenandoahGCHeuristics, "compact") == 0) { + return new ShenandoahCompactHeuristics(); + } else { + vm_exit_during_initialization("Unknown -XX:ShenandoahGCHeuristics option"); + } + } + ShouldNotReachHere(); + return NULL; +} diff --git a/src/hotspot/share/gc/shenandoah/mode/shenandoahIUMode.hpp b/src/hotspot/share/gc/shenandoah/mode/shenandoahIUMode.hpp index 95fbee8343d..bc80d754e8a 100644 --- a/src/hotspot/share/gc/shenandoah/mode/shenandoahIUMode.hpp +++ b/src/hotspot/share/gc/shenandoah/mode/shenandoahIUMode.hpp @@ -25,13 +25,14 @@ #ifndef SHARE_GC_SHENANDOAH_MODE_SHENANDOAHIUMODE_HPP #define SHARE_GC_SHENANDOAH_MODE_SHENANDOAHIUMODE_HPP -#include "gc/shenandoah/mode/shenandoahNormalMode.hpp" +#include "gc/shenandoah/mode/shenandoahMode.hpp" class ShenandoahHeuristics; -class ShenandoahIUMode : public ShenandoahNormalMode { +class ShenandoahIUMode : public ShenandoahMode { public: virtual void initialize_flags() const; + virtual ShenandoahHeuristics* initialize_heuristics() const; virtual const char* name() { return "Incremental-Update"; } virtual bool is_diagnostic() { return false; } diff --git a/src/hotspot/share/gc/shenandoah/mode/shenandoahPassiveMode.hpp b/src/hotspot/share/gc/shenandoah/mode/shenandoahPassiveMode.hpp index c485f11595d..c0e778174b3 100644 --- a/src/hotspot/share/gc/shenandoah/mode/shenandoahPassiveMode.hpp +++ b/src/hotspot/share/gc/shenandoah/mode/shenandoahPassiveMode.hpp @@ -25,9 +25,9 @@ #ifndef SHARE_GC_SHENANDOAH_MODE_SHENANDOAHPASSIVEMODE_HPP #define SHARE_GC_SHENANDOAH_MODE_SHENANDOAHPASSIVEMODE_HPP -#include "gc/shenandoah/mode/shenandoahNormalMode.hpp" +#include "gc/shenandoah/mode/shenandoahMode.hpp" -class ShenandoahPassiveMode : public ShenandoahNormalMode { +class ShenandoahPassiveMode : public ShenandoahMode { public: virtual void initialize_flags() const; virtual ShenandoahHeuristics* initialize_heuristics() const; From d5414d7929d8a3f8ab369891c02609b9aa0fca10 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Mon, 11 May 2020 18:33:50 +0200 Subject: [PATCH 009/143] 8244740: Shenandoah: rename ShenandoahNormalMode to ShenandoahSATBMode Reviewed-by: rkennke --- ...shenandoahNormalMode.cpp => shenandoahSATBMode.cpp} | 6 +++--- ...shenandoahNormalMode.hpp => shenandoahSATBMode.hpp} | 10 +++++----- src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp | 6 +++--- src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp | 4 ++-- .../jtreg/gc/shenandoah/TestObjItrWithHeapDump.java | 2 +- .../jtreg/gc/shenandoah/oom/TestClassLoaderLeak.java | 2 +- .../jtreg/gc/shenandoah/options/TestModeUnlock.java | 2 +- 7 files changed, 16 insertions(+), 16 deletions(-) rename src/hotspot/share/gc/shenandoah/mode/{shenandoahNormalMode.cpp => shenandoahSATBMode.cpp} (93%) rename src/hotspot/share/gc/shenandoah/mode/{shenandoahNormalMode.hpp => shenandoahSATBMode.hpp} (82%) diff --git a/src/hotspot/share/gc/shenandoah/mode/shenandoahNormalMode.cpp b/src/hotspot/share/gc/shenandoah/mode/shenandoahSATBMode.cpp similarity index 93% rename from src/hotspot/share/gc/shenandoah/mode/shenandoahNormalMode.cpp rename to src/hotspot/share/gc/shenandoah/mode/shenandoahSATBMode.cpp index c21ecad3860..a376386ebe3 100644 --- a/src/hotspot/share/gc/shenandoah/mode/shenandoahNormalMode.cpp +++ b/src/hotspot/share/gc/shenandoah/mode/shenandoahSATBMode.cpp @@ -28,11 +28,11 @@ #include "gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.hpp" #include "gc/shenandoah/heuristics/shenandoahCompactHeuristics.hpp" #include "gc/shenandoah/heuristics/shenandoahStaticHeuristics.hpp" -#include "gc/shenandoah/mode/shenandoahNormalMode.hpp" +#include "gc/shenandoah/mode/shenandoahSATBMode.hpp" #include "logging/log.hpp" #include "logging/logTag.hpp" -void ShenandoahNormalMode::initialize_flags() const { +void ShenandoahSATBMode::initialize_flags() const { if (ShenandoahConcurrentRoots::can_do_concurrent_class_unloading()) { FLAG_SET_DEFAULT(ShenandoahSuspendibleWorkers, true); FLAG_SET_DEFAULT(VerifyBeforeExit, false); @@ -49,7 +49,7 @@ void ShenandoahNormalMode::initialize_flags() const { SHENANDOAH_CHECK_FLAG_SET(ShenandoahCloneBarrier); } -ShenandoahHeuristics* ShenandoahNormalMode::initialize_heuristics() const { +ShenandoahHeuristics* ShenandoahSATBMode::initialize_heuristics() const { if (ShenandoahGCHeuristics != NULL) { if (strcmp(ShenandoahGCHeuristics, "aggressive") == 0) { return new ShenandoahAggressiveHeuristics(); diff --git a/src/hotspot/share/gc/shenandoah/mode/shenandoahNormalMode.hpp b/src/hotspot/share/gc/shenandoah/mode/shenandoahSATBMode.hpp similarity index 82% rename from src/hotspot/share/gc/shenandoah/mode/shenandoahNormalMode.hpp rename to src/hotspot/share/gc/shenandoah/mode/shenandoahSATBMode.hpp index 8f6275773f9..7df03ab9a52 100644 --- a/src/hotspot/share/gc/shenandoah/mode/shenandoahNormalMode.hpp +++ b/src/hotspot/share/gc/shenandoah/mode/shenandoahSATBMode.hpp @@ -22,20 +22,20 @@ * */ -#ifndef SHARE_GC_SHENANDOAH_MODE_SHENANDOAHNORMALMODE_HPP -#define SHARE_GC_SHENANDOAH_MODE_SHENANDOAHNORMALMODE_HPP +#ifndef SHARE_GC_SHENANDOAH_MODE_SHENANDOAHSATBMODE_HPP +#define SHARE_GC_SHENANDOAH_MODE_SHENANDOAHSATBMODE_HPP #include "gc/shenandoah/mode/shenandoahMode.hpp" class ShenandoahHeuristics; -class ShenandoahNormalMode : public ShenandoahMode { +class ShenandoahSATBMode : public ShenandoahMode { public: virtual void initialize_flags() const; virtual ShenandoahHeuristics* initialize_heuristics() const; - virtual const char* name() { return "Normal"; } + virtual const char* name() { return "Snapshot-At-TheBeginning"; } virtual bool is_diagnostic() { return false; } virtual bool is_experimental() { return false; } }; -#endif // SHARE_GC_SHENANDOAH_MODE_SHENANDOAHNORMALMODE_HPP +#endif // SHARE_GC_SHENANDOAH_MODE_SHENANDOAHSATBMODE_HPP diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp index be29c3ea749..ffa8414dbf2 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp @@ -65,8 +65,8 @@ #include "gc/shenandoah/shenandoahWorkGroup.hpp" #include "gc/shenandoah/shenandoahWorkerPolicy.hpp" #include "gc/shenandoah/mode/shenandoahIUMode.hpp" -#include "gc/shenandoah/mode/shenandoahNormalMode.hpp" #include "gc/shenandoah/mode/shenandoahPassiveMode.hpp" +#include "gc/shenandoah/mode/shenandoahSATBMode.hpp" #if INCLUDE_JFR #include "gc/shenandoah/shenandoahJfrSupport.hpp" #endif @@ -398,8 +398,8 @@ jint ShenandoahHeap::initialize() { void ShenandoahHeap::initialize_heuristics() { if (ShenandoahGCMode != NULL) { - if (strcmp(ShenandoahGCMode, "normal") == 0) { - _gc_mode = new ShenandoahNormalMode(); + if (strcmp(ShenandoahGCMode, "satb") == 0) { + _gc_mode = new ShenandoahSATBMode(); } else if (strcmp(ShenandoahGCMode, "iu") == 0) { _gc_mode = new ShenandoahIUMode(); } else if (strcmp(ShenandoahGCMode, "passive") == 0) { diff --git a/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp b/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp index 4191e25f5c9..1bdc8c9f402 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp @@ -63,10 +63,10 @@ "This also caps the maximum TLAB size.") \ range(1, 100) \ \ - experimental(ccstr, ShenandoahGCMode, "normal", \ + experimental(ccstr, ShenandoahGCMode, "satb", \ "GC mode to use. Among other things, this defines which " \ "barriers are in in use. Possible values are:" \ - " normal - default concurrent GC (three pass mark-evac-update);" \ + " satb - snapshot-at-the-beginning concurrent GC (three pass mark-evac-update);" \ " iu - incremental-update concurrent GC (three pass mark-evac-update);" \ " passive - stop the world GC only (either degenerated or full)") \ \ diff --git a/test/hotspot/jtreg/gc/shenandoah/TestObjItrWithHeapDump.java b/test/hotspot/jtreg/gc/shenandoah/TestObjItrWithHeapDump.java index 71b03e9c60f..1cf4edf5692 100644 --- a/test/hotspot/jtreg/gc/shenandoah/TestObjItrWithHeapDump.java +++ b/test/hotspot/jtreg/gc/shenandoah/TestObjItrWithHeapDump.java @@ -57,7 +57,7 @@ public class TestObjItrWithHeapDump { } String[][][] modeHeuristics = new String[][][] { - {{"normal"}, {"adaptive", "compact", "static", "aggressive"}}, + {{"satb"}, {"adaptive", "compact", "static", "aggressive"}}, {{"iu"}, {"adaptive", "aggressive"}}, {{"passive"}, {"passive"}} }; diff --git a/test/hotspot/jtreg/gc/shenandoah/oom/TestClassLoaderLeak.java b/test/hotspot/jtreg/gc/shenandoah/oom/TestClassLoaderLeak.java index 4c5fd853af4..e4a2dc8d7bf 100644 --- a/test/hotspot/jtreg/gc/shenandoah/oom/TestClassLoaderLeak.java +++ b/test/hotspot/jtreg/gc/shenandoah/oom/TestClassLoaderLeak.java @@ -126,7 +126,7 @@ public class TestClassLoaderLeak { } String[][][] modeHeuristics = new String[][][] { - {{"normal"}, {"adaptive", "compact", "static", "aggressive"}}, + {{"satb"}, {"adaptive", "compact", "static", "aggressive"}}, {{"iu"}, {"adaptive", "aggressive"}}, {{"passive"}, {"passive"}} }; diff --git a/test/hotspot/jtreg/gc/shenandoah/options/TestModeUnlock.java b/test/hotspot/jtreg/gc/shenandoah/options/TestModeUnlock.java index c338b27356b..d378833ff81 100644 --- a/test/hotspot/jtreg/gc/shenandoah/options/TestModeUnlock.java +++ b/test/hotspot/jtreg/gc/shenandoah/options/TestModeUnlock.java @@ -45,7 +45,7 @@ public class TestModeUnlock { } public static void main(String[] args) throws Exception { - testWith("-XX:ShenandoahGCMode=normal", Mode.PRODUCT); + testWith("-XX:ShenandoahGCMode=satb", Mode.PRODUCT); testWith("-XX:ShenandoahGCMode=iu", Mode.EXPERIMENTAL); testWith("-XX:ShenandoahGCMode=passive", Mode.DIAGNOSTIC); } From aebc856c44fc430faf50bb4ca565127a378b1fca Mon Sep 17 00:00:00 2001 From: Daniil Titov Date: Mon, 11 May 2020 10:29:13 -0700 Subject: [PATCH 010/143] 8194874: SA: Remove scripts with sa-jdi.jar dependencies Reviewed-by: cjplummer, amenkov --- src/jdk.hotspot.agent/scripts/README | 53 ------------------- .../scripts/start-debug-server.bat | 47 ---------------- .../scripts/start-debug-server.sh | 43 --------------- .../scripts/start-debug-server64.sh | 43 --------------- .../scripts/start-rmiregistry.bat | 48 ----------------- .../scripts/start-rmiregistry.sh | 42 --------------- .../scripts/start-rmiregistry64.sh | 42 --------------- 7 files changed, 318 deletions(-) delete mode 100644 src/jdk.hotspot.agent/scripts/README delete mode 100644 src/jdk.hotspot.agent/scripts/start-debug-server.bat delete mode 100644 src/jdk.hotspot.agent/scripts/start-debug-server.sh delete mode 100644 src/jdk.hotspot.agent/scripts/start-debug-server64.sh delete mode 100644 src/jdk.hotspot.agent/scripts/start-rmiregistry.bat delete mode 100644 src/jdk.hotspot.agent/scripts/start-rmiregistry.sh delete mode 100644 src/jdk.hotspot.agent/scripts/start-rmiregistry64.sh diff --git a/src/jdk.hotspot.agent/scripts/README b/src/jdk.hotspot.agent/scripts/README deleted file mode 100644 index 710d8b0d291..00000000000 --- a/src/jdk.hotspot.agent/scripts/README +++ /dev/null @@ -1,53 +0,0 @@ -# -# Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. -# 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. -# -# - -These scripts may be used to start SA debug server for SA/JDI -purpose. The SADebugServerAttachingConnector will connect to -SADebugServer. - -How to use? - -Before starting remote debug server, make sure that the environment -variable JAVA_HOME points to the pathname of a J2SE 1.5. - -step 1: Start the rmiregistry server using one of the following - commands as appropriate: - - start-rmiregistry.sh & - start-rmiregistry64.sh & - start-rmiregistry.bat - -step 2: For live process case, use one of the following commands - as appropriate: - - start-debug-server.sh - start-debug-server64.sh - start-debug-server.bat - - For core file case, use one of the following commands as - appropriate: - - start-debug-server.sh - start-debug-server64.sh - start-debug-server.bat diff --git a/src/jdk.hotspot.agent/scripts/start-debug-server.bat b/src/jdk.hotspot.agent/scripts/start-debug-server.bat deleted file mode 100644 index d7f51df62e0..00000000000 --- a/src/jdk.hotspot.agent/scripts/start-debug-server.bat +++ /dev/null @@ -1,47 +0,0 @@ -@echo off - -REM -REM Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. -REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -REM -REM This code is free software; you can redistribute it and/or modify it -REM under the terms of the GNU General Public License version 2 only, as -REM published by the Free Software Foundation. -REM -REM This code is distributed in the hope that it will be useful, but WITHOUT -REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -REM FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -REM version 2 for more details (a copy is included in the LICENSE file that -REM accompanied this code). -REM -REM You should have received a copy of the GNU General Public License version -REM 2 along with this work; if not, write to the Free Software Foundation, -REM Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -REM -REM Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -REM or visit www.oracle.com if you need additional information or have any -REM questions. -REM -REM - -if "%1" == "-help" goto usage - -:JAVA_HOME -if not exist %JAVA_HOME%\bin\java.exe goto BADJAVAHOME -if not exist %JAVA_HOME\lib\sa-jdi.jar goto BADJAVAHOME - -start %JAVA_HOME%\bin\java -classpath %JAVA_HOME%\lib\sa-jdi.jar sun.jvm.hotspot.jdi.SADebugServer %1 %2 -goto end - -:BADJAVAHOME -echo JAVA_HOME does not point to a working J2SE 1.5 installation. - -:usage -echo Usage: start-debug-server [pid] -echo $0 [Dr Watson dump file] -echo Start the JDI debug server on [pid] or [Dr Watson dump file] -echo so that it can be debugged from a remote machine. -echo JAVA_HOME must contain the pathname of a J2SE 1.5 -echo installation. - -:end diff --git a/src/jdk.hotspot.agent/scripts/start-debug-server.sh b/src/jdk.hotspot.agent/scripts/start-debug-server.sh deleted file mode 100644 index 43134a77cf0..00000000000 --- a/src/jdk.hotspot.agent/scripts/start-debug-server.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/sh - -# -# Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. -# 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. -# -# - -if [ "$1" = "-help" ] ; then - echo "Usage: $0 " - echo " $0 " - echo " Start the JDI debug server on or " - echo " so that it can be debugged from a remote machine." - echo " JAVA_HOME must contain the pathname of a J2SE 1.5" - echo " installation." - exit 0 -fi - -if [ ! -x ${JAVA_HOME}/bin/java -o ! -r ${JAVA_HOME}/lib/sa-jdi.jar ] ; -then - echo '${JAVA_HOME} does not point to a working J2SE 1.5 installation.' - exit 1 -fi - -${JAVA_HOME}/bin/java -classpath ${JAVA_HOME}/lib/sa-jdi.jar sun.jvm.hotspot.jdi.SADebugServer $* diff --git a/src/jdk.hotspot.agent/scripts/start-debug-server64.sh b/src/jdk.hotspot.agent/scripts/start-debug-server64.sh deleted file mode 100644 index d4fa43d6c24..00000000000 --- a/src/jdk.hotspot.agent/scripts/start-debug-server64.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/sh - -# -# Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. -# 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. -# -# - -if [ "$1" = "-help" ] ; then - echo "Usage: $0 " - echo " $0 " - echo " Start the JDI debug server on or " - echo " so that it can be debugged from a remote machine." - echo " JAVA_HOME must contain the pathname of a J2SE 1.5" - echo " installation." - exit 0 -fi - -if [ ! -x ${JAVA_HOME}/bin/java -o ! -r ${JAVA_HOME}/lib/sa-jdi.jar ] ; -then - echo '${JAVA_HOME} does not point to a working J2SE 1.5 installation.' - exit 1 -fi - -${JAVA_HOME}/bin/java -d64 -classpath ${JAVA_HOME}/lib/sa-jdi.jar sun.jvm.hotspot.jdi.SADebugServer $* diff --git a/src/jdk.hotspot.agent/scripts/start-rmiregistry.bat b/src/jdk.hotspot.agent/scripts/start-rmiregistry.bat deleted file mode 100644 index eb2b012f24d..00000000000 --- a/src/jdk.hotspot.agent/scripts/start-rmiregistry.bat +++ /dev/null @@ -1,48 +0,0 @@ -@echo off - -REM -REM Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. -REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -REM -REM This code is free software; you can redistribute it and/or modify it -REM under the terms of the GNU General Public License version 2 only, as -REM published by the Free Software Foundation. -REM -REM This code is distributed in the hope that it will be useful, but WITHOUT -REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -REM FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -REM version 2 for more details (a copy is included in the LICENSE file that -REM accompanied this code). -REM -REM You should have received a copy of the GNU General Public License version -REM 2 along with this work; if not, write to the Free Software Foundation, -REM Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -REM -REM Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -REM or visit www.oracle.com if you need additional information or have any -REM questions. -REM -REM - -@echo off - -if "%1" == "-help" goto usage - -:JAVA_HOME -if not exist %JAVA_HOME%\bin\rmiregistry goto BADJAVAHOME -if not exist %JAVA_HOME%\lib\sa-jdi.jar goto BADJAVAHOME - -start %JAVA_HOME%\bin\rmiregistry -J-Xbootclasspath/p:%JAVA_HOME%\lib\sa-jdi.jar -goto end - -:BADJAVAHOME -echo JAVA_HOME does not point to a working J2SE 1.5 installation. - -:usage -@echo usage: start-rmiregistry -@echo Start the rmi registry with with sa-jdi.jar on the bootclasspath -@echo for use by the debug server. -@echo JAVA_HOME must contain the pathname of a J2SE 1.5 installation. - -:end - diff --git a/src/jdk.hotspot.agent/scripts/start-rmiregistry.sh b/src/jdk.hotspot.agent/scripts/start-rmiregistry.sh deleted file mode 100644 index 11f184ff1b7..00000000000 --- a/src/jdk.hotspot.agent/scripts/start-rmiregistry.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/sh - -# -# Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. -# 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. -# -# - -if [ "$1" = "-help" ] ; then - echo "usage: $0&" - echo " Start the rmi registry with with sa-jdi.jar on the bootclasspath" - echo " for use by the debug server." - echo " JAVA_HOME must contain the pathname of a J2SE 1.5" - echo " installation." - exit 0 -fi - -if [ ! -x ${JAVA_HOME}/bin/rmiregistry -o ! -r ${JAVA_HOME}/lib/sa-jdi.jar ] ; -then - echo '${JAVA_HOME} does not point to a working J2SE installation.' - exit 1 -fi - -${JAVA_HOME}/bin/rmiregistry -J-Xbootclasspath/p:${JAVA_HOME}/lib/sa-jdi.jar diff --git a/src/jdk.hotspot.agent/scripts/start-rmiregistry64.sh b/src/jdk.hotspot.agent/scripts/start-rmiregistry64.sh deleted file mode 100644 index ffd0d8df6fe..00000000000 --- a/src/jdk.hotspot.agent/scripts/start-rmiregistry64.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/sh - -# -# Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. -# 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. -# -# - -if [ "$1" = "-help" ] ; then - echo "usage: $0&" - echo " Start the rmi registry with with sa-jdi.jar on the bootclasspath" - echo " for use by the debug server." - echo " JAVA_HOME must contain the pathname of a J2SE 1.5" - echo " installation." - exit 0 -fi - -if [ ! -x ${JAVA_HOME}/bin/rmiregistry -o ! -r ${JAVA_HOME}/lib/sa-jdi.jar ] ; -then - echo '${JAVA_HOME} does not point to a working J2SE installation.' - exit 1 -fi - -${JAVA_HOME}/bin/rmiregistry -J-d64 -J-Xbootclasspath/p:${JAVA_HOME}/lib/sa-jdi.jar From 78825925a5123aff66ae222420dcff8f454190e2 Mon Sep 17 00:00:00 2001 From: Valerie Peng Date: Mon, 11 May 2020 18:49:01 +0000 Subject: [PATCH 011/143] 8244151: Update MUSCLE PC/SC-Lite headers to the latest release 1.8.26 Updated from 1.8.24 to 1.8.26 Reviewed-by: xuelei --- src/java.smartcardio/unix/legal/pcsclite.md | 2 +- src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/pcsclite.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/java.smartcardio/unix/legal/pcsclite.md b/src/java.smartcardio/unix/legal/pcsclite.md index 42088c64314..abf19833838 100644 --- a/src/java.smartcardio/unix/legal/pcsclite.md +++ b/src/java.smartcardio/unix/legal/pcsclite.md @@ -1,4 +1,4 @@ -## PC/SC Lite v1.8.24 +## PC/SC Lite v1.8.26 ### PC/SC Lite License
diff --git a/src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/pcsclite.h b/src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/pcsclite.h
index ee131c90407..cc12b3d2a43 100644
--- a/src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/pcsclite.h
+++ b/src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/pcsclite.h
@@ -279,7 +279,7 @@ extern const SCARD_IO_REQUEST g_rgSCardT0Pci, g_rgSCardT1Pci, g_rgSCardRawPci;
 #define INFINITE                  0xFFFFFFFF      /**< Infinite timeout */
 #endif
 
-#define PCSCLITE_VERSION_NUMBER            "1.8.24"      /**< Current version */
+#define PCSCLITE_VERSION_NUMBER            "1.8.26"      /**< Current version */
 /** Maximum readers context (a slot is count as a reader) */
 #define PCSCLITE_MAX_READERS_CONTEXTS                  16
 

From 9253c29fd263e56145eea9e63c8dfe55ec448794 Mon Sep 17 00:00:00 2001
From: Andy Herrick 
Date: Mon, 11 May 2020 15:29:52 -0400
Subject: [PATCH 012/143] 8244620: Fix test WinUpgradeUUIDTest failures in
 Mach5

Reviewed-by: asemenyuk, prr
---
 test/jdk/ProblemList.txt                               |  1 -
 .../jdk/tools/jpackage/windows/WinUpgradeUUIDTest.java | 10 ++++++++--
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt
index fabef8d853e..7f330931974 100644
--- a/test/jdk/ProblemList.txt
+++ b/test/jdk/ProblemList.txt
@@ -897,7 +897,6 @@ sanity/client/SwingSet/src/ScrollPaneDemoTest.java 8225013 linux-all
 # core_tools
 
 tools/jlink/JLinkReproducibleTest.java                          8217166 windows-all
-tools/jpackage/windows/WinUpgradeUUIDTest.java#id1              8244620 windows-all
 
 ############################################################################
 
diff --git a/test/jdk/tools/jpackage/windows/WinUpgradeUUIDTest.java b/test/jdk/tools/jpackage/windows/WinUpgradeUUIDTest.java
index fd0c3b9d5b1..f1effb3f07b 100644
--- a/test/jdk/tools/jpackage/windows/WinUpgradeUUIDTest.java
+++ b/test/jdk/tools/jpackage/windows/WinUpgradeUUIDTest.java
@@ -182,19 +182,25 @@ public class WinUpgradeUUIDTest {
         void assertEquals(PackageTest x, PackageTest y) {
             var entryX = propertyValues().get(x);
             var entryY = propertyValues().get(y);
-            TKit.assertEquals(entryX.getValue(), entryY.getValue(),
+            // if MsiBundler is not supported, these will be null
+            if (entryX != null && entryY != null) {
+                TKit.assertEquals(entryX.getValue(), entryY.getValue(),
                     String.format(
                             "Check %s is the same for %s and %s command lines",
                             propertyName(), entryX.getKey(), entryY.getKey()));
+            }
         }
 
         void assertNotEquals(PackageTest x, PackageTest y) {
             var entryX = propertyValues().get(x);
             var entryY = propertyValues().get(y);
-            TKit.assertNotEquals(entryX.getValue(), entryY.getValue(),
+            // if MsiBundler is not supported, these will be null
+            if (entryX != null && entryY != null) {
+                TKit.assertNotEquals(entryX.getValue(), entryY.getValue(),
                     String.format(
                             "Check %s is different for %s and %s command lines",
                             propertyName(), entryX.getKey(), entryY.getKey()));
+            }
         }
 
         protected abstract String propertyName();

From 3b9367636e6daaa559f7651f7aabedc5e394f4fc Mon Sep 17 00:00:00 2001
From: Erik Gahlin 
Date: Mon, 11 May 2020 21:42:23 +0200
Subject: [PATCH 013/143] 8244676:
 test/jdk/jdk/jfr/startupargs/TestOptionsWithLocale.java fails

Reviewed-by: mgronlun
---
 test/jdk/jdk/jfr/startupargs/TestOptionsWithLocale.java | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/test/jdk/jdk/jfr/startupargs/TestOptionsWithLocale.java b/test/jdk/jdk/jfr/startupargs/TestOptionsWithLocale.java
index 1d1a79040f3..1942b3d3f63 100644
--- a/test/jdk/jdk/jfr/startupargs/TestOptionsWithLocale.java
+++ b/test/jdk/jdk/jfr/startupargs/TestOptionsWithLocale.java
@@ -16,7 +16,7 @@ import jdk.test.lib.process.ProcessTools;
  * @requires vm.hasJFR
  * @modules jdk.jfr
  * @library /test/lib
- * @run main jdk.jfr.startupargs.TestOptionsWithLocale
+ * @run main/othervm jdk.jfr.startupargs.TestOptionsWithLocale
  */
 public class TestOptionsWithLocale {
 
@@ -29,6 +29,13 @@ public class TestOptionsWithLocale {
     }
 
     public static void main(String... args) throws IOException {
+        // Can only run test if jdk.localedata is available.
+        // Can't specify @module jdk.jfr jdk.localedata, because
+        // --limit-modules jdk.jfr,jdk.localedata prevents the product issue.
+        if (ModuleLayer.boot().findModule("jdk.localedata").isEmpty()) {
+            return;
+        }
+
         ProcessBuilder pb = ProcessTools.createTestJvm(
                 "-Duser.country=DE",
                 "-Duser.language=de",

From fc842d2b4bb054f543990c715fcbebc3ccf052de Mon Sep 17 00:00:00 2001
From: Claes Redestad 
Date: Mon, 11 May 2020 21:43:57 +0200
Subject: [PATCH 014/143] 8193066: Avoid use of capturing lambdas in JarFile

Reviewed-by: lancea, alanb
---
 .../share/classes/java/util/jar/JarFile.java  |  34 ++---
 .../java/util/jar/JavaUtilJarAccessImpl.java  |   7 +
 .../share/classes/java/util/zip/ZipFile.java  |  65 +++-----
 .../internal/access/JavaUtilJarAccess.java    |   1 +
 .../access/JavaUtilZipFileAccess.java         |   6 +-
 .../bench/java/util/jar/JarFileGetEntry.java  | 144 ++++++++++++++++++
 6 files changed, 191 insertions(+), 66 deletions(-)
 create mode 100644 test/micro/org/openjdk/bench/java/util/jar/JarFileGetEntry.java

diff --git a/src/java.base/share/classes/java/util/jar/JarFile.java b/src/java.base/share/classes/java/util/jar/JarFile.java
index a71e13d8bff..43c56a86bb0 100644
--- a/src/java.base/share/classes/java/util/jar/JarFile.java
+++ b/src/java.base/share/classes/java/util/jar/JarFile.java
@@ -503,11 +503,11 @@ public class JarFile extends ZipFile {
         if (isMultiRelease()) {
             JarEntry je = getVersionedEntry(name, null);
             if (je == null) {
-                je = getEntry0(name);
+                je = (JarEntry)super.getEntry(name);
             }
             return je;
         } else {
-            return getEntry0(name);
+            return super.getEntry(name);
         }
     }
 
@@ -519,7 +519,7 @@ public class JarFile extends ZipFile {
      *         may be thrown if the jar file has been closed
      */
     public Enumeration entries() {
-        return JUZFA.entries(this, JarFileEntry::new);
+        return JUZFA.entries(this);
     }
 
     /**
@@ -532,7 +532,7 @@ public class JarFile extends ZipFile {
      * @since 1.8
      */
     public Stream stream() {
-        return JUZFA.stream(this, JarFileEntry::new);
+        return JUZFA.stream(this);
     }
 
     /**
@@ -563,19 +563,11 @@ public class JarFile extends ZipFile {
         return stream();
     }
 
-    /*
-     * Invokes {@ZipFile}'s getEntry to Return a {@code JarFileEntry} for the
-     * given entry name or {@code null} if not found.
+    /**
+     * Creates a ZipEntry suitable for the given ZipFile.
      */
-    private JarFileEntry getEntry0(String name) {
-        // Not using a lambda/method reference here to optimize startup time
-        Function newJarFileEntryFn = new Function<>() {
-            @Override
-            public JarEntry apply(String name) {
-                return new JarFileEntry(name);
-            }
-        };
-        return (JarFileEntry)JUZFA.getEntry(this, name, newJarFileEntryFn);
+    JarEntry entryFor(String name) {
+        return new JarFileEntry(name);
     }
 
     private String getBasename(String name) {
@@ -613,7 +605,8 @@ public class JarFile extends ZipFile {
                     if (version < BASE_VERSION_FEATURE) {
                         break;
                     }
-                    JarFileEntry vje = getEntry0(META_INF_VERSIONS + version + "/" + name);
+                    JarFileEntry vje = (JarFileEntry)super.getEntry(
+                            META_INF_VERSIONS + version + "/" + name);
                     if (vje != null) {
                         return vje.withBasename(name);
                     }
@@ -926,7 +919,7 @@ public class JarFile extends ZipFile {
             // initialization
             String name = JUZFA.getManifestName(this, false);
             if (name != null) {
-                this.manEntry = getEntry0(name);
+                this.manEntry = (JarEntry)super.getEntry(name);
             }
         }
         return manEntry;
@@ -1093,12 +1086,11 @@ public class JarFile extends ZipFile {
     Enumeration entries2() {
         ensureInitialization();
         if (jv != null) {
-            return jv.entries2(this, JUZFA.entries(JarFile.this,
-                                                   JarFileEntry::new));
+            return jv.entries2(this, JUZFA.entries(JarFile.this));
         }
 
         // screen out entries which are never signed
-        final var unfilteredEntries = JUZFA.entries(JarFile.this, JarFileEntry::new);
+        final var unfilteredEntries = JUZFA.entries(JarFile.this);
 
         return new Enumeration<>() {
 
diff --git a/src/java.base/share/classes/java/util/jar/JavaUtilJarAccessImpl.java b/src/java.base/share/classes/java/util/jar/JavaUtilJarAccessImpl.java
index c3e1628b801..27e872b5341 100644
--- a/src/java.base/share/classes/java/util/jar/JavaUtilJarAccessImpl.java
+++ b/src/java.base/share/classes/java/util/jar/JavaUtilJarAccessImpl.java
@@ -30,6 +30,9 @@ import java.net.URL;
 import java.security.CodeSource;
 import java.util.Enumeration;
 import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
 import jdk.internal.access.JavaUtilJarAccess;
 
 class JavaUtilJarAccessImpl implements JavaUtilJarAccess {
@@ -72,4 +75,8 @@ class JavaUtilJarAccessImpl implements JavaUtilJarAccess {
     public boolean isInitializing() {
         return JarFile.isInitializing();
     }
+
+    public JarEntry entryFor(JarFile jar, String name) {
+        return jar.entryFor(name);
+    }
 }
diff --git a/src/java.base/share/classes/java/util/zip/ZipFile.java b/src/java.base/share/classes/java/util/zip/ZipFile.java
index 1b028199434..8d426f2f854 100644
--- a/src/java.base/share/classes/java/util/zip/ZipFile.java
+++ b/src/java.base/share/classes/java/util/zip/ZipFile.java
@@ -55,13 +55,13 @@ import java.util.Spliterators;
 import java.util.TreeSet;
 import java.util.WeakHashMap;
 import java.util.function.Consumer;
-import java.util.function.Function;
 import java.util.function.IntFunction;
 import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
 import java.util.stream.Stream;
 import java.util.stream.StreamSupport;
 import jdk.internal.access.JavaUtilZipFileAccess;
+import jdk.internal.access.JavaUtilJarAccess;
 import jdk.internal.access.SharedSecrets;
 import jdk.internal.misc.VM;
 import jdk.internal.perf.PerfCounter;
@@ -321,27 +321,13 @@ public class ZipFile implements ZipConstants, Closeable {
      * @throws IllegalStateException if the zip file has been closed
      */
     public ZipEntry getEntry(String name) {
-        return getEntry(name, ZipEntry::new);
-    }
-
-    /*
-     * Returns the zip file entry for the specified name, or null
-     * if not found.
-     *
-     * @param name the name of the entry
-     * @param func the function that creates the returned entry
-     *
-     * @return the zip file entry, or null if not found
-     * @throws IllegalStateException if the zip file has been closed
-     */
-    private ZipEntry getEntry(String name, Function func) {
         Objects.requireNonNull(name, "name");
         ZipEntry entry = null;
         synchronized (this) {
             ensureOpen();
             int pos = res.zsrc.getEntryPos(name, true);
             if (pos != -1) {
-                entry = getZipEntry(name, pos, func);
+                entry = getZipEntry(name, pos);
             }
         }
         return entry;
@@ -487,11 +473,9 @@ public class ZipFile implements ZipConstants, Closeable {
 
         private int i = 0;
         private final int entryCount;
-        private final Function gen;
 
-        public ZipEntryIterator(int entryCount, Function gen) {
+        public ZipEntryIterator(int entryCount) {
             this.entryCount = entryCount;
-            this.gen = gen;
         }
 
         @Override
@@ -518,7 +502,7 @@ public class ZipFile implements ZipConstants, Closeable {
                     throw new NoSuchElementException();
                 }
                 // each "entry" has 3 ints in table entries
-                return (T)getZipEntry(null, res.zsrc.getEntryPos(i++ * 3), gen);
+                return (T)getZipEntry(null, res.zsrc.getEntryPos(i++ * 3));
             }
         }
 
@@ -536,14 +520,14 @@ public class ZipFile implements ZipConstants, Closeable {
     public Enumeration entries() {
         synchronized (this) {
             ensureOpen();
-            return new ZipEntryIterator(res.zsrc.total, ZipEntry::new);
+            return new ZipEntryIterator(res.zsrc.total);
         }
     }
 
-    private Enumeration entries(Function func) {
+    private Enumeration jarEntries() {
         synchronized (this) {
             ensureOpen();
-            return new ZipEntryIterator(res.zsrc.total, func);
+            return new ZipEntryIterator(res.zsrc.total);
         }
     }
 
@@ -590,7 +574,7 @@ public class ZipFile implements ZipConstants, Closeable {
         synchronized (this) {
             ensureOpen();
             return StreamSupport.stream(new EntrySpliterator<>(0, res.zsrc.total,
-                pos -> getZipEntry(null, pos, ZipEntry::new)), false);
+                pos -> getZipEntry(null, pos)), false);
        }
     }
 
@@ -625,16 +609,15 @@ public class ZipFile implements ZipConstants, Closeable {
      * Entries appear in the {@code Stream} in the order they appear in
      * the central directory of the jar file.
      *
-     * @param func the function that creates the returned entry
      * @return an ordered {@code Stream} of entries in this zip file
      * @throws IllegalStateException if the zip file has been closed
      * @since 10
      */
-    private Stream stream(Function func) {
+    private Stream jarStream() {
         synchronized (this) {
             ensureOpen();
             return StreamSupport.stream(new EntrySpliterator<>(0, res.zsrc.total,
-                pos -> (JarEntry)getZipEntry(null, pos, func)), false);
+                pos -> (JarEntry)getZipEntry(null, pos)), false);
         }
     }
 
@@ -642,8 +625,7 @@ public class ZipFile implements ZipConstants, Closeable {
     private int lastEntryPos;
 
     /* Check ensureOpen() before invoking this method */
-    private ZipEntry getZipEntry(String name, int pos,
-                                 Function func) {
+    private ZipEntry getZipEntry(String name, int pos) {
         byte[] cen = res.zsrc.cen;
         int nlen = CENNAM(cen, pos);
         int elen = CENEXT(cen, pos);
@@ -663,7 +645,12 @@ public class ZipFile implements ZipConstants, Closeable {
             // invoked from iterator, use the entry name stored in cen
             name = zc.toString(cen, pos + CENHDR, nlen);
         }
-        ZipEntry e = func.apply(name);    //ZipEntry e = new ZipEntry(name);
+        ZipEntry e;
+        if (this instanceof JarFile) {
+            e = Source.JUJA.entryFor((JarFile)this, name);
+        } else {
+            e = new ZipEntry(name);
+        }
         e.flag = CENFLG(cen, pos);
         e.xdostime = CENTIM(cen, pos);
         e.crc = CENCRC(cen, pos);
@@ -1094,19 +1081,12 @@ public class ZipFile implements ZipConstants, Closeable {
                     return ((ZipFile)jar).getMetaInfVersions();
                 }
                 @Override
-                public JarEntry getEntry(ZipFile zip, String name,
-                    Function func) {
-                    return (JarEntry)zip.getEntry(name, func);
+                public Enumeration entries(ZipFile zip) {
+                    return zip.jarEntries();
                 }
                 @Override
-                public Enumeration entries(ZipFile zip,
-                    Function func) {
-                    return zip.entries(func);
-                }
-                @Override
-                public Stream stream(ZipFile zip,
-                    Function func) {
-                    return zip.stream(func);
+                public Stream stream(ZipFile zip) {
+                    return zip.jarStream();
                 }
                 @Override
                 public Stream entryNameStream(ZipFile zip) {
@@ -1118,6 +1098,9 @@ public class ZipFile implements ZipConstants, Closeable {
     }
 
     private static class Source {
+        // While this is only used from ZipFile, defining it there would cause
+        // a bootstrap cycle that would leave this initialized as null
+        private static final JavaUtilJarAccess JUJA = SharedSecrets.javaUtilJarAccess();
         // "META-INF/".length()
         private static final int META_INF_LENGTH = 9;
         private static final int[] EMPTY_META_VERSIONS = new int[0];
diff --git a/src/java.base/share/classes/jdk/internal/access/JavaUtilJarAccess.java b/src/java.base/share/classes/jdk/internal/access/JavaUtilJarAccess.java
index f7e66165649..042c9c66d59 100644
--- a/src/java.base/share/classes/jdk/internal/access/JavaUtilJarAccess.java
+++ b/src/java.base/share/classes/jdk/internal/access/JavaUtilJarAccess.java
@@ -46,4 +46,5 @@ public interface JavaUtilJarAccess {
     public Attributes getTrustedAttributes(Manifest man, String name);
     public void ensureInitialization(JarFile jar);
     public boolean isInitializing();
+    public JarEntry entryFor(JarFile file, String name);
 }
diff --git a/src/java.base/share/classes/jdk/internal/access/JavaUtilZipFileAccess.java b/src/java.base/share/classes/jdk/internal/access/JavaUtilZipFileAccess.java
index 8a0a95dcedc..2011b16206f 100644
--- a/src/java.base/share/classes/jdk/internal/access/JavaUtilZipFileAccess.java
+++ b/src/java.base/share/classes/jdk/internal/access/JavaUtilZipFileAccess.java
@@ -27,7 +27,6 @@ package jdk.internal.access;
 
 import java.util.Enumeration;
 import java.util.List;
-import java.util.function.Function;
 import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
 import java.util.stream.Stream;
@@ -38,9 +37,8 @@ public interface JavaUtilZipFileAccess {
     public List getManifestAndSignatureRelatedFiles(JarFile zip);
     public String getManifestName(JarFile zip, boolean onlyIfSignatureRelatedFiles);
     public int[] getMetaInfVersions(JarFile zip);
-    public JarEntry getEntry(ZipFile zip, String name, Function func);
-    public Enumeration entries(ZipFile zip, Function func);
-    public Stream stream(ZipFile zip, Function func);
+    public Enumeration entries(ZipFile zip);
+    public Stream stream(ZipFile zip);
     public Stream entryNameStream(ZipFile zip);
 }
 
diff --git a/test/micro/org/openjdk/bench/java/util/jar/JarFileGetEntry.java b/test/micro/org/openjdk/bench/java/util/jar/JarFileGetEntry.java
new file mode 100644
index 00000000000..bc2182e00b4
--- /dev/null
+++ b/test/micro/org/openjdk/bench/java/util/jar/JarFileGetEntry.java
@@ -0,0 +1,144 @@
+/*
+ * 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.java.util.jar;
+
+import org.openjdk.jmh.annotations.*;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+import java.util.jar.JarFile;
+import java.util.jar.JarOutputStream;
+import java.util.zip.ZipEntry;
+
+/**
+ * Simple benchmark measuring cost of looking up entries in a jar file.
+ *
+ * Before JDK-8193066
+ * Benchmark                             (size)  Mode  Cnt   Score    Error   Units
+ * JarFileGetEntry.getEntryHit            1024  avgt   10  102.554    3.371   ns/op
+ *   gc.alloc.rate.norm                   1024  avgt   10  144.036    0.004    B/op
+ * JarFileGetEntry.getEntryHitUncached    1024  avgt   10  141.307    7.454   ns/op
+ *   gc.alloc.rate.norm                   1024  avgt   10  200.040    0.004    B/op
+ * JarFileGetEntry.getEntryMiss           1024  avgt   10   26.489    1.737   ns/op
+ *   gc.alloc.rate.norm                   1024  avgt   10   16.001    0.001    B/op
+ * JarFileGetEntry.getEntryMissUncached   1024  avgt   10   74.189    3.320   ns/op
+ *   gc.alloc.rate.norm                   1024  avgt   10   72.194    0.001    B/op
+ *
+ * After JDK-8193066
+ * Benchmark                            (size)  Mode  Cnt    Score    Error   Units
+ * JarFileGetEntry.getEntryHit            1024  avgt   10   98.075    3.718   ns/op
+ *   gc.alloc.rate.norm                   1024  avgt   10  128.034    0.007    B/op
+ * JarFileGetEntry.getEntryHitUncached    1024  avgt   10  132.998    5.937   ns/op
+ *   gc.alloc.rate.norm                   1024  avgt   10  184.039    0.009    B/op
+ * JarFileGetEntry.getEntryMiss           1024  avgt   10   24.043    0.930   ns/op
+ *   gc.alloc.rate.norm                   1024  avgt   10    0.001    0.001    B/op
+ * JarFileGetEntry.getEntryMissUncached   1024  avgt   10   65.840    3.296   ns/op
+ *   gc.alloc.rate.norm                   1024  avgt   10   56.192    0.003    B/op
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+@Warmup(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS)
+@Measurement(iterations = 5, time = 1000, timeUnit = TimeUnit.MILLISECONDS)
+@Fork(3)
+public class JarFileGetEntry {
+
+    @Param({"512", "1024"})
+    private int size;
+
+    public JarFile jarFile;
+    public String[]         entryNames;
+    public String[]         missingEntryNames;
+    public StringBuilder[]  entryNameBuilders;
+    public StringBuilder[]  missingEntryNameBuilders;
+
+    public int index = 0;
+
+    @Setup(Level.Trial)
+    public void beforeRun() throws IOException {
+        // Create a test Zip file with the number of entries.
+        File tempFile = Files.createTempFile("jar-mr-micro", ".jar").toFile();
+        tempFile.deleteOnExit();
+
+        entryNameBuilders = new StringBuilder[size];
+        missingEntryNameBuilders = new StringBuilder[size];
+
+        entryNames = new String[size];
+        missingEntryNames = new String[size];
+
+        try (FileOutputStream fos = new FileOutputStream(tempFile);
+             JarOutputStream jos = new JarOutputStream(fos)) {
+
+            Random random = new Random(4711);
+            for (int i = 0; i < size; i++) {
+                String ename = "entry-" + (random.nextInt(90000) + 10000) + "-" + i;
+                jos.putNextEntry(new ZipEntry(ename));
+
+                entryNames[i] = ename;
+                entryNameBuilders[i] = new StringBuilder(ename);
+
+                missingEntryNames[i] = ename + "-";
+                missingEntryNameBuilders[i] = new StringBuilder(missingEntryNames[i]);
+            }
+        }
+
+        jarFile = new JarFile(tempFile);
+    }
+
+    @Benchmark
+    public void getEntryHit() {
+        if (index >= size) {
+            index = 0;
+        }
+        jarFile.getEntry(entryNames[index++]);
+    }
+
+    @Benchmark
+    public void getEntryMiss() {
+        if (index >= size) {
+            index = 0;
+        }
+        jarFile.getEntry(missingEntryNames[index++]);
+    }
+
+    @Benchmark
+    public void getEntryHitUncached() {
+        if (index >= size) {
+            index = 0;
+        }
+        jarFile.getEntry(entryNameBuilders[index++].toString());
+    }
+
+    @Benchmark
+    public void getEntryMissUncached() {
+        if (index >= size) {
+            index = 0;
+        }
+        jarFile.getEntry(missingEntryNameBuilders[index++].toString());
+    }
+}

From 91220287fcada7943e09099022b5745af491e328 Mon Sep 17 00:00:00 2001
From: Evgeny Nikitin 
Date: Thu, 23 Apr 2020 16:20:17 +0200
Subject: [PATCH 015/143] 8147018: CompilerControl: Improve handling of
 timeouts and failures for tests

Dump expected method states, improve compile commands dumping in CompilerControl tests

Reviewed-by: iignatyev, rbackman
---
 .../jcmd/AddAndRemoveTest.java                |  1 -
 .../jcmd/ClearDirectivesFileStackTest.java    |  1 -
 .../jcmd/ClearDirectivesStackTest.java        |  1 -
 .../jcmd/PrintDirectivesTest.java             |  1 -
 .../compilercontrol/share/MultiCommand.java   |  3 +--
 .../compilercontrol/share/SingleCommand.java  |  3 +--
 .../share/actions/CompileAction.java          |  9 ++++++-
 .../share/scenario/CompileCommand.java        | 25 +++++++++++++++----
 .../share/scenario/JcmdCommand.java           | 11 +++++++-
 .../share/scenario/Scenario.java              |  3 ++-
 10 files changed, 42 insertions(+), 16 deletions(-)

diff --git a/test/hotspot/jtreg/compiler/compilercontrol/jcmd/AddAndRemoveTest.java b/test/hotspot/jtreg/compiler/compilercontrol/jcmd/AddAndRemoveTest.java
index 898fa82410c..5ff3bd830f9 100644
--- a/test/hotspot/jtreg/compiler/compilercontrol/jcmd/AddAndRemoveTest.java
+++ b/test/hotspot/jtreg/compiler/compilercontrol/jcmd/AddAndRemoveTest.java
@@ -63,7 +63,6 @@ public class AddAndRemoveTest extends AbstractTestBase {
             MethodDescriptor md = getValidMethodDescriptor(exec);
             CompileCommand compileCommand = new JcmdCommand(Command.COMPILEONLY,
                     md, null, Scenario.Type.JCMD, Scenario.JcmdType.ADD);
-            compileCommand.print();
             builder.add(compileCommand);
         }
         // Remove half of them
diff --git a/test/hotspot/jtreg/compiler/compilercontrol/jcmd/ClearDirectivesFileStackTest.java b/test/hotspot/jtreg/compiler/compilercontrol/jcmd/ClearDirectivesFileStackTest.java
index 6a18953c745..cbdafb63e65 100644
--- a/test/hotspot/jtreg/compiler/compilercontrol/jcmd/ClearDirectivesFileStackTest.java
+++ b/test/hotspot/jtreg/compiler/compilercontrol/jcmd/ClearDirectivesFileStackTest.java
@@ -76,7 +76,6 @@ public class ClearDirectivesFileStackTest extends AbstractTestBase {
             CompileCommand compileCommand = new CompileCommand(command,
                     methodDescriptor, cmdGen.generateCompiler(),
                     Scenario.Type.DIRECTIVE);
-            compileCommand.print();
             builder.add(compileCommand);
         }
         // clear the stack
diff --git a/test/hotspot/jtreg/compiler/compilercontrol/jcmd/ClearDirectivesStackTest.java b/test/hotspot/jtreg/compiler/compilercontrol/jcmd/ClearDirectivesStackTest.java
index a20ed6a53e5..c046812f730 100644
--- a/test/hotspot/jtreg/compiler/compilercontrol/jcmd/ClearDirectivesStackTest.java
+++ b/test/hotspot/jtreg/compiler/compilercontrol/jcmd/ClearDirectivesStackTest.java
@@ -66,7 +66,6 @@ public class ClearDirectivesStackTest extends AbstractTestBase {
                     cmdGen.generateCommand(), methodDescriptor,
                     cmdGen.generateCompiler(), Scenario.Type.JCMD,
                     Scenario.JcmdType.ADD);
-            compileCommand.print();
             builder.add(compileCommand);
         }
         // clear the stack
diff --git a/test/hotspot/jtreg/compiler/compilercontrol/jcmd/PrintDirectivesTest.java b/test/hotspot/jtreg/compiler/compilercontrol/jcmd/PrintDirectivesTest.java
index 8c1ea162423..70df3e95a1b 100644
--- a/test/hotspot/jtreg/compiler/compilercontrol/jcmd/PrintDirectivesTest.java
+++ b/test/hotspot/jtreg/compiler/compilercontrol/jcmd/PrintDirectivesTest.java
@@ -73,7 +73,6 @@ public class PrintDirectivesTest extends AbstractTestBase {
             CompileCommand compileCommand = new CompileCommand(command,
                     methodDescriptor, cmdGen.generateCompiler(),
                     Scenario.Type.DIRECTIVE);
-            compileCommand.print();
             builder.add(compileCommand);
         }
         // print all directives
diff --git a/test/hotspot/jtreg/compiler/compilercontrol/share/MultiCommand.java b/test/hotspot/jtreg/compiler/compilercontrol/share/MultiCommand.java
index ab51daa1520..2683c356708 100644
--- a/test/hotspot/jtreg/compiler/compilercontrol/share/MultiCommand.java
+++ b/test/hotspot/jtreg/compiler/compilercontrol/share/MultiCommand.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
@@ -76,7 +76,6 @@ public class MultiCommand extends AbstractTestBase {
         builder.addFlag("-XX:+UnlockDiagnosticVMOptions");
         builder.addFlag("-XX:CompilerDirectivesLimit=101");
         for (CompileCommand cc : testCases) {
-            cc.print();
             builder.add(cc);
         }
         Scenario scenario = builder.build();
diff --git a/test/hotspot/jtreg/compiler/compilercontrol/share/SingleCommand.java b/test/hotspot/jtreg/compiler/compilercontrol/share/SingleCommand.java
index 1ca86054bc5..a7a1bac1b3a 100644
--- a/test/hotspot/jtreg/compiler/compilercontrol/share/SingleCommand.java
+++ b/test/hotspot/jtreg/compiler/compilercontrol/share/SingleCommand.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
@@ -49,7 +49,6 @@ public class SingleCommand extends AbstractTestBase {
         CommandGenerator cmdGen = new CommandGenerator();
         CompileCommand compileCommand = cmdGen.generateCompileCommand(command,
                 md, type);
-        compileCommand.print();
         builder.add(compileCommand);
         Scenario scenario = builder.build();
         scenario.execute();
diff --git a/test/hotspot/jtreg/compiler/compilercontrol/share/actions/CompileAction.java b/test/hotspot/jtreg/compiler/compilercontrol/share/actions/CompileAction.java
index 515aced38ba..464952d715d 100644
--- a/test/hotspot/jtreg/compiler/compilercontrol/share/actions/CompileAction.java
+++ b/test/hotspot/jtreg/compiler/compilercontrol/share/actions/CompileAction.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
@@ -58,6 +58,13 @@ public class CompileAction {
      */
     public static void checkCompiled(Executable executable,
                                      State state) {
+        { // Dumping the state being checked
+            System.out.println("Checking expected compilation state: {");
+            System.out.println("  method: " + executable);
+            state.toString().lines()
+                    .map(line -> "  " + line).forEach(System.out::println);
+            System.out.println("}");
+        }
         int first = COMP_LEVELS[0];
         if (first < 4) {
             checkCompilation(executable, first, state.isC1Compilable());
diff --git a/test/hotspot/jtreg/compiler/compilercontrol/share/scenario/CompileCommand.java b/test/hotspot/jtreg/compiler/compilercontrol/share/scenario/CompileCommand.java
index 72e6c25cdc9..a22a45191a1 100644
--- a/test/hotspot/jtreg/compiler/compilercontrol/share/scenario/CompileCommand.java
+++ b/test/hotspot/jtreg/compiler/compilercontrol/share/scenario/CompileCommand.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
@@ -57,10 +57,25 @@ public class CompileCommand {
     }
 
     /**
-     * Prints compile command to the system output
+     * Formats the command according to the following pattern:
+     * {@code  Type:  Compiler:  MethodDescriptor:  IsValid: }
+     * Sample output:
+     * COMPILEONLY Type: OPTION Compiler: C1 MethodDescriptor: *Klass.method* IsValid: true
      */
-    public void print() {
-        System.out.printf("%s (type: %s): %s (valid: %b)%n", command.name(),
-                type.name(), methodDescriptor.getString(), isValid());
+    protected String formatFields() {
+        return command.name() +
+               " Type: " + type +
+               " Compiler: " + compiler +
+               " MethodDescriptor: " + (methodDescriptor == null ? "null" : methodDescriptor.getString()) +
+               " IsValid: " + isValid();
+    }
+
+    /**
+     * Returns formatted string representation in the form
+     * {@code "(CompileCommand Field1:  Field2:  ...)}
+     * The fields are formatted by {@link #formatFields()}.
+     */
+    public String toString() {
+        return "(CompileCommand " + formatFields() + ")";
     }
 }
diff --git a/test/hotspot/jtreg/compiler/compilercontrol/share/scenario/JcmdCommand.java b/test/hotspot/jtreg/compiler/compilercontrol/share/scenario/JcmdCommand.java
index 21452c83844..4e38ab5f1a5 100644
--- a/test/hotspot/jtreg/compiler/compilercontrol/share/scenario/JcmdCommand.java
+++ b/test/hotspot/jtreg/compiler/compilercontrol/share/scenario/JcmdCommand.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
@@ -36,4 +36,13 @@ public class JcmdCommand extends CompileCommand {
         super(command, methodDescriptor, compiler, type);
         this.jcmdType = jcmdType;
     }
+
+    /**
+     * Enchances parent's class method with the the JCMDtype printing:
+     * {@code ... JCMDType: }
+     */
+    protected String formatFields() {
+        return super.formatFields() + " JCMDType: " + jcmdType;
+    }
+
 }
diff --git a/test/hotspot/jtreg/compiler/compilercontrol/share/scenario/Scenario.java b/test/hotspot/jtreg/compiler/compilercontrol/share/scenario/Scenario.java
index 8c860de787a..f10b74ad1b6 100644
--- a/test/hotspot/jtreg/compiler/compilercontrol/share/scenario/Scenario.java
+++ b/test/hotspot/jtreg/compiler/compilercontrol/share/scenario/Scenario.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
@@ -214,6 +214,7 @@ public final class Scenario {
         }
 
         public void add(CompileCommand compileCommand) {
+            System.out.println(compileCommand);
             String[] vmOptions = compileCommand.command.vmOpts;
             Collections.addAll(vmopts, vmOptions);
             if (compileCommand.command == Command.LOG) {

From babaab2edb8b2c34559bc461f0c8bdf8b535e70b Mon Sep 17 00:00:00 2001
From: Eric Liu 
Date: Tue, 12 May 2020 10:19:01 +0800
Subject: [PATCH 016/143] 8242429: Better implementation for sign extract

Reviewed-by: vlivanov, thartmann
---
 src/hotspot/cpu/aarch64/aarch64.ad            | 48 ----------
 src/hotspot/share/opto/mulnode.cpp            | 25 ++++-
 src/hotspot/share/opto/subnode.cpp            | 26 ++++-
 .../jtreg/compiler/c2/TestSignExtract.java    | 96 +++++++++++++++++++
 4 files changed, 145 insertions(+), 50 deletions(-)
 create mode 100644 test/hotspot/jtreg/compiler/c2/TestSignExtract.java

diff --git a/src/hotspot/cpu/aarch64/aarch64.ad b/src/hotspot/cpu/aarch64/aarch64.ad
index b72ecef0f28..ddd9b7ad96e 100644
--- a/src/hotspot/cpu/aarch64/aarch64.ad
+++ b/src/hotspot/cpu/aarch64/aarch64.ad
@@ -10574,30 +10574,6 @@ instruct divI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
   ins_pipe(idiv_reg_reg);
 %}
 
-instruct signExtract(iRegINoSp dst, iRegIorL2I src1, immI_31 div1, immI_31 div2) %{
-  match(Set dst (URShiftI (RShiftI src1 div1) div2));
-  ins_cost(INSN_COST);
-  format %{ "lsrw $dst, $src1, $div1" %}
-  ins_encode %{
-    __ lsrw(as_Register($dst$$reg), as_Register($src1$$reg), 31);
-  %}
-  ins_pipe(ialu_reg_shift);
-%}
-
-instruct div2Round(iRegINoSp dst, iRegIorL2I src, immI_31 div1, immI_31 div2) %{
-  match(Set dst (AddI src (URShiftI (RShiftI src div1) div2)));
-  ins_cost(INSN_COST);
-  format %{ "addw $dst, $src, LSR $div1" %}
-
-  ins_encode %{
-    __ addw(as_Register($dst$$reg),
-              as_Register($src$$reg),
-              as_Register($src$$reg),
-              Assembler::LSR, 31);
-  %}
-  ins_pipe(ialu_reg);
-%}
-
 // Long Divide
 
 instruct divL(iRegLNoSp dst, iRegL src1, iRegL src2) %{
@@ -10610,30 +10586,6 @@ instruct divL(iRegLNoSp dst, iRegL src1, iRegL src2) %{
   ins_pipe(ldiv_reg_reg);
 %}
 
-instruct signExtractL(iRegLNoSp dst, iRegL src1, immI_63 div1, immI_63 div2) %{
-  match(Set dst (URShiftL (RShiftL src1 div1) div2));
-  ins_cost(INSN_COST);
-  format %{ "lsr $dst, $src1, $div1" %}
-  ins_encode %{
-    __ lsr(as_Register($dst$$reg), as_Register($src1$$reg), 63);
-  %}
-  ins_pipe(ialu_reg_shift);
-%}
-
-instruct div2RoundL(iRegLNoSp dst, iRegL src, immI_63 div1, immI_63 div2) %{
-  match(Set dst (AddL src (URShiftL (RShiftL src div1) div2)));
-  ins_cost(INSN_COST);
-  format %{ "add $dst, $src, $div1" %}
-
-  ins_encode %{
-    __ add(as_Register($dst$$reg),
-              as_Register($src$$reg),
-              as_Register($src$$reg),
-              Assembler::LSR, 63);
-  %}
-  ins_pipe(ialu_reg);
-%}
-
 // Integer Remainder
 
 instruct modI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
diff --git a/src/hotspot/share/opto/mulnode.cpp b/src/hotspot/share/opto/mulnode.cpp
index 441430c2504..bd081df11d2 100644
--- a/src/hotspot/share/opto/mulnode.cpp
+++ b/src/hotspot/share/opto/mulnode.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, 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
@@ -1166,6 +1166,18 @@ Node *URShiftINode::Ideal(PhaseGVN *phase, bool can_reshape) {
       phase->type(shl->in(2)) == t2 )
     return new AndINode( shl->in(1), phase->intcon(mask) );
 
+  // Check for (x >> n) >>> 31. Replace with (x >>> 31)
+  Node *shr = in(1);
+  if ( in1_op == Op_RShiftI ) {
+    Node *in11 = shr->in(1);
+    Node *in12 = shr->in(2);
+    const TypeInt *t11 = phase->type(in11)->isa_int();
+    const TypeInt *t12 = phase->type(in12)->isa_int();
+    if ( t11 && t2 && t2->is_con(31) && t12 && t12->is_con() ) {
+      return new URShiftINode(in11, phase->intcon(31));
+    }
+  }
+
   return NULL;
 }
 
@@ -1295,6 +1307,17 @@ Node *URShiftLNode::Ideal(PhaseGVN *phase, bool can_reshape) {
       phase->type(shl->in(2)) == t2 )
     return new AndLNode( shl->in(1), phase->longcon(mask) );
 
+  // Check for (x >> n) >>> 63. Replace with (x >>> 63)
+  Node *shr = in(1);
+  if ( shr->Opcode() == Op_RShiftL ) {
+    Node *in11 = shr->in(1);
+    Node *in12 = shr->in(2);
+    const TypeLong *t11 = phase->type(in11)->isa_long();
+    const TypeInt *t12 = phase->type(in12)->isa_int();
+    if ( t11 && t2 && t2->is_con(63) && t12 && t12->is_con() ) {
+      return new URShiftLNode(in11, phase->intcon(63));
+    }
+  }
   return NULL;
 }
 
diff --git a/src/hotspot/share/opto/subnode.cpp b/src/hotspot/share/opto/subnode.cpp
index c1234dd8a0d..4c0eae62ce9 100644
--- a/src/hotspot/share/opto/subnode.cpp
+++ b/src/hotspot/share/opto/subnode.cpp
@@ -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
@@ -252,6 +252,18 @@ Node *SubINode::Ideal(PhaseGVN *phase, bool can_reshape){
     return new SubINode( add1, in2->in(1) );
   }
 
+  // Convert "0-(A>>31)" into "(A>>>31)"
+  if ( op2 == Op_RShiftI ) {
+    Node *in21 = in2->in(1);
+    Node *in22 = in2->in(2);
+    const TypeInt *zero = phase->type(in1)->isa_int();
+    const TypeInt *t21 = phase->type(in21)->isa_int();
+    const TypeInt *t22 = phase->type(in22)->isa_int();
+    if ( t21 && t22 && zero == TypeInt::ZERO && t22->is_con(31) ) {
+      return new URShiftINode(in21, in22);
+    }
+  }
+
   return NULL;
 }
 
@@ -361,6 +373,18 @@ Node *SubLNode::Ideal(PhaseGVN *phase, bool can_reshape) {
     return new SubLNode( add1, in2->in(1) );
   }
 
+  // Convert "0L-(A>>63)" into "(A>>>63)"
+  if ( op2 == Op_RShiftL ) {
+    Node *in21 = in2->in(1);
+    Node *in22 = in2->in(2);
+    const TypeLong *zero = phase->type(in1)->isa_long();
+    const TypeLong *t21 = phase->type(in21)->isa_long();
+    const TypeInt *t22 = phase->type(in22)->isa_int();
+    if ( t21 && t22 && zero == TypeLong::ZERO && t22->is_con(63) ) {
+      return new URShiftLNode(in21, in22);
+    }
+  }
+
   return NULL;
 }
 
diff --git a/test/hotspot/jtreg/compiler/c2/TestSignExtract.java b/test/hotspot/jtreg/compiler/c2/TestSignExtract.java
new file mode 100644
index 00000000000..1fe5687480f
--- /dev/null
+++ b/test/hotspot/jtreg/compiler/c2/TestSignExtract.java
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8242429
+ * @summary Better implementation for sign extract.
+ *
+ * @run main/othervm -XX:-TieredCompilation -XX:CompileCommand=dontinline,compiler.c2.TestSignExtract::signExtract*
+ *      compiler.c2.TestSignExtract
+ */
+package compiler.c2;
+
+public class TestSignExtract {
+
+    private static final long[] LONG_VALUES = {0L, 0xFFFFFFFFL, 0x12L, -1L, -123L, -0x12L, Long.MAX_VALUE, Long.MIN_VALUE};
+    private static final int[] INT_VALUES = {0, 0x1234, -1, -0x12345678, Integer.MAX_VALUE, Integer.MIN_VALUE};
+
+
+    private static int signExtractInt1(int x) {
+        return (x >> 1) >>> 31;
+    }
+
+    private static int signExtractInt2(int x) {
+        return (x >> 32) >>> 31;
+    }
+
+    private static int signExtractInt3(int x) {
+        return (x >> 31) >>> 31;
+    }
+
+    private static int signExtractInt4(int x) {
+        return 0 - (x >> 31);
+    }
+
+    private static long signExtractLong1(long x) {
+        return (x >> 1) >>> 63;
+    }
+
+    private static long signExtractLong2(long x) {
+        return (x >> 54) >>> 63;
+    }
+
+    private static long signExtractLong3(long x) {
+        return (x >> 63) >>> 63;
+    }
+
+    private static long signExtractLong4(long x) {
+        return 0 - (x >> 63);
+    }
+
+    private static int WARMUP = 5000;
+
+    public static void main(String[] args) {
+        for (int i = 0; i < WARMUP; i++) {
+            for (int e : INT_VALUES) {
+                // "(A >> n) >>> 31" => "(A >>> 31)"
+                assert e >>> 31 == signExtractInt1(e);
+                assert e >>> 31 == signExtractInt2(e);
+                assert e >>> 31 == signExtractInt3(e);
+                // "0 - (A >> 31)" => "(A >>> 31)"
+                assert e >>> 31 == signExtractInt4(e);
+            }
+
+            for (long e : LONG_VALUES) {
+                // "(A >> n) >>> 63" => "(A >>> 63)"
+                assert e >>> 63 == signExtractLong1(e);
+                assert e >>> 63 == signExtractLong2(e);
+                assert e >>> 63 == signExtractLong3(e);
+                // "0 - (A >> 63)" => "(A >>> 63)"
+                assert e >>> 63 == signExtractLong4(e);
+            }
+        }
+    }
+}

From 46d287916cc04eb4d78162630150f4767ec28404 Mon Sep 17 00:00:00 2001
From: David Holmes 
Date: Tue, 12 May 2020 00:47:27 -0400
Subject: [PATCH 017/143] 8244779: ProblemList
 serviceability/jvmti/HiddenClass/P/Q/HiddenClassSigTest.java pending
 JDK-8244571

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

diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt
index 429afc335e5..82334a65328 100644
--- a/test/hotspot/jtreg/ProblemList.txt
+++ b/test/hotspot/jtreg/ProblemList.txt
@@ -108,6 +108,7 @@ serviceability/sa/TestRevPtrsForInvokeDynamic.java 8241235 generic-all
 
 serviceability/jvmti/HeapMonitor/MyPackage/HeapMonitorStatIntervalTest.java 8214032 generic-all
 serviceability/jvmti/HeapMonitor/MyPackage/HeapMonitorStatArrayCorrectnessTest.java 8224150 generic-all
+serviceability/jvmti/HiddenClass/P/Q/HiddenClassSigTest.java 8244571 generic-all
 
 #############################################################################
 

From 45e0c6a1811c53b7272088bf320a0e8480e09ee0 Mon Sep 17 00:00:00 2001
From: Aleksey Shipilev 
Date: Tue, 12 May 2020 08:25:17 +0200
Subject: [PATCH 018/143] 8244759: Shenandoah: print verbose class unloading
 counters

Reviewed-by: zgu
---
 .../share/gc/shenandoah/shenandoahHeap.cpp    |  2 +-
 .../gc/shenandoah/shenandoahPhaseTimings.hpp  | 11 ++-
 .../share/gc/shenandoah/shenandoahUnload.cpp  | 81 ++++++++++++-------
 .../share/gc/shenandoah/shenandoahUnload.hpp  |  3 -
 4 files changed, 63 insertions(+), 34 deletions(-)

diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp
index ffa8414dbf2..333d1575f9b 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp
@@ -2878,7 +2878,7 @@ void ShenandoahHeap::entry_weak_roots() {
 
 void ShenandoahHeap::entry_class_unloading() {
   static const char* msg = "Concurrent class unloading";
-  ShenandoahConcurrentPhase gc_phase(msg, ShenandoahPhaseTimings::conc_class_unloading);
+  ShenandoahConcurrentPhase gc_phase(msg, ShenandoahPhaseTimings::conc_class_unload);
   EventMark em("%s", msg);
 
   ShenandoahWorkerScope scope(workers(),
diff --git a/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.hpp b/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.hpp
index 5716b2ca6a9..651c54457d4 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.hpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.hpp
@@ -93,7 +93,16 @@ class outputStream;
   f(conc_weak_roots,                                "Concurrent Weak Roots")           \
   SHENANDOAH_PAR_PHASE_DO(conc_weak_roots_,         "  CWR: ", f)                      \
   f(conc_cleanup_early,                             "Concurrent Cleanup")              \
-  f(conc_class_unloading,                           "Concurrent Class Unloading")      \
+  f(conc_class_unload,                              "Concurrent Class Unloading")      \
+  f(conc_class_unload_unlink,                       "  Unlink Stale")                  \
+  f(conc_class_unload_unlink_sd,                    "    System Dictionary")           \
+  f(conc_class_unload_unlink_weak_klass,            "    Weak Class Links")            \
+  f(conc_class_unload_unlink_code_roots,            "    Code Roots")                  \
+  f(conc_class_unload_rendezvous,                   "  Rendezvous")                    \
+  f(conc_class_unload_purge,                        "  Purge Unlinked")                \
+  f(conc_class_unload_purge_coderoots,              "    Code Roots")                  \
+  f(conc_class_unload_purge_cldg,                   "    CLDG")                        \
+  f(conc_class_unload_purge_ec,                     "    Exception Caches")            \
   f(conc_strong_roots,                              "Concurrent Strong Roots")         \
   SHENANDOAH_PAR_PHASE_DO(conc_strong_roots_,       "  CSR: ", f)                      \
   f(conc_evac,                                      "Concurrent Evacuation")           \
diff --git a/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp b/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp
index 35c64949044..70e8ecd50a4 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp
@@ -37,6 +37,7 @@
 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
 #include "gc/shenandoah/shenandoahNMethod.inline.hpp"
 #include "gc/shenandoah/shenandoahLock.hpp"
+#include "gc/shenandoah/shenandoahPhaseTimings.hpp"
 #include "gc/shenandoah/shenandoahRootProcessor.hpp"
 #include "gc/shenandoah/shenandoahUnload.hpp"
 #include "gc/shenandoah/shenandoahVerifier.hpp"
@@ -135,30 +136,6 @@ void ShenandoahUnload::prepare() {
   DependencyContext::cleaning_start();
 }
 
-void ShenandoahUnload::unlink() {
-  SuspendibleThreadSetJoiner sts;
-  bool unloading_occurred;
-  ShenandoahHeap* const heap = ShenandoahHeap::heap();
-  {
-    MutexLocker cldg_ml(ClassLoaderDataGraph_lock);
-    unloading_occurred = SystemDictionary::do_unloading(heap->gc_timer());
-  }
-
-  Klass::clean_weak_klass_links(unloading_occurred);
-  ShenandoahCodeRoots::unlink(ShenandoahHeap::heap()->workers(), unloading_occurred);
-  DependencyContext::cleaning_end();
-}
-
-void ShenandoahUnload::purge() {
-  {
-    SuspendibleThreadSetJoiner sts;
-    ShenandoahCodeRoots::purge(ShenandoahHeap::heap()->workers());
-  }
-
-  ClassLoaderDataGraph::purge();
-  CodeCache::purge_exception_caches();
-}
-
 class ShenandoahUnloadRendezvousClosure : public HandshakeClosure {
 public:
   ShenandoahUnloadRendezvousClosure() : HandshakeClosure("ShenandoahUnloadRendezvous") {}
@@ -167,19 +144,65 @@ public:
 
 void ShenandoahUnload::unload() {
   assert(ShenandoahConcurrentRoots::can_do_concurrent_class_unloading(), "Why we here?");
-  if (!ShenandoahHeap::heap()->is_concurrent_weak_root_in_progress()) {
+
+  ShenandoahHeap* heap = ShenandoahHeap::heap();
+
+  if (!heap->is_concurrent_weak_root_in_progress()) {
     return;
   }
 
   // Unlink stale metadata and nmethods
-  unlink();
+  {
+    ShenandoahTimingsTracker t(ShenandoahPhaseTimings::conc_class_unload_unlink);
+
+    SuspendibleThreadSetJoiner sts;
+    bool unloadingOccurred;
+    {
+      ShenandoahTimingsTracker t(ShenandoahPhaseTimings::conc_class_unload_unlink_sd);
+      MutexLocker cldgMl(ClassLoaderDataGraph_lock);
+      unloadingOccurred = SystemDictionary::do_unloading(heap->gc_timer());
+    }
+
+    {
+      ShenandoahTimingsTracker t(ShenandoahPhaseTimings::conc_class_unload_unlink_weak_klass);
+      Klass::clean_weak_klass_links(unloadingOccurred);
+    }
+
+    {
+      ShenandoahTimingsTracker t(ShenandoahPhaseTimings::conc_class_unload_unlink_code_roots);
+      ShenandoahCodeRoots::unlink(heap->workers(), unloadingOccurred);
+    }
+
+    DependencyContext::cleaning_end();
+  }
 
   // Make sure stale metadata and nmethods are no longer observable
-  ShenandoahUnloadRendezvousClosure cl;
-  Handshake::execute(&cl);
+  {
+    ShenandoahTimingsTracker t(ShenandoahPhaseTimings::conc_class_unload_rendezvous);
+    ShenandoahUnloadRendezvousClosure cl;
+    Handshake::execute(&cl);
+  }
 
   // Purge stale metadata and nmethods that were unlinked
-  purge();
+  {
+    ShenandoahTimingsTracker t(ShenandoahPhaseTimings::conc_class_unload_purge);
+
+    {
+      ShenandoahTimingsTracker t(ShenandoahPhaseTimings::conc_class_unload_purge_coderoots);
+      SuspendibleThreadSetJoiner sts;
+      ShenandoahCodeRoots::purge(heap->workers());
+    }
+
+    {
+      ShenandoahTimingsTracker t(ShenandoahPhaseTimings::conc_class_unload_purge_cldg);
+      ClassLoaderDataGraph::purge();
+    }
+
+    {
+      ShenandoahTimingsTracker t(ShenandoahPhaseTimings::conc_class_unload_purge_ec);
+      CodeCache::purge_exception_caches();
+    }
+  }
 }
 
 void ShenandoahUnload::finish() {
diff --git a/src/hotspot/share/gc/shenandoah/shenandoahUnload.hpp b/src/hotspot/share/gc/shenandoah/shenandoahUnload.hpp
index d8291abb8d7..9456e21f58d 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoahUnload.hpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahUnload.hpp
@@ -35,9 +35,6 @@ public:
   void prepare();
   void unload();
   void finish();
-private:
-  void unlink();
-  void purge();
 };
 
 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHCLASSUNLOAD_HPP

From cc47d0aa61175c35204327be99460f5772a6c2f1 Mon Sep 17 00:00:00 2001
From: Weijun Wang 
Date: Tue, 12 May 2020 15:15:40 +0800
Subject: [PATCH 019/143] 8244674: Third-party code version check

Reviewed-by: mullan
---
 test/jdk/java/security/misc/Versions.java     | 94 +++++++++++++++++++
 test/jdk/javax/xml/crypto/dsig/Versions.java  | 82 ----------------
 .../util/RegisteredDomain/Versions.java       | 81 ----------------
 3 files changed, 94 insertions(+), 163 deletions(-)
 create mode 100644 test/jdk/java/security/misc/Versions.java
 delete mode 100644 test/jdk/javax/xml/crypto/dsig/Versions.java
 delete mode 100644 test/jdk/sun/security/util/RegisteredDomain/Versions.java

diff --git a/test/jdk/java/security/misc/Versions.java b/test/jdk/java/security/misc/Versions.java
new file mode 100644
index 00000000000..6c14b2bc212
--- /dev/null
+++ b/test/jdk/java/security/misc/Versions.java
@@ -0,0 +1,94 @@
+/*
+ * 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
+ * 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 8232357 8221801 8244674
+ * @summary Make sure version info is consistent between code and license
+ * @run testng Versions
+ */
+
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class Versions {
+
+    Path rootPath = Path.of(System.getProperty("test.root"), "../..");
+    Path legalPath = Path.of(System.getProperty("test.jdk"), "legal");
+
+    @DataProvider(name = "data")
+    public Object[][] createData() {
+        return new Object[][]{
+                {"src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/XMLDSigRI.java",
+                        Pattern.compile("// Apache Santuario XML Security for Java, version (?\\S+)"),
+                        "src/java.xml.crypto/share/legal/santuario.md",
+                        Pattern.compile("## Apache Santuario v(?\\S+)"),
+                        "java.xml.crypto/santuario.md"},
+                {"make/data/publicsuffixlist/VERSION",
+                        Pattern.compile("list/(?[0-9a-f]+)/public_suffix_list.dat"),
+                        "src/java.base/share/legal/public_suffix.md",
+                        Pattern.compile("list/(?[0-9a-f]+)/public_suffix_list.dat"),
+                        "java.base/public_suffix.md"},
+                {"src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/pcsclite.h",
+                        Pattern.compile("#define PCSCLITE_VERSION_NUMBER +\"(?[0-9\\.]+)\""),
+                        "src/java.smartcardio/unix/legal/pcsclite.md",
+                        Pattern.compile("## PC/SC Lite v(?[0-9\\.]+)"),
+                        "java.smartcardio/pcsclite.md"}
+        };
+    }
+
+    @Test(dataProvider = "data")
+    public void Test(String src, Pattern sp, String legal, Pattern lp,
+                     String legalInBuild) throws IOException {
+
+        Path pSrc = rootPath.resolve(src);
+        Path pLegal = rootPath.resolve(legal);
+
+        Assert.assertEquals(fetch(pSrc, sp), fetch(pLegal, lp));
+
+        Path pLegalInBuild = legalPath.resolve(legalInBuild);
+        if (!Files.exists(pLegalInBuild)) {
+            System.out.println("Not an image build, or file platform dependent");
+        } else {
+            Assert.assertEquals(Files.mismatch(pLegal, pLegalInBuild), -1);
+        }
+    }
+
+    // Find a match in path and return the extracted named group
+    static String fetch(Path path, Pattern pattern)
+            throws IOException  {
+        return Files.lines(path)
+                .map(pattern::matcher)
+                .filter(Matcher::find)
+                .findFirst()
+                .map(m -> m.group("n"))
+                .get();
+    }
+}
diff --git a/test/jdk/javax/xml/crypto/dsig/Versions.java b/test/jdk/javax/xml/crypto/dsig/Versions.java
deleted file mode 100644
index f589fb95ca4..00000000000
--- a/test/jdk/javax/xml/crypto/dsig/Versions.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * 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 8232357
- * @library /test/lib
- * @summary Compare version info of Santuario to legal notice
- */
-
-import jdk.test.lib.Asserts;
-
-import java.nio.file.Files;
-import java.nio.file.Path;
-
-public class Versions {
-
-    public static void main(String[] args) throws Exception {
-
-        Path src = Path.of(System.getProperty("test.root"),
-                "../../src/java.xml.crypto");
-        Path legal = Path.of(System.getProperty("test.jdk"), "legal");
-
-        Path provider = src.resolve(
-                "share/classes/org/jcp/xml/dsig/internal/dom/XMLDSigRI.java");
-
-        Path mdInSrc = src.resolve(
-                "share/legal/santuario.md");
-        Path mdInImage = legal.resolve(
-                "java.xml.crypto/santuario.md");
-
-        // Files in src should either both exist or not
-        if (!Files.exists(provider) && !Files.exists(mdInSrc)) {
-            System.out.println("Source not available. Cannot proceed.");
-            return;
-        }
-
-        // The line containing the version number looks like
-        // // Apache Santuario XML Security for Java, version n.n.n
-        String s1 = Files.lines(provider)
-                .filter(s -> s.contains(
-                        "// Apache Santuario XML Security for Java, version "))
-                .findFirst()
-                .get()
-                .replaceFirst(".* ", ""); // keep chars after the last space
-
-        // The first line of this file should look like
-        // ## Apache Santuario v2.1.3
-        String s2 = Files.lines(mdInSrc)
-                .findFirst()
-                .get()
-                .replace("## Apache Santuario v", "");
-
-        Asserts.assertEQ(s1, s2);
-
-        if (Files.exists(legal)) {
-            Asserts.assertTrue(Files.mismatch(mdInSrc, mdInImage) == -1);
-        } else {
-            System.out.println("Warning: skip image compare. Exploded build?");
-        }
-    }
-}
diff --git a/test/jdk/sun/security/util/RegisteredDomain/Versions.java b/test/jdk/sun/security/util/RegisteredDomain/Versions.java
deleted file mode 100644
index 8bf39468770..00000000000
--- a/test/jdk/sun/security/util/RegisteredDomain/Versions.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * 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 8221801
- * @library /test/lib
- * @summary Update src/java.base/share/legal/public_suffix.md
- */
-
-import jdk.test.lib.Asserts;
-
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.Objects;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public class Versions {
-
-    public static void main(String[] args) throws Exception {
-
-        Path root = Path.of(System.getProperty("test.root"));
-        Path jdk = Path.of(System.getProperty("test.jdk"));
-
-        Path version = root.resolve("../../make/data/publicsuffixlist/VERSION");
-        Path mdSrc = root.resolve("../../src/java.base/share/legal/public_suffix.md");
-        Path mdImage = jdk.resolve("legal/java.base/public_suffix.md");
-
-        // Files in src should either both exist or not
-        if (!Files.exists(version) && !Files.exists(mdSrc)) {
-            System.out.println("Source not available. Cannot proceed.");
-            return;
-        }
-
-        String s1 = findURL(version);
-        String s2 = findURL(mdSrc);
-
-        Asserts.assertEQ(s1, s2);
-
-        String s3 = findURL(mdImage);
-        Asserts.assertEQ(s2, s3);
-    }
-
-    static Pattern URL_PATTERN = Pattern.compile(
-            "(https://raw.githubusercontent.com.*?public_suffix_list.dat)");
-
-    static String findURL(Path p) throws IOException  {
-        return Files.lines(p)
-                .map(Versions::matchURL)
-                .filter(Objects::nonNull)
-                .findFirst()
-                .orElseThrow();
-    }
-
-    static String matchURL(String input) {
-        Matcher m = URL_PATTERN.matcher(input);
-        return m.find() ? m.group(1) : null;
-    }
-}

From 52e1bec7bc9a63890a301222829e89b3aeab0fbc Mon Sep 17 00:00:00 2001
From: Xin Liu 
Date: Tue, 12 May 2020 10:59:12 +0200
Subject: [PATCH 020/143] 8022574: remove HaltNode code after uncommon trap
 calls

Reviewed-by: thartmann, mdoerr, simonis
---
 src/hotspot/cpu/aarch64/aarch64.ad  | 6 +++---
 src/hotspot/cpu/arm/arm.ad          | 5 +++--
 src/hotspot/cpu/ppc/ppc.ad          | 7 ++++---
 src/hotspot/cpu/s390/s390.ad        | 7 +++++--
 src/hotspot/cpu/x86/x86.ad          | 6 ++++--
 src/hotspot/share/adlc/output_c.cpp | 1 +
 src/hotspot/share/opto/graphKit.cpp | 3 ++-
 src/hotspot/share/opto/machnode.hpp | 4 ++++
 src/hotspot/share/opto/rootnode.cpp | 3 ++-
 src/hotspot/share/opto/rootnode.hpp | 3 ++-
 10 files changed, 30 insertions(+), 15 deletions(-)

diff --git a/src/hotspot/cpu/aarch64/aarch64.ad b/src/hotspot/cpu/aarch64/aarch64.ad
index ddd9b7ad96e..c9f94e46d50 100644
--- a/src/hotspot/cpu/aarch64/aarch64.ad
+++ b/src/hotspot/cpu/aarch64/aarch64.ad
@@ -15285,9 +15285,9 @@ instruct ShouldNotReachHere() %{
   format %{ "ShouldNotReachHere" %}
 
   ins_encode %{
-    // +1 so NativeInstruction::is_sigill_zombie_not_entrant() doesn't
-    // return true
-    __ dpcs1(0xdead + 1);
+    if (is_reachable()) {
+      __ dpcs1(0xdead + 1);
+    }
   %}
 
   ins_pipe(pipe_class_default);
diff --git a/src/hotspot/cpu/arm/arm.ad b/src/hotspot/cpu/arm/arm.ad
index 8c2a1c00692..f6d47638723 100644
--- a/src/hotspot/cpu/arm/arm.ad
+++ b/src/hotspot/cpu/arm/arm.ad
@@ -8959,11 +8959,12 @@ instruct ShouldNotReachHere( )
   match(Halt);
   ins_cost(CALL_COST);
 
-  size(4);
   // Use the following format syntax
   format %{ "ShouldNotReachHere" %}
   ins_encode %{
-    __ udf(0xdead);
+    if (is_reachable()) {
+      __ udf(0xdead);
+    }
   %}
   ins_pipe(tail_call);
 %}
diff --git a/src/hotspot/cpu/ppc/ppc.ad b/src/hotspot/cpu/ppc/ppc.ad
index d4c33d45617..ecf2b32f86d 100644
--- a/src/hotspot/cpu/ppc/ppc.ad
+++ b/src/hotspot/cpu/ppc/ppc.ad
@@ -15136,10 +15136,11 @@ instruct ShouldNotReachHere() %{
   ins_cost(CALL_COST);
 
   format %{ "ShouldNotReachHere" %}
-  size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_tdi);
-    __ trap_should_not_reach_here();
+    if (is_reachable()) {
+      // TODO: PPC port $archOpcode(ppc64Opcode_tdi);
+      __ trap_should_not_reach_here();
+    }
   %}
   ins_pipe(pipe_class_default);
 %}
diff --git a/src/hotspot/cpu/s390/s390.ad b/src/hotspot/cpu/s390/s390.ad
index 68314d6c96e..69d234fe583 100644
--- a/src/hotspot/cpu/s390/s390.ad
+++ b/src/hotspot/cpu/s390/s390.ad
@@ -9886,9 +9886,12 @@ instruct RethrowException() %{
 instruct ShouldNotReachHere() %{
   match(Halt);
   ins_cost(CALL_COST);
-  size(2);
   format %{ "ILLTRAP; ShouldNotReachHere" %}
-  ins_encode %{ __ z_illtrap(); %}
+  ins_encode %{
+    if (is_reachable()) {
+      __ z_illtrap();
+    }
+  %}
   ins_pipe(pipe_class_dummy);
 %}
 
diff --git a/src/hotspot/cpu/x86/x86.ad b/src/hotspot/cpu/x86/x86.ad
index ec8cab21de9..6fc47c25b69 100644
--- a/src/hotspot/cpu/x86/x86.ad
+++ b/src/hotspot/cpu/x86/x86.ad
@@ -2341,9 +2341,11 @@ operand cmpOp_vcmppd() %{
 
 instruct ShouldNotReachHere() %{
   match(Halt);
-  format %{ "ud2\t# ShouldNotReachHere" %}
+  format %{ "stop\t# ShouldNotReachHere" %}
   ins_encode %{
-    __ stop(_halt_reason);
+    if (is_reachable()) {
+      __ stop(_halt_reason);
+    }
   %}
   ins_pipe(pipe_slow);
 %}
diff --git a/src/hotspot/share/adlc/output_c.cpp b/src/hotspot/share/adlc/output_c.cpp
index 580d42e2752..7b1e8b024dd 100644
--- a/src/hotspot/share/adlc/output_c.cpp
+++ b/src/hotspot/share/adlc/output_c.cpp
@@ -3941,6 +3941,7 @@ void ArchDesc::buildMachNode(FILE *fp_cpp, InstructForm *inst, const char *inden
   }
   if (inst->is_ideal_halt()) {
     fprintf(fp_cpp, "%s node->_halt_reason = _leaf->as_Halt()->_halt_reason;\n", indent);
+    fprintf(fp_cpp, "%s node->_reachable   = _leaf->as_Halt()->_reachable;\n", indent);
   }
   if (inst->is_ideal_jump()) {
     fprintf(fp_cpp, "%s node->_probs = _leaf->as_Jump()->_probs;\n", indent);
diff --git a/src/hotspot/share/opto/graphKit.cpp b/src/hotspot/share/opto/graphKit.cpp
index 9838473ecbf..15c4e255129 100644
--- a/src/hotspot/share/opto/graphKit.cpp
+++ b/src/hotspot/share/opto/graphKit.cpp
@@ -2113,7 +2113,8 @@ void GraphKit::uncommon_trap(int trap_request,
   // The debug info is the only real input to this call.
 
   // Halt-and-catch fire here.  The above call should never return!
-  HaltNode* halt = new HaltNode(control(), frameptr(), "uncommon trap returned which should never happen");
+  HaltNode* halt = new HaltNode(control(), frameptr(), "uncommon trap returned which should never happen"
+                                                       PRODUCT_ONLY(COMMA /*reachable*/false));
   _gvn.set_type_bottom(halt);
   root()->add_req(halt);
 
diff --git a/src/hotspot/share/opto/machnode.hpp b/src/hotspot/share/opto/machnode.hpp
index e20a7eb3d8e..f901206f16a 100644
--- a/src/hotspot/share/opto/machnode.hpp
+++ b/src/hotspot/share/opto/machnode.hpp
@@ -1010,8 +1010,12 @@ public:
 // Machine-specific versions of halt nodes
 class MachHaltNode : public MachReturnNode {
 public:
+  bool _reachable;
   const char* _halt_reason;
   virtual JVMState* jvms() const;
+  bool is_reachable() const {
+    return _reachable;
+  }
 };
 
 class MachMemBarNode : public MachNode {
diff --git a/src/hotspot/share/opto/rootnode.cpp b/src/hotspot/share/opto/rootnode.cpp
index 82cd0334cfe..6d4270732ac 100644
--- a/src/hotspot/share/opto/rootnode.cpp
+++ b/src/hotspot/share/opto/rootnode.cpp
@@ -62,7 +62,8 @@ Node *RootNode::Ideal(PhaseGVN *phase, bool can_reshape) {
 }
 
 //=============================================================================
-HaltNode::HaltNode(Node* ctrl, Node* frameptr, const char* halt_reason) : Node(TypeFunc::Parms), _halt_reason(halt_reason) {
+HaltNode::HaltNode(Node* ctrl, Node* frameptr, const char* halt_reason, bool reachable)
+                        : Node(TypeFunc::Parms), _halt_reason(halt_reason), _reachable(reachable) {
   init_class_id(Class_Halt);
   Node* top = Compile::current()->top();
   init_req(TypeFunc::Control,  ctrl        );
diff --git a/src/hotspot/share/opto/rootnode.hpp b/src/hotspot/share/opto/rootnode.hpp
index 3af26df207c..f71acf8baca 100644
--- a/src/hotspot/share/opto/rootnode.hpp
+++ b/src/hotspot/share/opto/rootnode.hpp
@@ -52,7 +52,8 @@ public:
 class HaltNode : public Node {
 public:
   const char* _halt_reason;
-  HaltNode(Node* ctrl, Node* frameptr, const char* halt_reason);
+  bool        _reachable;
+  HaltNode(Node* ctrl, Node* frameptr, const char* halt_reason, bool reachable = true);
   virtual int Opcode() const;
   virtual bool  pinned() const { return true; };
   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);

From b29d982a9c87db0db0fdaf8a4354e06d542469bf Mon Sep 17 00:00:00 2001
From: Magnus Ihse Bursie 
Date: Tue, 12 May 2020 11:11:02 +0200
Subject: [PATCH 021/143] 8244756: Build broken with some awk version after
 JDK-8244248

Reviewed-by: mbaesken, xliu
---
 make/autoconf/boot-jdk.m4 | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/make/autoconf/boot-jdk.m4 b/make/autoconf/boot-jdk.m4
index 323035744a7..dc443815948 100644
--- a/make/autoconf/boot-jdk.m4
+++ b/make/autoconf/boot-jdk.m4
@@ -75,7 +75,7 @@ AC_DEFUN([BOOTJDK_DO_CHECK],
         else
           # Oh, this is looking good! We probably have found a proper JDK. Is it the correct version?
           # Additional [] needed to keep m4 from mangling shell constructs.
-          [ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java$EXE_SUFFIX" $USER_BOOT_JDK_OPTIONS -version 2>&1 | $AWK '/version \"[0-9\._\-a-zA-Z]+\"/{print $ 0; exit;}'` ]
+          [ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java$EXE_SUFFIX" $USER_BOOT_JDK_OPTIONS -version 2>&1 | $AWK '/version \"[0-9a-zA-Z\._\-]+\"/{print $ 0; exit;}'` ]
           if [ [[ "$BOOT_JDK_VERSION" =~ "Picked up" ]] ]; then
             AC_MSG_NOTICE([You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead.])
             AC_MSG_NOTICE([Java reports: "$BOOT_JDK_VERSION".])
@@ -531,7 +531,7 @@ AC_DEFUN([BOOTJDK_CHECK_BUILD_JDK],
       else
         # Oh, this is looking good! We probably have found a proper JDK. Is it the correct version?
         # Additional [] needed to keep m4 from mangling shell constructs.
-        [ BUILD_JDK_VERSION=`"$BUILD_JDK/bin/java" -version 2>&1 | $AWK '/version \"[0-9\._\-a-zA-Z]+\"/{print $ 0; exit;}'` ]
+        [ BUILD_JDK_VERSION=`"$BUILD_JDK/bin/java" -version 2>&1 | $AWK '/version \"[0-9a-zA-Z\._\-]+\"/{print $ 0; exit;}'` ]
 
         # Extra M4 quote needed to protect [] in grep expression.
         [FOUND_CORRECT_VERSION=`echo $BUILD_JDK_VERSION | $EGREP "\"$VERSION_FEATURE([\.+-].*)?\""`]

From a6cdce140450a9d6750df560ce179428380e4733 Mon Sep 17 00:00:00 2001
From: Erik Gahlin 
Date: Tue, 12 May 2020 15:20:15 +0200
Subject: [PATCH 022/143] 8244661: JFR: Remove use of thread-locals for
 java.base events

Reviewed-by: jbachorik, mgronlun
---
 .../jdk/jfr/events/ErrorThrownEvent.java      |   5 +-
 .../jdk/jfr/events/ExceptionThrownEvent.java  |   5 +-
 .../jdk/jfr/events/FileForceEvent.java        |  15 +-
 .../classes/jdk/jfr/events/FileReadEvent.java |  16 +--
 .../jdk/jfr/events/FileWriteEvent.java        |  15 +-
 .../classes/jdk/jfr/events/Handlers.java      |  38 +++++
 .../jdk/jfr/events/SocketReadEvent.java       |  19 +--
 .../jdk/jfr/events/SocketWriteEvent.java      |  17 +--
 .../share/classes/jdk/jfr/internal/Utils.java |   2 +-
 .../jfr/internal/handlers/EventHandler.java   |  28 ++++
 .../FileChannelImplInstrumentor.java          | 133 ++++++++++--------
 .../FileInputStreamInstrumentor.java          |  68 +++++----
 .../FileOutputStreamInstrumentor.java         |  56 +++++---
 .../RandomAccessFileInstrumentor.java         | 120 +++++++++-------
 .../SocketChannelImplInstrumentor.java        | 104 +++++++-------
 .../SocketInputStreamInstrumentor.java        |  31 ++--
 .../SocketOutputStreamInstrumentor.java       |  30 ++--
 .../internal/instrument/ThrowableTracer.java  |  34 ++---
 18 files changed, 394 insertions(+), 342 deletions(-)
 create mode 100644 src/jdk.jfr/share/classes/jdk/jfr/events/Handlers.java

diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/ErrorThrownEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/ErrorThrownEvent.java
index 64efc7049df..ccc27946efd 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/events/ErrorThrownEvent.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/events/ErrorThrownEvent.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
@@ -36,6 +36,9 @@ import jdk.jfr.internal.Type;
 @Description("An object derived from java.lang.Error has been created. OutOfMemoryErrors are ignored")
 public final class ErrorThrownEvent extends AbstractJDKEvent {
 
+    // The order of these fields must be the same as the parameters in
+    // EventHandler::write(..., String, Class)
+
     @Label("Message")
     public String message;
 
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/ExceptionThrownEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/ExceptionThrownEvent.java
index 1489803ee89..d03a9336a4f 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/events/ExceptionThrownEvent.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/events/ExceptionThrownEvent.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
@@ -37,6 +37,9 @@ import jdk.jfr.internal.Type;
 @Description("An object derived from java.lang.Exception has been created")
 public final class ExceptionThrownEvent extends AbstractJDKEvent {
 
+    // The order of these fields must be the same as the parameters in
+    // EventHandler::write(..., String, Class)
+
     @Label("Message")
     public String message;
 
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/FileForceEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/FileForceEvent.java
index 6a21bfa8301..c093676fbff 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/events/FileForceEvent.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/events/FileForceEvent.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2018, 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
@@ -37,12 +37,8 @@ import jdk.jfr.internal.Type;
 @Description("Force updates to be written to file")
 public final class FileForceEvent extends AbstractJDKEvent {
 
-    public static final ThreadLocal EVENT =
-        new ThreadLocal<>() {
-            @Override protected FileForceEvent initialValue() {
-                return new FileForceEvent();
-            }
-        };
+    // The order of these fields must be the same as the parameters in
+    // EventHandler::write(..., String, boolean)
 
     @Label("Path")
     @Description("Full path of the file")
@@ -51,9 +47,4 @@ public final class FileForceEvent extends AbstractJDKEvent {
     @Label("Update Metadata")
     @Description("Whether the file metadata is updated")
     public boolean metaData;
-
-    public void reset() {
-        path = null;
-        metaData = false;
-    }
 }
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/FileReadEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/FileReadEvent.java
index bbd412a6352..703f0d1271c 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/events/FileReadEvent.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/events/FileReadEvent.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
@@ -38,12 +38,8 @@ import jdk.jfr.internal.Type;
 @Description("Reading data from a file")
 public final class FileReadEvent extends AbstractJDKEvent {
 
-    public static final ThreadLocal EVENT =
-        new ThreadLocal<>() {
-            @Override protected FileReadEvent initialValue() {
-                return new FileReadEvent();
-            }
-        };
+    // The order of these fields must be the same as the parameters in
+    // EventHandler::write(..., String, long, boolean)
 
     @Label("Path")
     @Description("Full path of the file")
@@ -57,10 +53,4 @@ public final class FileReadEvent extends AbstractJDKEvent {
     @Label("End of File")
     @Description("If end of file was reached")
     public boolean endOfFile;
-
-    public void reset() {
-        path = null;
-        endOfFile = false;
-        bytesRead = 0;
-    }
 }
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/FileWriteEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/FileWriteEvent.java
index 3d291b75f02..7554fee09c2 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/events/FileWriteEvent.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/events/FileWriteEvent.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
@@ -38,12 +38,8 @@ import jdk.jfr.internal.Type;
 @Description("Writing data to a file")
 public final class FileWriteEvent extends AbstractJDKEvent {
 
-    public static final ThreadLocal EVENT =
-        new ThreadLocal<>() {
-            @Override protected FileWriteEvent initialValue() {
-                return new FileWriteEvent();
-            }
-        };
+    // The order of these fields must be the same as the parameters in
+    // EventHandler::write(..., String, long)
 
     @Label("Path")
     @Description("Full path of the file")
@@ -53,9 +49,4 @@ public final class FileWriteEvent extends AbstractJDKEvent {
     @Description("Number of bytes written to the file")
     @DataAmount
     public long bytesWritten;
-
-    public void reset() {
-        path = null;
-        bytesWritten = 0;
-    }
 }
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/Handlers.java b/src/jdk.jfr/share/classes/jdk/jfr/events/Handlers.java
new file mode 100644
index 00000000000..4f5c7b0a1d3
--- /dev/null
+++ b/src/jdk.jfr/share/classes/jdk/jfr/events/Handlers.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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jfr.events;
+import jdk.jfr.internal.handlers.EventHandler;
+import jdk.jfr.internal.Utils;
+
+public final class Handlers {
+    public final static EventHandler SOCKET_READ = Utils.getHandler(SocketReadEvent.class);
+    public final static EventHandler SOCKET_WRITE = Utils.getHandler(SocketWriteEvent.class);
+    public final static EventHandler FILE_READ = Utils.getHandler(FileReadEvent.class);
+    public final static EventHandler FILE_WRITE = Utils.getHandler(FileWriteEvent.class);
+    public final static EventHandler FILE_FORCE = Utils.getHandler(FileForceEvent.class);
+    public final static EventHandler ERROR_THROWN = Utils.getHandler(ErrorThrownEvent.class);
+    public final static EventHandler EXCEPTION_THROWN = Utils.getHandler(ExceptionThrownEvent.class);
+}
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/SocketReadEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/SocketReadEvent.java
index 856ccf14861..faf11802c62 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/events/SocketReadEvent.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/events/SocketReadEvent.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
@@ -39,12 +39,8 @@ import jdk.jfr.internal.Type;
 @Description("Reading data from a socket")
 public final class SocketReadEvent extends AbstractJDKEvent {
 
-    public static final ThreadLocal EVENT =
-        new ThreadLocal<>() {
-            @Override protected SocketReadEvent initialValue() {
-                return new SocketReadEvent();
-            }
-        };
+    // The order of these fields must be the same as the parameters in
+    // EventHandler::write(..., String, String, int, long, long, boolean)
 
     @Label("Remote Host")
     public String host;
@@ -67,13 +63,4 @@ public final class SocketReadEvent extends AbstractJDKEvent {
     @Label("End of Stream")
     @Description("If end of stream was reached")
     public boolean endOfStream;
-
-    public void reset() {
-        host = null;
-        address = null;
-        port = 0;
-        timeout = 0;
-        bytesRead = 0L;
-        endOfStream = false;
-    }
 }
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/SocketWriteEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/SocketWriteEvent.java
index 8fa71e958cb..864a411426f 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/events/SocketWriteEvent.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/events/SocketWriteEvent.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
@@ -38,12 +38,8 @@ import jdk.jfr.internal.Type;
 @Description("Writing data to a socket")
 public final class SocketWriteEvent extends AbstractJDKEvent {
 
-    public static final ThreadLocal EVENT =
-        new ThreadLocal<>() {
-            @Override protected SocketWriteEvent initialValue() {
-                return new SocketWriteEvent();
-            }
-        };
+    // The order of these fields must be the same as the parameters in
+    // EventHandler::write(..., String, String, int, long)
 
     @Label("Remote Host")
     public String host;
@@ -58,11 +54,4 @@ public final class SocketWriteEvent extends AbstractJDKEvent {
     @Description("Number of bytes written to the socket")
     @DataAmount
     public long bytesWritten;
-
-    public void reset() {
-        host = null;
-        address = null;
-        port = 0;
-        bytesWritten = 0;
-    }
 }
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/Utils.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/Utils.java
index 264f7e7e182..7f5fb13dd19 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/Utils.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/Utils.java
@@ -350,7 +350,7 @@ public final class Utils {
         return (long) (nanos * JVM.getJVM().getTimeConversionFactor());
     }
 
-    static synchronized EventHandler getHandler(Class eventClass) {
+    public static synchronized EventHandler getHandler(Class eventClass) {
         Utils.ensureValidEventSubclass(eventClass);
         try {
             Field f = eventClass.getDeclaredField(EventInstrumentation.FIELD_EVENT_HANDLER);
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/handlers/EventHandler.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/handlers/EventHandler.java
index 00ecd760967..df8615910a7 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/handlers/EventHandler.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/handlers/EventHandler.java
@@ -114,4 +114,32 @@ public abstract class EventHandler {
     public boolean setRegistered(boolean registered) {
        return platformEventType.setRegistered(registered);
     }
+
+    public void write(long start, long duration, String host, String address, int port, long timeout, long bytesRead, boolean endOfSTream) {
+        throwError("SocketReadEvent");
+    }
+
+    public void write(long start, long duration, String host, String address, int port, long bytesWritten) {
+        throwError("SocketWriteEvent");
+    }
+
+    public void write(long start, long duration, String path, boolean metadata) {
+        throwError("FileForceEvent");
+    }
+
+    public void write(long start, long duration, String path, long bytesRead, boolean endOfFile) {
+        throwError("FileReadEvent");
+    }
+
+    public void write(long start, long duration, String path, long bytesWritten) {
+        throwError("FileWriteEvent");
+    }
+
+    public void write(long start, long duration, String path, Class exceptionClass)  {
+        throwError("ExceptionThrownEvent or ErrorThrownEvent");
+    }
+
+    private void throwError(String classes) {
+        throw new InternalError("Method parameters don't match fields in class " + classes);
+    }
 }
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/FileChannelImplInstrumentor.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/FileChannelImplInstrumentor.java
index 18d09c48c9d..7d3ece33f96 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/FileChannelImplInstrumentor.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/FileChannelImplInstrumentor.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
@@ -28,9 +28,8 @@ package jdk.jfr.internal.instrument;
 import java.io.IOException;
 import java.nio.ByteBuffer;
 
-import jdk.jfr.events.FileForceEvent;
-import jdk.jfr.events.FileReadEvent;
-import jdk.jfr.events.FileWriteEvent;
+import jdk.jfr.events.Handlers;
+import jdk.jfr.internal.handlers.EventHandler;
 
 /**
  * See {@link JITracer} for an explanation of this code.
@@ -46,42 +45,44 @@ final class FileChannelImplInstrumentor {
     @SuppressWarnings("deprecation")
     @JIInstrumentationMethod
     public void force(boolean metaData) throws IOException {
-        FileForceEvent event = FileForceEvent.EVENT.get();
-        if (!event.isEnabled()) {
+        EventHandler handler = Handlers.FILE_FORCE;
+        if (!handler.isEnabled()) {
             force(metaData);
             return;
         }
+        long start = 0;
         try {
-            event.begin();
+            start = EventHandler.timestamp();
             force(metaData);
         } finally {
-            event.path = path;
-            event.metaData = metaData;
-            event.commit();
-            event.reset();
+            long duration = EventHandler.timestamp() - start;
+            if (handler.shouldCommit(duration)) {
+                handler.write(start, duration, path, metaData);
+            }
         }
     }
 
     @SuppressWarnings("deprecation")
     @JIInstrumentationMethod
     public int read(ByteBuffer dst) throws IOException {
-        FileReadEvent event = FileReadEvent.EVENT.get();
-        if (!event.isEnabled()) {
+        EventHandler handler = Handlers.FILE_READ;
+        if (!handler.isEnabled()) {
             return read(dst);
         }
         int bytesRead = 0;
+        long start = 0;
         try {
-            event.begin();
+            start = EventHandler.timestamp();
             bytesRead = read(dst);
         } finally {
-            if (bytesRead < 0) {
-                event.endOfFile = true;
-            } else {
-                event.bytesRead = bytesRead;
+            long duration = EventHandler.timestamp() - start;
+            if (handler.shouldCommit(duration)) {
+                if (bytesRead < 0) {
+                    handler.write(start, duration, path, 0L, true);
+                } else {
+                    handler.write(start, duration, path, bytesRead, false);
+                }
             }
-            event.path = path;
-            event.commit();
-            event.reset();
         }
         return bytesRead;
     }
@@ -89,23 +90,24 @@ final class FileChannelImplInstrumentor {
     @SuppressWarnings("deprecation")
     @JIInstrumentationMethod
     public int read(ByteBuffer dst, long position) throws IOException {
-        FileReadEvent event = FileReadEvent.EVENT.get();
-        if (!event.isEnabled()) {
+        EventHandler handler = Handlers.FILE_READ;
+        if (!handler.isEnabled()) {
             return read(dst, position);
         }
         int bytesRead = 0;
+        long start = 0;
         try {
-            event.begin();
+            start = EventHandler.timestamp();
             bytesRead = read(dst, position);
         } finally {
-            if (bytesRead < 0) {
-                event.endOfFile = true;
-            } else {
-                event.bytesRead = bytesRead;
+            long duration = EventHandler.timestamp() - start;
+            if (handler.shouldCommit(duration)) {
+                if (bytesRead < 0) {
+                    handler.write(start, duration, path, 0L, true);
+                } else {
+                    handler.write(start, duration, path, bytesRead, false);
+                }
             }
-            event.path = path;
-            event.commit();
-            event.reset();
         }
         return bytesRead;
     }
@@ -113,23 +115,24 @@ final class FileChannelImplInstrumentor {
     @SuppressWarnings("deprecation")
     @JIInstrumentationMethod
     public long read(ByteBuffer[] dsts, int offset, int length) throws IOException {
-        FileReadEvent event = FileReadEvent.EVENT.get();
-        if (!event.isEnabled()) {
+        EventHandler handler = Handlers.FILE_READ;
+        if (!handler.isEnabled()) {
             return read(dsts, offset, length);
         }
         long bytesRead = 0;
+        long start = 0;
         try {
-            event.begin();
+            start = EventHandler.timestamp();
             bytesRead = read(dsts, offset, length);
         } finally {
-            if (bytesRead < 0) {
-                event.endOfFile = true;
-            } else {
-                event.bytesRead = bytesRead;
+            long duration = EventHandler.timestamp() - start;
+            if (handler.shouldCommit(duration)) {
+                if (bytesRead < 0) {
+                    handler.write(start, duration, path, 0L, true);
+                } else {
+                    handler.write(start, duration, path, bytesRead, false);
+                }
             }
-            event.path = path;
-            event.commit();
-            event.reset();
         }
         return bytesRead;
     }
@@ -137,19 +140,21 @@ final class FileChannelImplInstrumentor {
     @SuppressWarnings("deprecation")
     @JIInstrumentationMethod
     public int write(ByteBuffer src) throws IOException {
-        FileWriteEvent event = FileWriteEvent.EVENT.get();
-        if (!event.isEnabled()) {
+        EventHandler handler = Handlers.FILE_WRITE;
+        if (!handler.isEnabled()) {
             return write(src);
         }
         int bytesWritten = 0;
+        long start = 0;
         try {
-            event.begin();
+            start = EventHandler.timestamp();
             bytesWritten = write(src);
         } finally {
-            event.bytesWritten = bytesWritten > 0 ? bytesWritten : 0;
-            event.path = path;
-            event.commit();
-            event.reset();
+            long duration = EventHandler.timestamp() - start;
+            if (handler.shouldCommit(duration)) {
+                long bytes = bytesWritten > 0 ? bytesWritten : 0;
+                handler.write(start, duration, path, bytes);
+            }
         }
         return bytesWritten;
     }
@@ -157,20 +162,22 @@ final class FileChannelImplInstrumentor {
     @SuppressWarnings("deprecation")
     @JIInstrumentationMethod
     public int write(ByteBuffer src, long position) throws IOException {
-        FileWriteEvent event = FileWriteEvent.EVENT.get();
-        if (!event.isEnabled()) {
+        EventHandler handler = Handlers.FILE_WRITE;
+        if (!handler.isEnabled()) {
             return write(src, position);
         }
 
         int bytesWritten = 0;
+        long start = 0;
         try {
-            event.begin();
+            start = EventHandler.timestamp();
             bytesWritten = write(src, position);
         } finally {
-            event.bytesWritten = bytesWritten > 0 ? bytesWritten : 0;
-            event.path = path;
-            event.commit();
-            event.reset();
+            long duration = EventHandler.timestamp() - start;
+            if (handler.shouldCommit(duration)) {
+                long bytes = bytesWritten > 0 ? bytesWritten : 0;
+                handler.write(start, duration, path, bytes);
+            }
         }
         return bytesWritten;
     }
@@ -178,19 +185,21 @@ final class FileChannelImplInstrumentor {
     @SuppressWarnings("deprecation")
     @JIInstrumentationMethod
     public long write(ByteBuffer[] srcs, int offset, int length) throws IOException {
-        FileWriteEvent event = FileWriteEvent.EVENT.get();
-        if (!event.isEnabled()) {
+        EventHandler handler = Handlers.FILE_WRITE;
+        if (!handler.isEnabled()) {
             return write(srcs, offset, length);
         }
         long bytesWritten = 0;
+        long start = 0;
         try {
-            event.begin();
+            start = EventHandler.timestamp();
             bytesWritten = write(srcs, offset, length);
         } finally {
-            event.bytesWritten = bytesWritten > 0 ? bytesWritten : 0;
-            event.path = path;
-            event.commit();
-            event.reset();
+            long duration = EventHandler.timestamp() - start;
+            if (handler.shouldCommit(duration)) {
+                long bytes = bytesWritten > 0 ? bytesWritten : 0;
+                handler.write(start, duration, path, bytes);
+            }
         }
         return bytesWritten;
     }
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/FileInputStreamInstrumentor.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/FileInputStreamInstrumentor.java
index 1a0699b7760..d6150dff2cc 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/FileInputStreamInstrumentor.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/FileInputStreamInstrumentor.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
@@ -27,7 +27,8 @@ package jdk.jfr.internal.instrument;
 
 import java.io.IOException;
 
-import jdk.jfr.events.FileReadEvent;
+import jdk.jfr.events.Handlers;
+import jdk.jfr.internal.handlers.EventHandler;
 
 /**
  * See {@link JITracer} for an explanation of this code.
@@ -43,23 +44,27 @@ final class FileInputStreamInstrumentor {
     @SuppressWarnings("deprecation")
     @JIInstrumentationMethod
     public int read() throws IOException {
-        FileReadEvent event = FileReadEvent.EVENT.get();
-        if (!event.isEnabled()) {
+        EventHandler handler = Handlers.FILE_READ;
+        if (!handler.isEnabled()) {
             return read();
         }
         int result = 0;
+        boolean endOfFile = false;
+        long bytesRead = 0;
+        long start = 0;
         try {
-            event.begin();
+            start = EventHandler.timestamp();
             result = read();
             if (result < 0) {
-                event.endOfFile = true;
+                endOfFile = true;
             } else {
-                event.bytesRead = 1;
+                bytesRead = 1;
             }
         } finally {
-            event.path = path;
-            event.commit();
-            event.reset();
+            long duration = EventHandler.timestamp() - start;
+            if (handler.shouldCommit(duration)) {
+                handler.write(start, duration, path, bytesRead, endOfFile);
+            }
         }
         return result;
     }
@@ -67,23 +72,24 @@ final class FileInputStreamInstrumentor {
     @SuppressWarnings("deprecation")
     @JIInstrumentationMethod
     public int read(byte b[]) throws IOException {
-        FileReadEvent event = FileReadEvent.EVENT.get();
-        if (!event.isEnabled()) {
+        EventHandler handler = Handlers.FILE_READ;
+        if (!handler.isEnabled()) {
             return read(b);
         }
         int bytesRead = 0;
+        long start = 0;
         try {
-            event.begin();
+            start = EventHandler.timestamp();
             bytesRead = read(b);
         } finally {
-            if (bytesRead < 0) {
-                event.endOfFile = true;
-            } else {
-                event.bytesRead = bytesRead;
+            long duration = EventHandler.timestamp() - start;
+            if (handler.shouldCommit(duration)) {
+                if (bytesRead < 0) {
+                    handler.write(start, duration, path, 0L, true);
+                } else {
+                    handler.write(start, duration, path, bytesRead, false);
+                }
             }
-            event.path = path;
-            event.commit();
-            event.reset();
         }
         return bytesRead;
     }
@@ -91,25 +97,25 @@ final class FileInputStreamInstrumentor {
     @SuppressWarnings("deprecation")
     @JIInstrumentationMethod
     public int read(byte b[], int off, int len) throws IOException {
-        FileReadEvent event = FileReadEvent.EVENT.get();
-        if (!event.isEnabled()) {
+        EventHandler handler = Handlers.FILE_READ;
+        if (!handler.isEnabled()) {
             return read(b, off, len);
         }
         int bytesRead = 0;
+        long start = 0;
         try {
-            event.begin();
+            start = EventHandler.timestamp();
             bytesRead = read(b, off, len);
         } finally {
-            if (bytesRead < 0) {
-                event.endOfFile = true;
-            } else {
-                event.bytesRead = bytesRead;
+            long duration = EventHandler.timestamp() - start;
+            if (handler.shouldCommit(duration)) {
+                if (bytesRead < 0) {
+                    handler.write(start, duration, path, 0L, true);
+                } else {
+                    handler.write(start, duration, path, bytesRead, false);
+                }
             }
-            event.path = path;
-            event.commit();
-            event.reset();
         }
         return bytesRead;
     }
-
 }
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/FileOutputStreamInstrumentor.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/FileOutputStreamInstrumentor.java
index 21139854eac..5c1c85cad2d 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/FileOutputStreamInstrumentor.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/FileOutputStreamInstrumentor.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
@@ -27,7 +27,8 @@ package jdk.jfr.internal.instrument;
 
 import java.io.IOException;
 
-import jdk.jfr.events.FileWriteEvent;
+import jdk.jfr.events.Handlers;
+import jdk.jfr.internal.handlers.EventHandler;
 
 /**
  * See {@link JITracer} for an explanation of this code.
@@ -43,57 +44,66 @@ final class FileOutputStreamInstrumentor {
     @SuppressWarnings("deprecation")
     @JIInstrumentationMethod
     public void write(int b) throws IOException {
-        FileWriteEvent event = FileWriteEvent.EVENT.get();
-        if (!event.isEnabled()) {
+        EventHandler handler = Handlers.FILE_WRITE;
+        if (!handler.isEnabled()) {
             write(b);
             return;
         }
+        long bytesWritten = 0;
+        long start = 0;
         try {
-            event.begin();
+            start = EventHandler.timestamp();
             write(b);
-            event.bytesWritten = 1;
+            bytesWritten = 1;
         } finally {
-            event.path = path;
-            event.commit();
-            event.reset();
+            long duration = EventHandler.timestamp() - start;
+            if (handler.shouldCommit(duration)) {
+                handler.write(start, duration, path, bytesWritten);
+            }
         }
     }
 
     @SuppressWarnings("deprecation")
     @JIInstrumentationMethod
     public void write(byte b[]) throws IOException {
-        FileWriteEvent event = FileWriteEvent.EVENT.get();
-        if (!event.isEnabled()) {
+        EventHandler handler = Handlers.FILE_WRITE;
+        if (!handler.isEnabled()) {
             write(b);
             return;
         }
+        long bytesWritten = 0;
+        long start = 0;
         try {
-            event.begin();
+            start = EventHandler.timestamp();
             write(b);
-            event.bytesWritten = b.length;
+            bytesWritten = b.length;
         } finally {
-            event.path = path;
-            event.commit();
-            event.reset();
+            long duration = EventHandler.timestamp() - start;
+            if (handler.shouldCommit(duration)) {
+                handler.write(start, duration, path, bytesWritten);
+            }
         }
     }
 
     @SuppressWarnings("deprecation")
     @JIInstrumentationMethod
     public void write(byte b[], int off, int len) throws IOException {
-        FileWriteEvent event = FileWriteEvent.EVENT.get();
-        if (!event.isEnabled()) {
+        EventHandler handler = Handlers.FILE_WRITE;
+        if (!handler.isEnabled()) {
             write(b, off, len);
             return;
         }
+        long bytesWritten = 0;
+        long start = 0;
         try {
-            event.begin();
+            start = EventHandler.timestamp();
             write(b, off, len);
-            event.bytesWritten = len;
+            bytesWritten = len;
         } finally {
-            event.path = path;
-            event.commit();
-            event.reset();
+            long duration = EventHandler.timestamp() - start;
+            if (handler.shouldCommit(duration)) {
+                handler.write(start, duration, path, bytesWritten);
+            }
         }
     }
 }
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/RandomAccessFileInstrumentor.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/RandomAccessFileInstrumentor.java
index c376700112c..ee4c7c34c82 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/RandomAccessFileInstrumentor.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/RandomAccessFileInstrumentor.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
@@ -27,8 +27,8 @@ package jdk.jfr.internal.instrument;
 
 import java.io.IOException;
 
-import jdk.jfr.events.FileReadEvent;
-import jdk.jfr.events.FileWriteEvent;
+import jdk.jfr.events.Handlers;
+import jdk.jfr.internal.handlers.EventHandler;
 
 /**
  * See {@link JITracer} for an explanation of this code.
@@ -44,23 +44,27 @@ final class RandomAccessFileInstrumentor {
     @SuppressWarnings("deprecation")
     @JIInstrumentationMethod
     public int read() throws IOException {
-        FileReadEvent event = FileReadEvent.EVENT.get();
-        if (!event.isEnabled()) {
+        EventHandler handler = Handlers.FILE_READ;
+        if (!handler.isEnabled()) {
             return read();
         }
         int result = 0;
+        long bytesRead = 0;
+        boolean endOfFile = false;
+        long start = 0;
         try {
-            event.begin();
+            start = EventHandler.timestamp();
             result = read();
             if (result < 0) {
-                event.endOfFile = true;
+                endOfFile = true;
             } else {
-                event.bytesRead = 1;
+                bytesRead = 1;
             }
         } finally {
-            event.path = path;
-            event.commit();
-            event.reset();
+            long duration = EventHandler.timestamp() - start;
+            if (handler.shouldCommit(duration)) {
+                handler.write(start, duration, path, bytesRead, endOfFile);
+            }
         }
         return result;
     }
@@ -68,23 +72,24 @@ final class RandomAccessFileInstrumentor {
     @SuppressWarnings("deprecation")
     @JIInstrumentationMethod
     public int read(byte b[]) throws IOException {
-        FileReadEvent event = FileReadEvent.EVENT.get();
-        if (!event.isEnabled()) {
+        EventHandler handler = Handlers.FILE_READ;
+        if (!handler.isEnabled()) {
             return read(b);
         }
         int bytesRead = 0;
+        long start = 0;
         try {
-            event.begin();
+            start = EventHandler.timestamp();
             bytesRead = read(b);
         } finally {
-            if (bytesRead < 0) {
-                event.endOfFile = true;
-            } else {
-                event.bytesRead = bytesRead;
+            long duration = EventHandler.timestamp() - start;
+            if (handler.shouldCommit(duration)) {
+                if (bytesRead < 0) {
+                    handler.write(start, duration, path, 0L, true);
+                } else {
+                    handler.write(start, duration, path, bytesRead, false);
+                }
             }
-            event.path = path;
-            event.commit();
-            event.reset();
         }
         return bytesRead;
     }
@@ -92,23 +97,24 @@ final class RandomAccessFileInstrumentor {
     @SuppressWarnings("deprecation")
     @JIInstrumentationMethod
     public int read(byte b[], int off, int len) throws IOException {
-        FileReadEvent event = FileReadEvent.EVENT.get();
-        if (!event.isEnabled()) {
+        EventHandler handler = Handlers.FILE_READ;
+        if (!handler.isEnabled()) {
             return read(b, off, len);
         }
         int bytesRead = 0;
+        long start = 0;
         try {
-            event.begin();
+            start = EventHandler.timestamp();
             bytesRead = read(b, off, len);
         } finally {
-            if (bytesRead < 0) {
-                event.endOfFile = true;
-            } else {
-                event.bytesRead = bytesRead;
+            long duration = EventHandler.timestamp() - start;
+            if (handler.shouldCommit(duration)) {
+                if (bytesRead < 0) {
+                    handler.write(start, duration, path, 0L, true);
+                } else {
+                    handler.write(start, duration, path, bytesRead, false);
+                }
             }
-            event.path = path;
-            event.commit();
-            event.reset();
         }
         return bytesRead;
     }
@@ -116,58 +122,66 @@ final class RandomAccessFileInstrumentor {
     @SuppressWarnings("deprecation")
     @JIInstrumentationMethod
     public void write(int b) throws IOException {
-        FileWriteEvent event = FileWriteEvent.EVENT.get();
-        if (!event.isEnabled()) {
+        EventHandler handler = Handlers.FILE_WRITE;
+        if (!handler.isEnabled()) {
             write(b);
             return;
         }
+        long bytesWritten = 0;
+        long start = 0;
         try {
-            event.begin();
+            start = EventHandler.timestamp();
             write(b);
-            event.bytesWritten = 1;
+            bytesWritten = 1;
         } finally {
-            event.path = path;
-            event.commit();
-            event.reset();
+            long duration = EventHandler.timestamp() - start;
+            if (handler.shouldCommit(duration)) {
+                handler.write(start, duration, path, bytesWritten);
+            }
         }
     }
 
     @SuppressWarnings("deprecation")
     @JIInstrumentationMethod
     public void write(byte b[]) throws IOException {
-        FileWriteEvent event = FileWriteEvent.EVENT.get();
-        if (!event.isEnabled()) {
+        EventHandler handler = Handlers.FILE_WRITE;
+        if (!handler.isEnabled()) {
             write(b);
             return;
         }
+        long bytesWritten = 0;
+        long start = 0;
         try {
-            event.begin();
+            start = EventHandler.timestamp();
             write(b);
-            event.bytesWritten = b.length;
+            bytesWritten = b.length;
         } finally {
-            event.path = path;
-            event.commit();
-            event.reset();
+            long duration = EventHandler.timestamp();
+            if (handler.shouldCommit(duration)) {
+                handler.write(start, duration, path, bytesWritten);
+            }
         }
     }
 
     @SuppressWarnings("deprecation")
     @JIInstrumentationMethod
     public void write(byte b[], int off, int len) throws IOException {
-        FileWriteEvent event = FileWriteEvent.EVENT.get();
-        if (!event.isEnabled()) {
+        EventHandler handler = Handlers.FILE_WRITE;
+        if (!handler.isEnabled()) {
             write(b, off, len);
             return;
         }
+        long bytesWritten = 0;
+        long start = 0;
         try {
-            event.begin();
+            start = EventHandler.timestamp();
             write(b, off, len);
-            event.bytesWritten = len;
+            bytesWritten = len;
         } finally {
-            event.path = path;
-            event.commit();
-            event.reset();
+            long duration = EventHandler.timestamp() - start;
+            if (handler.shouldCommit(duration)) {
+                handler.write(start, duration, path, bytesWritten);
+            }
         }
     }
-
 }
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/SocketChannelImplInstrumentor.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/SocketChannelImplInstrumentor.java
index 7291c69e943..0e0486b6ab0 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/SocketChannelImplInstrumentor.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/SocketChannelImplInstrumentor.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
@@ -29,8 +29,8 @@ import java.io.IOException;
 import java.net.InetSocketAddress;
 import java.nio.ByteBuffer;
 
-import jdk.jfr.events.SocketReadEvent;
-import jdk.jfr.events.SocketWriteEvent;
+import jdk.jfr.events.Handlers;
+import jdk.jfr.internal.handlers.EventHandler;
 
 /**
  * See {@link JITracer} for an explanation of this code.
@@ -46,32 +46,29 @@ final class SocketChannelImplInstrumentor {
     @SuppressWarnings("deprecation")
     @JIInstrumentationMethod
     public int read(ByteBuffer dst) throws IOException {
-        SocketReadEvent event = SocketReadEvent.EVENT.get();
-        if (!event.isEnabled()) {
+        EventHandler handler = Handlers.SOCKET_READ;
+        if (!handler.isEnabled()) {
             return read(dst);
         }
         int bytesRead = 0;
+        long start  = 0;
         try {
-            event.begin();
+            start = EventHandler.timestamp();;
             bytesRead = read(dst);
         } finally {
-            event.end();
-            if (event.shouldCommit())  {
+            long duration = EventHandler.timestamp() - start;
+            if (handler.shouldCommit(duration))  {
                 String hostString  = remoteAddress.getAddress().toString();
                 int delimiterIndex = hostString.lastIndexOf('/');
 
-                event.host      = hostString.substring(0, delimiterIndex);
-                event.address   = hostString.substring(delimiterIndex + 1);
-                event.port      = remoteAddress.getPort();
+                String host = hostString.substring(0, delimiterIndex);
+                String address = hostString.substring(delimiterIndex + 1);
+                int port = remoteAddress.getPort();
                 if (bytesRead < 0) {
-                    event.endOfStream = true;
+                    handler.write(start, duration, host, address, port, 0, 0L, true);
                 } else {
-                    event.bytesRead = bytesRead;
+                    handler.write(start, duration, host, address, port, 0, bytesRead, false);
                 }
-                event.timeout   = 0;
-
-                event.commit();
-                event.reset();
             }
         }
         return bytesRead;
@@ -80,33 +77,30 @@ final class SocketChannelImplInstrumentor {
     @SuppressWarnings("deprecation")
     @JIInstrumentationMethod
     public long read(ByteBuffer[] dsts, int offset, int length) throws IOException {
-        SocketReadEvent event = SocketReadEvent.EVENT.get();
-        if(!event.isEnabled()) {
+        EventHandler handler = Handlers.SOCKET_READ;
+        if (!handler.isEnabled()) {
             return read(dsts, offset, length);
         }
 
         long bytesRead = 0;
+        long start = 0;
         try {
-            event.begin();
+            start = EventHandler.timestamp();
             bytesRead = read(dsts, offset, length);
         } finally {
-            event.end();
-            if (event.shouldCommit()) {
+            long duration = EventHandler.timestamp() - start;
+            if (handler.shouldCommit(duration)) {
                 String hostString  = remoteAddress.getAddress().toString();
                 int delimiterIndex = hostString.lastIndexOf('/');
 
-                event.host      = hostString.substring(0, delimiterIndex);
-                event.address   = hostString.substring(delimiterIndex + 1);
-                event.port      = remoteAddress.getPort();
+                String host = hostString.substring(0, delimiterIndex);
+                String address = hostString.substring(delimiterIndex + 1);
+                int port = remoteAddress.getPort();
                 if (bytesRead < 0) {
-                    event.endOfStream = true;
+                    handler.write(start, duration, host, address, port, 0, 0L, true);
                 } else {
-                    event.bytesRead = bytesRead;
+                    handler.write(start, duration, host, address, port, 0, bytesRead, false);
                 }
-                event.timeout   = 0;
-
-                event.commit();
-                event.reset();
             }
         }
         return bytesRead;
@@ -115,28 +109,26 @@ final class SocketChannelImplInstrumentor {
     @SuppressWarnings("deprecation")
     @JIInstrumentationMethod
     public int write(ByteBuffer buf) throws IOException {
-        SocketWriteEvent event = SocketWriteEvent.EVENT.get();
-        if (!event.isEnabled()) {
+        EventHandler handler = Handlers.SOCKET_WRITE;
+        if (!handler.isEnabled()) {
             return write(buf);
         }
-
         int bytesWritten = 0;
+        long start = 0;
         try {
-            event.begin();
+            start = EventHandler.timestamp();
             bytesWritten = write(buf);
         } finally {
-            event.end();
-            if (event.shouldCommit()) {
+            long duration = EventHandler.timestamp() - start;
+            if (handler.shouldCommit(duration)) {
                 String hostString  = remoteAddress.getAddress().toString();
                 int delimiterIndex = hostString.lastIndexOf('/');
 
-                event.host         = hostString.substring(0, delimiterIndex);
-                event.address      = hostString.substring(delimiterIndex + 1);
-                event.port         = remoteAddress.getPort();
-                event.bytesWritten = bytesWritten < 0 ? 0 : bytesWritten;
-
-                event.commit();
-                event.reset();
+                String host = hostString.substring(0, delimiterIndex);
+                String address = hostString.substring(delimiterIndex + 1);
+                int port = remoteAddress.getPort();
+                long bytes = bytesWritten < 0 ? 0 : bytesWritten;
+                handler.write(start, duration, host, address, port, bytes);
             }
         }
         return bytesWritten;
@@ -145,30 +137,28 @@ final class SocketChannelImplInstrumentor {
     @SuppressWarnings("deprecation")
     @JIInstrumentationMethod
     public long write(ByteBuffer[] srcs, int offset, int length) throws IOException {
-        SocketWriteEvent event = SocketWriteEvent.EVENT.get();
-        if (!event.isEnabled()) {
+        EventHandler handler = Handlers.SOCKET_WRITE;
+        if (!handler.isEnabled()) {
             return write(srcs, offset, length);
         }
         long bytesWritten = 0;
+        long start = 0;
         try {
-            event.begin();
+            start = EventHandler.timestamp();
             bytesWritten = write(srcs, offset, length);
         } finally {
-            event.end();
-            if (event.shouldCommit()) {
+            long duration = EventHandler.timestamp() - start;
+            if (handler.shouldCommit(duration)) {
                 String hostString  = remoteAddress.getAddress().toString();
                 int delimiterIndex = hostString.lastIndexOf('/');
 
-                event.host         = hostString.substring(0, delimiterIndex);
-                event.address      = hostString.substring(delimiterIndex + 1);
-                event.port         = remoteAddress.getPort();
-                event.bytesWritten = bytesWritten < 0 ? 0 : bytesWritten;
-
-                event.commit();
-                event.reset();
+                String host = hostString.substring(0, delimiterIndex);
+                String address = hostString.substring(delimiterIndex + 1);
+                int port = remoteAddress.getPort();
+                long bytes = bytesWritten < 0 ? 0 : bytesWritten;
+                handler.write(start, duration, host, address, port, bytes);
             }
         }
         return bytesWritten;
     }
-
 }
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/SocketInputStreamInstrumentor.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/SocketInputStreamInstrumentor.java
index 83b4f8afc75..96325452e28 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/SocketInputStreamInstrumentor.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/SocketInputStreamInstrumentor.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
@@ -29,7 +29,8 @@ import java.io.IOException;
 import java.net.InetAddress;
 import java.net.Socket;
 
-import jdk.jfr.events.SocketReadEvent;
+import jdk.jfr.events.Handlers;
+import jdk.jfr.internal.handlers.EventHandler;
 
 /**
  * See {@link JITracer} for an explanation of this code.
@@ -43,30 +44,28 @@ final class SocketInputStreamInstrumentor {
     @SuppressWarnings("deprecation")
     @JIInstrumentationMethod
     public int read(byte b[], int off, int length) throws IOException {
-        SocketReadEvent event = SocketReadEvent.EVENT.get();
-        if (!event.isEnabled()) {
+        EventHandler handler = Handlers.SOCKET_READ;
+        if (!handler.isEnabled()) {
             return read(b, off, length);
         }
         int bytesRead = 0;
+        long start = 0;
         try {
-            event.begin();
+            start = EventHandler.timestamp();
             bytesRead = read(b, off, length);
         } finally {
-            event.end();
-            if (event.shouldCommit()) {
+            long duration = EventHandler.timestamp() - start;
+            if (handler.shouldCommit(duration)) {
                 InetAddress remote = parent.getInetAddress();
-                event.host = remote.getHostName();
-                event.address = remote.getHostAddress();
-                event.port = parent.getPort();
+                String host = remote.getHostName();
+                String address = remote.getHostAddress();
+                int port = parent.getPort();
+                int timeout = parent.getSoTimeout();
                 if (bytesRead < 0) {
-                    event.endOfStream = true;
+                    handler.write(start, duration, host, address, port, timeout, 0L, true);
                 } else {
-                    event.bytesRead = bytesRead;
+                    handler.write(start, duration, host, address, port, timeout, bytesRead, false);
                 }
-                event.timeout = parent.getSoTimeout();
-
-                event.commit();
-                event.reset();
             }
         }
         return bytesRead;
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/SocketOutputStreamInstrumentor.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/SocketOutputStreamInstrumentor.java
index 3fdd07138db..1edb2b3c642 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/SocketOutputStreamInstrumentor.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/SocketOutputStreamInstrumentor.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
@@ -29,7 +29,8 @@ import java.io.IOException;
 import java.net.InetAddress;
 import java.net.Socket;
 
-import jdk.jfr.events.SocketWriteEvent;
+import jdk.jfr.events.Handlers;
+import jdk.jfr.internal.handlers.EventHandler;
 
 /**
  * See {@link JITracer} for an explanation of this code.
@@ -43,27 +44,28 @@ final class SocketOutputStreamInstrumentor {
     @SuppressWarnings("deprecation")
     @JIInstrumentationMethod
     public void write(byte b[], int off, int len) throws IOException {
-        SocketWriteEvent event = SocketWriteEvent.EVENT.get();
-        if (!event.isEnabled()) {
+        EventHandler handler = Handlers.SOCKET_WRITE;
+        if (!handler.isEnabled()) {
             write(b, off, len);
             return;
         }
         int bytesWritten = 0;
+        long start = 0;
         try {
-            event.begin();
+            start = EventHandler.timestamp();
             write(b, off, len);
             bytesWritten = len;
         } finally {
-            event.end() ;
-            if (event.shouldCommit()) {
+            long duration = EventHandler.timestamp() - start;
+            if (handler.shouldCommit(duration)) {
                 InetAddress remote = parent.getInetAddress();
-                event.host = remote.getHostName();
-                event.address = remote.getHostAddress();
-                event.port = parent.getPort();
-                event.bytesWritten = bytesWritten;
-
-                event.commit();
-                event.reset();
+                handler.write(
+                        start,
+                        duration,
+                        remote.getHostName(),
+                        remote.getHostAddress(),
+                        parent.getPort(),
+                        bytesWritten);
             }
         }
     }
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/ThrowableTracer.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/ThrowableTracer.java
index 236082738da..404a3fd772d 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/ThrowableTracer.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/ThrowableTracer.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
@@ -27,34 +27,36 @@ package jdk.jfr.internal.instrument;
 
 import java.util.concurrent.atomic.AtomicLong;
 
-import jdk.jfr.events.ErrorThrownEvent;
-import jdk.jfr.events.ExceptionThrownEvent;
+import jdk.jfr.events.Handlers;
+import jdk.jfr.internal.handlers.EventHandler;
 
 public final class ThrowableTracer {
 
-    private static AtomicLong numThrowables = new AtomicLong(0);
+    private static final AtomicLong numThrowables = new AtomicLong(0);
 
     public static void traceError(Error e, String message) {
         if (e instanceof OutOfMemoryError) {
             return;
         }
-        ErrorThrownEvent errorEvent = new ErrorThrownEvent();
-        errorEvent.message = message;
-        errorEvent.thrownClass = e.getClass();
-        errorEvent.commit();
+        long timestamp = EventHandler.timestamp();
 
-        ExceptionThrownEvent exceptionEvent = new ExceptionThrownEvent();
-        exceptionEvent.message = message;
-        exceptionEvent.thrownClass = e.getClass();
-        exceptionEvent.commit();
+        EventHandler h1 = Handlers.ERROR_THROWN;
+        if (h1.isEnabled()) {
+            h1.write(timestamp, 0L, message, e.getClass());
+        }
+        EventHandler h2 = Handlers.EXCEPTION_THROWN;
+        if (h2.isEnabled()) {
+            h2.write(timestamp, 0L, message, e.getClass());
+        }
         numThrowables.incrementAndGet();
     }
 
     public static void traceThrowable(Throwable t, String message) {
-        ExceptionThrownEvent event = new ExceptionThrownEvent();
-        event.message = message;
-        event.thrownClass = t.getClass();
-        event.commit();
+        EventHandler h = Handlers.EXCEPTION_THROWN;
+        if (h.isEnabled()) {
+            long timestamp = EventHandler.timestamp();
+            h.write(timestamp, 0L, message, t.getClass());
+        }
         numThrowables.incrementAndGet();
     }
 

From 25dcb1f717f0394d1868400388c6f01699f3f4b3 Mon Sep 17 00:00:00 2001
From: Zhengyu Gu 
Date: Tue, 12 May 2020 10:01:36 -0400
Subject: [PATCH 023/143] 8244821: Shenandoah: disarmed_value is initialized at
 wrong place

Reviewed-by: shade
---
 src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp      | 1 +
 src/hotspot/share/gc/shenandoah/shenandoahThreadLocalData.hpp | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp
index 4927e452014..0cbd74b546e 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp
@@ -164,6 +164,7 @@ void ShenandoahBarrierSet::on_thread_attach(Thread *thread) {
   if (thread->is_Java_thread()) {
     ShenandoahThreadLocalData::set_gc_state(thread, _heap->gc_state());
     ShenandoahThreadLocalData::initialize_gclab(thread);
+    ShenandoahThreadLocalData::set_disarmed_value(thread, ShenandoahCodeRoots::disarmed_value());
   }
 }
 
diff --git a/src/hotspot/share/gc/shenandoah/shenandoahThreadLocalData.hpp b/src/hotspot/share/gc/shenandoah/shenandoahThreadLocalData.hpp
index 5ff5590c1b5..0539d69a4ab 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoahThreadLocalData.hpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahThreadLocalData.hpp
@@ -55,7 +55,7 @@ private:
     _gclab_size(0),
     _worker_id(INVALID_WORKER_ID),
     _force_satb_flush(false),
-    _disarmed_value(ShenandoahCodeRoots::disarmed_value()) {
+    _disarmed_value(0) {
 
     // At least on x86_64, nmethod entry barrier encodes _disarmed_value offset
     // in instruction as disp8 immed

From ba59fe95037a9f98d66d53b1372e5857e57ba48d Mon Sep 17 00:00:00 2001
From: Roman Kennke 
Date: Tue, 12 May 2020 16:12:37 +0200
Subject: [PATCH 024/143] 8244813: [BACKOUT] 8244523: Shenandoah: Remove
 null-handling in LRB expansion

Reviewed-by: shade
---
 .../shenandoah/c2/shenandoahBarrierSetC2.cpp  |  41 ++-
 .../shenandoah/c2/shenandoahBarrierSetC2.hpp  |   2 +-
 .../gc/shenandoah/c2/shenandoahSupport.cpp    | 292 +++++++++++++++++-
 .../gc/shenandoah/c2/shenandoahSupport.hpp    |   4 +
 4 files changed, 316 insertions(+), 23 deletions(-)

diff --git a/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp b/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp
index 0951bff5d53..05c45b4e955 100644
--- a/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp
+++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp
@@ -481,16 +481,16 @@ const TypeFunc* ShenandoahBarrierSetC2::shenandoah_clone_barrier_Type() {
   return TypeFunc::make(domain, range);
 }
 
-const TypeFunc* ShenandoahBarrierSetC2::shenandoah_load_reference_barrier_Type(const Type* value_type) {
+const TypeFunc* ShenandoahBarrierSetC2::shenandoah_load_reference_barrier_Type() {
   const Type **fields = TypeTuple::fields(2);
-  fields[TypeFunc::Parms+0] = value_type;           // original field value
+  fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // original field value
   fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM;   // original load address
 
   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields);
 
   // create result type (range)
   fields = TypeTuple::fields(1);
-  fields[TypeFunc::Parms+0] = value_type;
+  fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;
   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
 
   return TypeFunc::make(domain, range);
@@ -1059,10 +1059,37 @@ Node* ShenandoahBarrierSetC2::ideal_node(PhaseGVN* phase, Node* n, bool can_resh
       }
     }
   }
-  if (can_reshape &&
-      n->Opcode() == Op_If &&
-      ShenandoahBarrierC2Support::is_heap_stable_test(n) &&
-      n->in(0) != NULL) {
+  if (n->Opcode() == Op_CmpP) {
+    Node* in1 = n->in(1);
+    Node* in2 = n->in(2);
+    if (in1->bottom_type() == TypePtr::NULL_PTR) {
+      in2 = step_over_gc_barrier(in2);
+    }
+    if (in2->bottom_type() == TypePtr::NULL_PTR) {
+      in1 = step_over_gc_barrier(in1);
+    }
+    PhaseIterGVN* igvn = phase->is_IterGVN();
+    if (in1 != n->in(1)) {
+      if (igvn != NULL) {
+        n->set_req_X(1, in1, igvn);
+      } else {
+        n->set_req(1, in1);
+      }
+      assert(in2 == n->in(2), "only one change");
+      return n;
+    }
+    if (in2 != n->in(2)) {
+      if (igvn != NULL) {
+        n->set_req_X(2, in2, igvn);
+      } else {
+        n->set_req(2, in2);
+      }
+      return n;
+    }
+  } else if (can_reshape &&
+             n->Opcode() == Op_If &&
+             ShenandoahBarrierC2Support::is_heap_stable_test(n) &&
+             n->in(0) != NULL) {
     Node* dom = n->in(0);
     Node* prev_dom = n;
     int op = n->Opcode();
diff --git a/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.hpp b/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.hpp
index d985deb67fe..db494012805 100644
--- a/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.hpp
+++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.hpp
@@ -103,7 +103,7 @@ public:
 
   static const TypeFunc* write_ref_field_pre_entry_Type();
   static const TypeFunc* shenandoah_clone_barrier_Type();
-  static const TypeFunc* shenandoah_load_reference_barrier_Type(const Type* value_type);
+  static const TypeFunc* shenandoah_load_reference_barrier_Type();
   virtual bool has_load_barrier_nodes() const { return true; }
 
   // This is the entry-point for the backend to perform accesses through the Access API.
diff --git a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp
index 3390b0eff15..3f1991a6889 100644
--- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp
+++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp
@@ -919,6 +919,76 @@ void ShenandoahBarrierC2Support::test_null(Node*& ctrl, Node* val, Node*& null_c
   }
 }
 
+Node* ShenandoahBarrierC2Support::clone_null_check(Node*& c, Node* val, Node* unc_ctrl, PhaseIdealLoop* phase) {
+  IdealLoopTree *loop = phase->get_loop(c);
+  Node* iff = unc_ctrl->in(0);
+  assert(iff->is_If(), "broken");
+  Node* new_iff = iff->clone();
+  new_iff->set_req(0, c);
+  phase->register_control(new_iff, loop, c);
+  Node* iffalse = new IfFalseNode(new_iff->as_If());
+  phase->register_control(iffalse, loop, new_iff);
+  Node* iftrue = new IfTrueNode(new_iff->as_If());
+  phase->register_control(iftrue, loop, new_iff);
+  c = iftrue;
+  const Type *t = phase->igvn().type(val);
+  assert(val->Opcode() == Op_CastPP, "expect cast to non null here");
+  Node* uncasted_val = val->in(1);
+  val = new CastPPNode(uncasted_val, t);
+  val->init_req(0, c);
+  phase->register_new_node(val, c);
+  return val;
+}
+
+void ShenandoahBarrierC2Support::fix_null_check(Node* unc, Node* unc_ctrl, Node* new_unc_ctrl,
+                                                Unique_Node_List& uses, PhaseIdealLoop* phase) {
+  IfNode* iff = unc_ctrl->in(0)->as_If();
+  Node* proj = iff->proj_out(0);
+  assert(proj != unc_ctrl, "bad projection");
+  Node* use = proj->unique_ctrl_out();
+
+  assert(use == unc || use->is_Region(), "what else?");
+
+  uses.clear();
+  if (use == unc) {
+    phase->set_idom(use, new_unc_ctrl, phase->dom_depth(use));
+    for (uint i = 1; i < unc->req(); i++) {
+      Node* n = unc->in(i);
+      if (phase->has_ctrl(n) && phase->get_ctrl(n) == proj) {
+        uses.push(n);
+      }
+    }
+  } else {
+    assert(use->is_Region(), "what else?");
+    uint idx = 1;
+    for (; use->in(idx) != proj; idx++);
+    for (DUIterator_Fast imax, i = use->fast_outs(imax); i < imax; i++) {
+      Node* u = use->fast_out(i);
+      if (u->is_Phi() && phase->get_ctrl(u->in(idx)) == proj) {
+        uses.push(u->in(idx));
+      }
+    }
+  }
+  for(uint next = 0; next < uses.size(); next++ ) {
+    Node *n = uses.at(next);
+    assert(phase->get_ctrl(n) == proj, "bad control");
+    phase->set_ctrl_and_loop(n, new_unc_ctrl);
+    if (n->in(0) == proj) {
+      phase->igvn().replace_input_of(n, 0, new_unc_ctrl);
+    }
+    for (uint i = 0; i < n->req(); i++) {
+      Node* m = n->in(i);
+      if (m != NULL && phase->has_ctrl(m) && phase->get_ctrl(m) == proj) {
+        uses.push(m);
+      }
+    }
+  }
+
+  phase->igvn().rehash_node_delayed(use);
+  int nb = use->replace_edge(proj, new_unc_ctrl);
+  assert(nb == 1, "only use expected");
+}
+
 void ShenandoahBarrierC2Support::test_in_cset(Node*& ctrl, Node*& not_cset_ctrl, Node* val, Node* raw_mem, PhaseIdealLoop* phase) {
   Node* old_ctrl = ctrl;
   PhaseIterGVN& igvn = phase->igvn();
@@ -970,7 +1040,7 @@ void ShenandoahBarrierC2Support::call_lrb_stub(Node*& ctrl, Node*& val, Node* lo
   address calladdr = is_native ? CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native)
                                : target;
   const char* name = is_native ? "load_reference_barrier_native" : "load_reference_barrier";
-  Node* call = new CallLeafNode(ShenandoahBarrierSetC2::shenandoah_load_reference_barrier_Type(obj_type), calladdr, name, TypeRawPtr::BOTTOM);
+  Node* call = new CallLeafNode(ShenandoahBarrierSetC2::shenandoah_load_reference_barrier_Type(), calladdr, name, TypeRawPtr::BOTTOM);
 
   call->init_req(TypeFunc::Control, ctrl);
   call->init_req(TypeFunc::I_O, phase->C->top());
@@ -986,6 +1056,8 @@ void ShenandoahBarrierC2Support::call_lrb_stub(Node*& ctrl, Node*& val, Node* lo
   phase->register_new_node(result_mem, call);
   val = new ProjNode(call, TypeFunc::Parms);
   phase->register_new_node(val, call);
+  val = new CheckCastPPNode(ctrl, val, obj_type);
+  phase->register_new_node(val, ctrl);
 }
 
 void ShenandoahBarrierC2Support::fix_ctrl(Node* barrier, Node* region, const MemoryGraphFixer& fixer, Unique_Node_List& uses, Unique_Node_List& uses_to_ignore, uint last, PhaseIdealLoop* phase) {
@@ -1091,6 +1163,119 @@ void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) {
     }
 
     Node* ctrl = phase->get_ctrl(lrb);
+    Node* val = lrb->in(ShenandoahLoadReferenceBarrierNode::ValueIn);
+
+    CallStaticJavaNode* unc = NULL;
+    Node* unc_ctrl = NULL;
+    Node* uncasted_val = val;
+
+    for (DUIterator_Fast imax, i = lrb->fast_outs(imax); i < imax; i++) {
+      Node* u = lrb->fast_out(i);
+      if (u->Opcode() == Op_CastPP &&
+          u->in(0) != NULL &&
+          phase->is_dominator(u->in(0), ctrl)) {
+        const Type* u_t = phase->igvn().type(u);
+
+        if (u_t->meet(TypePtr::NULL_PTR) != u_t &&
+            u->in(0)->Opcode() == Op_IfTrue &&
+            u->in(0)->as_Proj()->is_uncommon_trap_if_pattern(Deoptimization::Reason_none) &&
+            u->in(0)->in(0)->is_If() &&
+            u->in(0)->in(0)->in(1)->Opcode() == Op_Bool &&
+            u->in(0)->in(0)->in(1)->as_Bool()->_test._test == BoolTest::ne &&
+            u->in(0)->in(0)->in(1)->in(1)->Opcode() == Op_CmpP &&
+            u->in(0)->in(0)->in(1)->in(1)->in(1) == val &&
+            u->in(0)->in(0)->in(1)->in(1)->in(2)->bottom_type() == TypePtr::NULL_PTR) {
+          IdealLoopTree* loop = phase->get_loop(ctrl);
+          IdealLoopTree* unc_loop = phase->get_loop(u->in(0));
+
+          if (!unc_loop->is_member(loop)) {
+            continue;
+          }
+
+          Node* branch = no_branches(ctrl, u->in(0), false, phase);
+          assert(branch == NULL || branch == NodeSentinel, "was not looking for a branch");
+          if (branch == NodeSentinel) {
+            continue;
+          }
+
+          phase->igvn().replace_input_of(u, 1, val);
+          phase->igvn().replace_input_of(lrb, ShenandoahLoadReferenceBarrierNode::ValueIn, u);
+          phase->set_ctrl(u, u->in(0));
+          phase->set_ctrl(lrb, u->in(0));
+          unc = u->in(0)->as_Proj()->is_uncommon_trap_if_pattern(Deoptimization::Reason_none);
+          unc_ctrl = u->in(0);
+          val = u;
+
+          for (DUIterator_Fast jmax, j = val->fast_outs(jmax); j < jmax; j++) {
+            Node* u = val->fast_out(j);
+            if (u == lrb) continue;
+            phase->igvn().rehash_node_delayed(u);
+            int nb = u->replace_edge(val, lrb);
+            --j; jmax -= nb;
+          }
+
+          RegionNode* r = new RegionNode(3);
+          IfNode* iff = unc_ctrl->in(0)->as_If();
+
+          Node* ctrl_use = unc_ctrl->unique_ctrl_out();
+          Node* unc_ctrl_clone = unc_ctrl->clone();
+          phase->register_control(unc_ctrl_clone, loop, iff);
+          Node* c = unc_ctrl_clone;
+          Node* new_cast = clone_null_check(c, val, unc_ctrl_clone, phase);
+          r->init_req(1, new_cast->in(0)->in(0)->as_If()->proj_out(0));
+
+          phase->igvn().replace_input_of(unc_ctrl, 0, c->in(0));
+          phase->set_idom(unc_ctrl, c->in(0), phase->dom_depth(unc_ctrl));
+          phase->lazy_replace(c, unc_ctrl);
+          c = NULL;;
+          phase->igvn().replace_input_of(val, 0, unc_ctrl_clone);
+          phase->set_ctrl(val, unc_ctrl_clone);
+
+          IfNode* new_iff = new_cast->in(0)->in(0)->as_If();
+          fix_null_check(unc, unc_ctrl_clone, r, uses, phase);
+          Node* iff_proj = iff->proj_out(0);
+          r->init_req(2, iff_proj);
+          phase->register_control(r, phase->ltree_root(), iff);
+
+          Node* new_bol = new_iff->in(1)->clone();
+          Node* new_cmp = new_bol->in(1)->clone();
+          assert(new_cmp->Opcode() == Op_CmpP, "broken");
+          assert(new_cmp->in(1) == val->in(1), "broken");
+          new_bol->set_req(1, new_cmp);
+          new_cmp->set_req(1, lrb);
+          phase->register_new_node(new_bol, new_iff->in(0));
+          phase->register_new_node(new_cmp, new_iff->in(0));
+          phase->igvn().replace_input_of(new_iff, 1, new_bol);
+          phase->igvn().replace_input_of(new_cast, 1, lrb);
+
+          for (DUIterator_Fast imax, i = lrb->fast_outs(imax); i < imax; i++) {
+            Node* u = lrb->fast_out(i);
+            if (u == new_cast || u == new_cmp) {
+              continue;
+            }
+            phase->igvn().rehash_node_delayed(u);
+            int nb = u->replace_edge(lrb, new_cast);
+            assert(nb > 0, "no update?");
+            --i; imax -= nb;
+          }
+
+          for (DUIterator_Fast imax, i = val->fast_outs(imax); i < imax; i++) {
+            Node* u = val->fast_out(i);
+            if (u == lrb) {
+              continue;
+            }
+            phase->igvn().rehash_node_delayed(u);
+            int nb = u->replace_edge(val, new_cast);
+            assert(nb > 0, "no update?");
+            --i; imax -= nb;
+          }
+
+          ctrl = unc_ctrl_clone;
+          phase->set_ctrl_and_loop(lrb, ctrl);
+          break;
+        }
+      }
+    }
     if ((ctrl->is_Proj() && ctrl->in(0)->is_CallJava()) || ctrl->is_CallJava()) {
       CallNode* call = ctrl->is_Proj() ? ctrl->in(0)->as_CallJava() : ctrl->as_CallJava();
       if (call->entry_point() == OptoRuntime::rethrow_stub()) {
@@ -1231,45 +1416,90 @@ void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) {
     Node* ctrl = phase->get_ctrl(lrb);
     Node* val = lrb->in(ShenandoahLoadReferenceBarrierNode::ValueIn);
 
+
     Node* orig_ctrl = ctrl;
 
     Node* raw_mem = fixer.find_mem(ctrl, lrb);
     Node* init_raw_mem = raw_mem;
     Node* raw_mem_for_ctrl = fixer.find_mem(ctrl, NULL);
 
-    IdealLoopTree* loop = phase->get_loop(ctrl);
+    IdealLoopTree *loop = phase->get_loop(ctrl);
+    CallStaticJavaNode* unc = lrb->pin_and_expand_null_check(phase->igvn());
+    Node* unc_ctrl = NULL;
+    if (unc != NULL) {
+      if (val->in(ShenandoahLoadReferenceBarrierNode::Control) != ctrl) {
+        unc = NULL;
+      } else {
+        unc_ctrl = val->in(ShenandoahLoadReferenceBarrierNode::Control);
+      }
+    }
+
+    Node* uncasted_val = val;
+    if (unc != NULL) {
+      uncasted_val = val->in(1);
+    }
+
+    Node* heap_stable_ctrl = NULL;
+    Node* null_ctrl = NULL;
 
     assert(val->bottom_type()->make_oopptr(), "need oop");
     assert(val->bottom_type()->make_oopptr()->const_oop() == NULL, "expect non-constant");
 
-    enum { _heap_stable = 1, _not_cset, _evac_path, PATH_LIMIT };
+    enum { _heap_stable = 1, _not_cset, _evac_path, _null_path, PATH_LIMIT };
     Node* region = new RegionNode(PATH_LIMIT);
-    Node* val_phi = new PhiNode(region, val->bottom_type()->is_oopptr());
+    Node* val_phi = new PhiNode(region, uncasted_val->bottom_type()->is_oopptr());
     Node* raw_mem_phi = PhiNode::make(region, raw_mem, Type::MEMORY, TypeRawPtr::BOTTOM);
 
     // Stable path.
-    Node* heap_stable_ctrl = NULL;
     test_gc_state(ctrl, raw_mem, heap_stable_ctrl, phase, ShenandoahHeap::HAS_FORWARDED);
     IfNode* heap_stable_iff = heap_stable_ctrl->in(0)->as_If();
 
     // Heap stable case
     region->init_req(_heap_stable, heap_stable_ctrl);
-    val_phi->init_req(_heap_stable, val);
+    val_phi->init_req(_heap_stable, uncasted_val);
     raw_mem_phi->init_req(_heap_stable, raw_mem);
 
+    Node* reg2_ctrl = NULL;
+    // Null case
+    test_null(ctrl, val, null_ctrl, phase);
+    if (null_ctrl != NULL) {
+      reg2_ctrl = null_ctrl->in(0);
+      region->init_req(_null_path, null_ctrl);
+      val_phi->init_req(_null_path, uncasted_val);
+      raw_mem_phi->init_req(_null_path, raw_mem);
+    } else {
+      region->del_req(_null_path);
+      val_phi->del_req(_null_path);
+      raw_mem_phi->del_req(_null_path);
+    }
+
     // Test for in-cset.
     // Wires !in_cset(obj) to slot 2 of region and phis
     Node* not_cset_ctrl = NULL;
-    test_in_cset(ctrl, not_cset_ctrl, val, raw_mem, phase);
+    test_in_cset(ctrl, not_cset_ctrl, uncasted_val, raw_mem, phase);
     if (not_cset_ctrl != NULL) {
+      if (reg2_ctrl == NULL) reg2_ctrl = not_cset_ctrl->in(0);
       region->init_req(_not_cset, not_cset_ctrl);
-      val_phi->init_req(_not_cset, val);
+      val_phi->init_req(_not_cset, uncasted_val);
       raw_mem_phi->init_req(_not_cset, raw_mem);
     }
 
+    // Resolve object when orig-value is in cset.
+    // Make the unconditional resolve for fwdptr.
+    Node* new_val = uncasted_val;
+    if (unc_ctrl != NULL) {
+      // Clone the null check in this branch to allow implicit null check
+      new_val = clone_null_check(ctrl, val, unc_ctrl, phase);
+      fix_null_check(unc, unc_ctrl, ctrl->in(0)->as_If()->proj_out(0), uses, phase);
+
+      IfNode* iff = unc_ctrl->in(0)->as_If();
+      phase->igvn().replace_input_of(iff, 1, phase->igvn().intcon(1));
+    }
+
     // Call lrb-stub and wire up that path in slots 4
     Node* result_mem = NULL;
 
+    Node* fwd = new_val;
     Node* addr;
     if (ShenandoahSelfFixing) {
       VectorSet visited(Thread::current()->resource_area());
@@ -1302,9 +1532,9 @@ void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) {
         }
       }
     }
-    call_lrb_stub(ctrl, val, addr, result_mem, raw_mem, lrb->is_native(), phase);
+    call_lrb_stub(ctrl, fwd, addr, result_mem, raw_mem, lrb->is_native(), phase);
     region->init_req(_evac_path, ctrl);
-    val_phi->init_req(_evac_path, val);
+    val_phi->init_req(_evac_path, fwd);
     raw_mem_phi->init_req(_evac_path, result_mem);
 
     phase->register_control(region, loop, heap_stable_iff);
@@ -1316,6 +1546,20 @@ void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) {
 
     ctrl = orig_ctrl;
 
+    if (unc != NULL) {
+      for (DUIterator_Fast imax, i = val->fast_outs(imax); i < imax; i++) {
+        Node* u = val->fast_out(i);
+        Node* c = phase->ctrl_or_self(u);
+        if (u != lrb && (c != ctrl || is_dominator_same_ctrl(c, lrb, u, phase))) {
+          phase->igvn().rehash_node_delayed(u);
+          int nb = u->replace_edge(val, out_val);
+          --i, imax -= nb;
+        }
+      }
+      if (val->outcnt() == 0) {
+        phase->igvn()._worklist.push(val);
+      }
+    }
     phase->igvn().replace_node(lrb, out_val);
 
     follow_barrier_uses(out_val, ctrl, uses, phase);
@@ -2943,11 +3187,6 @@ bool ShenandoahLoadReferenceBarrierNode::is_redundant() {
     bool visit_users = false;
     switch (n->Opcode()) {
       case Op_CallStaticJava:
-        // Uncommon traps don't need barriers, values are handled during deoptimization. It also affects
-        // optimizing null-checks into implicit null-checks.
-        if (n->as_CallStaticJava()->uncommon_trap_request() != 0) {
-          break;
-        }
       case Op_CallDynamicJava:
       case Op_CallLeaf:
       case Op_CallLeafNoFP:
@@ -3089,3 +3328,26 @@ bool ShenandoahLoadReferenceBarrierNode::is_redundant() {
   // No need for barrier found.
   return true;
 }
+
+CallStaticJavaNode* ShenandoahLoadReferenceBarrierNode::pin_and_expand_null_check(PhaseIterGVN& igvn) {
+  Node* val = in(ValueIn);
+
+  const Type* val_t = igvn.type(val);
+
+  if (val_t->meet(TypePtr::NULL_PTR) != val_t &&
+      val->Opcode() == Op_CastPP &&
+      val->in(0) != NULL &&
+      val->in(0)->Opcode() == Op_IfTrue &&
+      val->in(0)->as_Proj()->is_uncommon_trap_if_pattern(Deoptimization::Reason_none) &&
+      val->in(0)->in(0)->is_If() &&
+      val->in(0)->in(0)->in(1)->Opcode() == Op_Bool &&
+      val->in(0)->in(0)->in(1)->as_Bool()->_test._test == BoolTest::ne &&
+      val->in(0)->in(0)->in(1)->in(1)->Opcode() == Op_CmpP &&
+      val->in(0)->in(0)->in(1)->in(1)->in(1) == val->in(1) &&
+      val->in(0)->in(0)->in(1)->in(1)->in(2)->bottom_type() == TypePtr::NULL_PTR) {
+    assert(val->in(0)->in(0)->in(1)->in(1)->in(1) == val->in(1), "");
+    CallStaticJavaNode* unc = val->in(0)->as_Proj()->is_uncommon_trap_if_pattern(Deoptimization::Reason_none);
+    return unc;
+  }
+  return NULL;
+}
diff --git a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp
index 3e15fa09937..1fbd24a0cbd 100644
--- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp
+++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp
@@ -63,6 +63,9 @@ private:
   static void call_lrb_stub(Node*& ctrl, Node*& val, Node* load_addr, Node*& result_mem, Node* raw_mem, bool is_native, PhaseIdealLoop* phase);
   static void test_in_cset(Node*& ctrl, Node*& not_cset_ctrl, Node* val, Node* raw_mem, PhaseIdealLoop* phase);
   static void move_gc_state_test_out_of_loop(IfNode* iff, PhaseIdealLoop* phase);
+  static Node* clone_null_check(Node*& c, Node* val, Node* unc_ctrl, PhaseIdealLoop* phase);
+  static void fix_null_check(Node* unc, Node* unc_ctrl, Node* new_unc_ctrl, Unique_Node_List& uses,
+                             PhaseIdealLoop* phase);
   static void merge_back_to_back_tests(Node* n, PhaseIdealLoop* phase);
   static bool identical_backtoback_ifs(Node *n, PhaseIdealLoop* phase);
   static void fix_ctrl(Node* barrier, Node* region, const MemoryGraphFixer& fixer, Unique_Node_List& uses, Unique_Node_List& uses_to_ignore, uint last, PhaseIdealLoop* phase);
@@ -251,6 +254,7 @@ public:
   virtual bool cmp( const Node &n ) const;
 
   bool is_redundant();
+  CallStaticJavaNode* pin_and_expand_null_check(PhaseIterGVN& igvn);
 
 private:
   bool needs_barrier(PhaseGVN* phase, Node* n);

From e722efa65c5ff94a2aa1498a002fb9adaca6dcd7 Mon Sep 17 00:00:00 2001
From: Aleksey Shipilev 
Date: Tue, 12 May 2020 16:19:53 +0200
Subject: [PATCH 025/143] 8244807: Shenandoah: ditch filter in
 ShenandoahUnload::unload

Reviewed-by: rkennke, zgu
---
 src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp b/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp
index 70e8ecd50a4..19b59d4cc73 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp
@@ -143,13 +143,9 @@ public:
 };
 
 void ShenandoahUnload::unload() {
-  assert(ShenandoahConcurrentRoots::can_do_concurrent_class_unloading(), "Why we here?");
-
   ShenandoahHeap* heap = ShenandoahHeap::heap();
-
-  if (!heap->is_concurrent_weak_root_in_progress()) {
-    return;
-  }
+  assert(ShenandoahConcurrentRoots::can_do_concurrent_class_unloading(), "Filtered by caller");
+  assert(heap->is_concurrent_weak_root_in_progress(), "Filtered by caller");
 
   // Unlink stale metadata and nmethods
   {

From e686fb6bf6c55fe6606b0895462aad7f866baefc Mon Sep 17 00:00:00 2001
From: Magnus Ihse Bursie 
Date: Tue, 12 May 2020 16:35:58 +0200
Subject: [PATCH 026/143] 8244757: Introduce SetupTarget in Main.gmk

Reviewed-by: erikj
---
 make/Main.gmk        | 635 ++++++++++++++++++++++---------------------
 make/MainSupport.gmk |  21 ++
 2 files changed, 348 insertions(+), 308 deletions(-)

diff --git a/make/Main.gmk b/make/Main.gmk
index 1eb3b2b1dfd..65a5911c3a7 100644
--- a/make/Main.gmk
+++ b/make/Main.gmk
@@ -38,13 +38,18 @@ endif
 # Now load the spec
 include $(SPEC)
 
-include $(TOPDIR)/make/MainSupport.gmk
-
 # Load the vital tools for all the makefiles.
 include $(TOPDIR)/make/common/MakeBase.gmk
 include $(TOPDIR)/make/common/Modules.gmk
 include $(TOPDIR)/make/common/FindTests.gmk
 
+include $(TOPDIR)/make/MainSupport.gmk
+
+# Are we requested to ignore dependencies?
+ifneq ($(findstring -only, $(MAKECMDGOALS)), )
+  DEPS := none
+endif
+
 # Declare ALL_TARGETS as an immediate variable. This variable is a list of all
 # valid top level targets. It's used to declare them all as PHONY and to
 # generate the -only targets.
@@ -66,36 +71,40 @@ ALL_MODULES := $(call FindAllModules)
 ################################################################################
 # Interim/build tools targets, compiling tools used during the build
 
-buildtools-langtools:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f ToolsLangtools.gmk)
+$(eval $(call SetupTarget, buildtools-langtools, \
+    MAKEFILE := ToolsLangtools, \
+))
 
-interim-langtools:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f CompileInterimLangtools.gmk)
+$(eval $(call SetupTarget, interim-langtools, \
+    MAKEFILE := CompileInterimLangtools, \
+))
 
-interim-tzdb:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f CopyInterimTZDB.gmk)
+$(eval $(call SetupTarget, interim-tzdb, \
+    MAKEFILE := CopyInterimTZDB, \
+))
 
+$(eval $(call SetupTarget, buildtools-jdk, \
+    MAKEFILE := CompileToolsJdk, \
+    DEPS := interim-langtools interim-tzdb, \
+))
 
-buildtools-jdk:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f CompileToolsJdk.gmk)
+$(eval $(call SetupTarget, buildtools-modules, \
+    MAKEFILE := CompileModuleTools, \
+    DEPS := exploded-image-base, \
+))
 
-buildtools-modules:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f CompileModuleTools.gmk)
-
-buildtools-hotspot:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f CompileToolsHotspot.gmk)
-
-ALL_TARGETS += buildtools-langtools interim-langtools \
-    interim-tzdb buildtools-jdk buildtools-modules \
-    buildtools-hotspot
+$(eval $(call SetupTarget, buildtools-hotspot, \
+    MAKEFILE := CompileToolsHotspot, \
+    DEPS := interim-langtools, \
+))
 
 ################################################################################
 # Special targets for certain modules
 
-generate-exported-symbols:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f BuildStatic.gmk)
-
-ALL_TARGETS += generate-exported-symbols
+$(eval $(call SetupTarget, generate-exported-symbols, \
+    MAKEFILE := BuildStatic, \
+    DEPS := java.base-libs jdk.jdwp.agent-libs, \
+))
 
 ################################################################################
 # Gensrc targets, generating source before java compilation can be done
@@ -251,11 +260,13 @@ endef
 
 $(foreach v, $(JVM_VARIANTS), $(eval $(call DeclareHotspotLibsRecipe,$v)))
 
-hotspot-ide-project:
-	+($(CD) $(TOPDIR)/make/hotspot && $(MAKE) $(MAKE_ARGS) -f ide/CreateVSProject.gmk)
+$(eval $(call SetupTarget, hotspot-ide-project, \
+    MAKEFILE := ide/CreateVSProject, \
+    DEPS := hotspot exploded-image, \
+))
 
 ALL_TARGETS += $(HOTSPOT_VARIANT_TARGETS) $(HOTSPOT_VARIANT_GENSRC_TARGETS) \
-    $(HOTSPOT_VARIANT_LIBS_TARGETS) hotspot-ide-project
+    $(HOTSPOT_VARIANT_LIBS_TARGETS)
 
 ################################################################################
 # Generate libs and launcher targets for creating compile_commands.json fragments
@@ -276,51 +287,67 @@ $(foreach t, $(LIBS_TARGETS) $(LAUNCHER_TARGETS), \
   $(eval $(call DeclareCompileCommandsRecipe,$t,JDK)) \
 )
 
-compile-commands compile-commands-hotspot:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f CompileCommands.gmk)
+$(eval $(call SetupTarget, compile-commands, \
+    MAKEFILE := CompileCommands, \
+))
+
+$(eval $(call SetupTarget, compile-commands-hotspot, \
+    MAKEFILE := CompileCommands, \
+))
 
 ALL_TARGETS += $(COMPILE_COMMANDS_TARGETS_HOTSPOT) $(COMPILE_COMMANDS_TARGETS_JDK)
-ALL_TARGETS += compile-commands compile-commands-hotspot
 
 ################################################################################
 # VS Code projects
-vscode-project:
-	+($(CD) $(TOPDIR)/make/vscode && $(MAKE) $(MAKE_ARGS) -f CreateVSCodeProject.gmk \
-      VSCODE_INDEXER=cpptools)
 
-vscode-project-clangd:
-	+($(CD) $(TOPDIR)/make/vscode && $(MAKE) $(MAKE_ARGS) -f CreateVSCodeProject.gmk \
-      VSCODE_INDEXER=clangd)
+$(eval $(call SetupTarget, vscode-project, \
+    MAKEFILE := CreateVSCodeProject, \
+    ARGS := VSCODE_INDEXER=cpptools, \
+    DEPS := compile-commands, \
+))
 
-vscode-project-rtags:
-	+($(CD) $(TOPDIR)/make/vscode && $(MAKE) $(MAKE_ARGS) -f CreateVSCodeProject.gmk \
-      VSCODE_INDEXER=rtags)
+$(eval $(call SetupTarget, vscode-project-clangd, \
+    MAKEFILE := CreateVSCodeProject, \
+    ARGS := VSCODE_INDEXER=clangd, \
+    DEPS := compile-commands, \
+))
 
-vscode-project-ccls:
-	+($(CD) $(TOPDIR)/make/vscode && $(MAKE) $(MAKE_ARGS) -f CreateVSCodeProject.gmk \
-      VSCODE_INDEXER=ccls)
+$(eval $(call SetupTarget, vscode-project-rtags, \
+    MAKEFILE := CreateVSCodeProject, \
+    ARGS := VSCODE_INDEXER=rtags, \
+    DEPS := compile-commands, \
+))
 
-ALL_TARGETS += vscode-project vscode-project-clangd vscode-project-rtags \
-  vscode-project-ccls
+$(eval $(call SetupTarget, vscode-project-ccls, \
+    MAKEFILE := CreateVSCodeProject, \
+    ARGS := VSCODE_INDEXER=ccls, \
+    DEPS := compile-commands, \
+))
 
 ################################################################################
 # Build demos targets
 
-demos-jdk:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f CompileDemos.gmk)
+# The demos are currently linking to libjvm and libjava, just like all other
+# jdk libs, even though they don't need to. To avoid warnings, make sure they
+# aren't built until after libjava and libjvm are available to link to.
+$(eval $(call SetupTarget, demos-jdk, \
+    MAKEFILE := CompileDemos, \
+    DEPS := java.base-libs exploded-image, \
+))
 
-test-image-demos-jdk:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f CompileDemos.gmk images)
-
-ALL_TARGETS += demos-jdk test-image-demos-jdk
+$(eval $(call SetupTarget, test-image-demos-jdk, \
+    MAKEFILE := CompileDemos, \
+    TARGET := images, \
+    DEPS := demos-jdk, \
+))
 
 ################################################################################
 # Jigsaw specific data and analysis targets.
 
-generate-summary:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f GenerateModuleSummary.gmk)
-
-ALL_TARGETS += generate-summary
+$(eval $(call SetupTarget, generate-summary, \
+    MAKEFILE := GenerateModuleSummary, \
+    DEPS := jmods buildtools-modules, \
+))
 
 ################################################################################
 # Jmod targets
@@ -341,11 +368,15 @@ ALL_TARGETS += $(JMOD_TARGETS)
 ################################################################################
 # Images targets
 
-store-source-revision:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f SourceRevision.gmk store-source-revision)
+$(eval $(call SetupTarget, store-source-revision, \
+    MAKEFILE := SourceRevision, \
+    TARGET := store-source-revision, \
+))
 
-create-source-revision-tracker:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f SourceRevision.gmk create-source-revision-tracker)
+$(eval $(call SetupTarget, create-source-revision-tracker, \
+    MAKEFILE := SourceRevision, \
+    TARGET := create-source-revision-tracker, \
+))
 
 BOOTCYCLE_TARGET := product-images
 bootcycle-images:
@@ -358,97 +389,150 @@ bootcycle-images:
 	  $(call LogWarn, Boot cycle build disabled when cross compiling)
         endif
 
-zip-security:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f ZipSecurity.gmk)
+$(eval $(call SetupTarget, zip-security, \
+    MAKEFILE := ZipSecurity, \
+    DEPS := java.base-java java.security.jgss-java java.security.jgss-libs, \
+))
 
-zip-source:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f ZipSource.gmk)
+$(eval $(call SetupTarget, zip-source, \
+    MAKEFILE := ZipSource, \
+    DEPS := gensrc, \
+))
 
-jrtfs-jar:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f JrtfsJar.gmk)
+$(eval $(call SetupTarget, jrtfs-jar, \
+    MAKEFILE := JrtfsJar, \
+    DEPS := interim-langtools, \
+))
 
-jdk-image:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f Images.gmk jdk)
+$(eval $(call SetupTarget, jdk-image, \
+    MAKEFILE := Images, \
+    TARGET := jdk, \
+    DEPS := jmods zip-source demos release-file, \
+))
 
-legacy-jre-image:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f Images.gmk jre)
+$(eval $(call SetupTarget, legacy-jre-image, \
+    MAKEFILE := Images, \
+    TARGET := jre, \
+    DEPS := jmods release-file, \
+))
 
-symbols-image:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f Images.gmk symbols)
+$(eval $(call SetupTarget, symbols-image, \
+    MAKEFILE := Images, \
+    TARGET := symbols, \
+))
 
-static-libs-image:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f StaticLibsImage.gmk)
+$(eval $(call SetupTarget, static-libs-image, \
+    MAKEFILE := StaticLibsImage, \
+))
 
-mac-jdk-bundle:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f MacBundles.gmk jdk-bundle)
+$(eval $(call SetupTarget, mac-jdk-bundle, \
+    MAKEFILE := MacBundles, \
+    TARGET := jdk-bundle, \
+    DEPS := jdk-image, \
+))
 
-mac-legacy-jre-bundle:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f MacBundles.gmk jre-bundle)
+$(eval $(call SetupTarget, mac-legacy-jre-bundle, \
+    MAKEFILE := MacBundles, \
+    TARGET := jre-bundle, \
+    DEPS := legacy-jre-image, \
+))
 
-release-file:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f ReleaseFile.gmk)
+$(eval $(call SetupTarget, release-file, \
+    MAKEFILE := ReleaseFile, \
+    DEPS := create-source-revision-tracker, \
+))
 
-exploded-image-optimize:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f ExplodedImageOptimize.gmk)
+$(eval $(call SetupTarget, exploded-image-optimize, \
+    MAKEFILE := ExplodedImageOptimize, \
+    DEPS := java copy gendata java.base-libs java.base-launchers \
+        buildtools-modules, \
+))
 
-graal-builder-image:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f GraalBuilderImage.gmk)
+$(eval $(call SetupTarget, graal-builder-image, \
+    MAKEFILE := GraalBuilderImage, \
+    DEPS := jdk-image static-libs-image, \
+))
 
 ifeq ($(JCOV_ENABLED), true)
-  jcov-image:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f Coverage.gmk jcov-image)
+  $(eval $(call SetupTarget, jcov-image, \
+      MAKEFILE := Coverage, \
+      TARGET := jcov-image, \
+      DEPS := jdk-image, \
+  ))
 endif
 
-ALL_TARGETS += store-source-revision create-source-revision-tracker bootcycle-images zip-security \
-    zip-source jrtfs-jar jdk-image legacy-jre-image \
-    symbols-image static-libs-image mac-jdk-bundle mac-legacy-jre-bundle \
-    release-file exploded-image-optimize graal-builder-image jcov-image
+ALL_TARGETS += bootcycle-images
 
 ################################################################################
 # Docs targets
 
 # If building full docs, to complete docs-*-api we need both the javadoc and
 # modulegraph targets.
-docs-jdk-api-javadoc:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f Docs.gmk docs-jdk-api-javadoc)
+$(eval $(call SetupTarget, docs-jdk-api-javadoc, \
+    MAKEFILE := Docs, \
+    TARGET := docs-jdk-api-javadoc, \
+))
 
-docs-jdk-api-modulegraph:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f Docs.gmk docs-jdk-api-modulegraph)
+$(eval $(call SetupTarget, docs-jdk-api-modulegraph, \
+    MAKEFILE := Docs, \
+    TARGET := docs-jdk-api-modulegraph, \
+    DEPS := exploded-image buildtools-modules, \
+))
 
-docs-javase-api-javadoc:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f Docs.gmk docs-javase-api-javadoc)
+$(eval $(call SetupTarget, docs-javase-api-javadoc, \
+    MAKEFILE := Docs, \
+    TARGET := docs-javase-api-javadoc, \
+))
 
-docs-javase-api-modulegraph:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f Docs.gmk docs-javase-api-modulegraph)
+$(eval $(call SetupTarget, docs-javase-api-modulegraph, \
+    MAKEFILE := Docs, \
+    TARGET := docs-javase-api-modulegraph, \
+    DEPS := exploded-image buildtools-modules, \
+))
 
-docs-reference-api-javadoc:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f Docs.gmk docs-reference-api-javadoc)
+$(eval $(call SetupTarget, docs-reference-api-javadoc, \
+    MAKEFILE := Docs, \
+    TARGET := docs-reference-api-javadoc, \
+))
 
-docs-reference-api-modulegraph:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f Docs.gmk docs-reference-api-modulegraph)
+$(eval $(call SetupTarget, docs-reference-api-modulegraph, \
+    MAKEFILE := Docs, \
+    TARGET := docs-reference-api-modulegraph, \
+    DEPS := exploded-image buildtools-modules, \
+))
 
-docs-jdk-specs:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f Docs.gmk docs-jdk-specs)
+# The gensrc steps for jdk.jdi create html spec files.
+$(eval $(call SetupTarget, docs-jdk-specs, \
+    MAKEFILE := Docs, \
+    TARGET := docs-jdk-specs, \
+    DEPS := buildtools-jdk jdk.jdi-gensrc docs-jdk-index, \
+))
 
-docs-jdk-index:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f Docs.gmk docs-jdk-index)
+$(eval $(call SetupTarget, docs-jdk-index, \
+    MAKEFILE := Docs, \
+    TARGET := docs-jdk-index, \
+))
 
-docs-zip:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f Docs.gmk docs-zip)
+$(eval $(call SetupTarget, docs-zip, \
+    MAKEFILE := Docs, \
+    TARGET := docs-zip, \
+    DEPS :=  docs-jdk, \
+))
 
-docs-specs-zip:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f Docs.gmk docs-specs-zip)
+$(eval $(call SetupTarget, docs-specs-zip, \
+    MAKEFILE := Docs, \
+    TARGET := docs-specs-zip, \
+    DEPS := docs-jdk-specs, \
+))
 
-update-build-docs:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f UpdateBuildDocs.gmk)
+$(eval $(call SetupTarget, update-build-docs, \
+    MAKEFILE := UpdateBuildDocs, \
+))
 
-update-x11wrappers:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f UpdateX11Wrappers.gmk)
-
-ALL_TARGETS += docs-jdk-api-javadoc docs-jdk-api-modulegraph \
-    docs-javase-api-javadoc docs-javase-api-modulegraph \
-    docs-reference-api-javadoc docs-reference-api-modulegraph docs-jdk-specs \
-    docs-jdk-index docs-zip docs-specs-zip update-build-docs update-x11wrappers
+$(eval $(call SetupTarget, update-x11wrappers, \
+    MAKEFILE := UpdateX11Wrappers, \
+    DEPS := java.base-copy buildtools-jdk, \
+))
 
 ################################################################################
 # Cross compilation support
@@ -462,17 +546,15 @@ endif
 BUILDJDK_MODULES := $(sort $(foreach m, jdk.jlink $(INTERIM_IMAGE_MODULES), \
     $(call FindTransitiveDepsForModule, $m) $m))
 
-create-buildjdk-interim-image:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f Main.gmk \
-	    $@-helper \
-	    SPEC=$(dir $(SPEC))buildjdk-spec.gmk \
-	    HOTSPOT_SPEC=$(dir $(SPEC))buildjdk-spec.gmk \
-	    CREATING_BUILDJDK=true \
-	    LOG_PREFIX="[buildjdk] " \
-	    JAVA_MODULES="$(BUILDJDK_MODULES)" \
-	)
-
-ALL_TARGETS += create-buildjdk-copy create-buildjdk-interim-image
+$(eval $(call SetupTarget, create-buildjdk-interim-image, \
+    MAKEFILE := Main, \
+    TARGET := create-buildjdk-interim-image-helper, \
+    ARGS := SPEC=$(dir $(SPEC))buildjdk-spec.gmk \
+        HOTSPOT_SPEC=$(dir $(SPEC))buildjdk-spec.gmk \
+        CREATING_BUILDJDK=true \
+        LOG_PREFIX="[buildjdk] " \
+        JAVA_MODULES="$(BUILDJDK_MODULES)", \
+))
 
 ################################################################################
 # The interim-image is a small jlinked image that is used to generate artifacts
@@ -492,16 +574,16 @@ endef
 
 $(foreach m, $(INTERIM_IMAGE_MODULES), $(eval $(call DeclareInterimJmodRecipe,$m)))
 
-interim-image:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f InterimImage.gmk)
+$(eval $(call SetupTarget, interim-image, \
+    MAKEFILE := InterimImage, \
+))
 
 ifeq ($(ENABLE_GENERATE_CLASSLIST), true)
-  generate-link-opt-data:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f GenerateLinkOptData.gmk)
+  $(eval $(call SetupTarget, generate-link-opt-data, \
+      MAKEFILE := GenerateLinkOptData, \
+  ))
 endif
 
-ALL_TARGETS += $(INTERIM_JMOD_TARGETS) interim-image generate-link-opt-data
-
 ################################################################################
 # Generate test names for all JTReg test groups
 #
@@ -530,113 +612,151 @@ ALL_TARGETS += $(ALL_TEST_TARGETS) $(ALL_EXPLODED_TEST_TARGETS)
 # Build tests and microbenchmarks
 #
 
-prepare-test-image:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f TestImage.gmk prepare-test-image)
+$(eval $(call SetupTarget, prepare-test-image, \
+    MAKEFILE := TestImage, \
+    TARGET := prepare-test-image, \
+))
 
-build-test-hotspot-jtreg-native:
-	+($(CD) $(TOPDIR)/make/test && $(MAKE) $(MAKE_ARGS) -f JtregNativeHotspot.gmk \
-	    build-test-hotspot-jtreg-native)
+$(eval $(call SetupTarget, build-test-hotspot-jtreg-native, \
+    MAKEFILE := test/JtregNativeHotspot, \
+    TARGET := build-test-hotspot-jtreg-native, \
+    DEPS := buildtools-jdk, \
+))
 
-test-image-hotspot-jtreg-native:
-	+($(CD) $(TOPDIR)/make/test && $(MAKE) $(MAKE_ARGS) -f JtregNativeHotspot.gmk \
-	    test-image-hotspot-jtreg-native)
+$(eval $(call SetupTarget, test-image-hotspot-jtreg-native, \
+    MAKEFILE := test/JtregNativeHotspot, \
+    TARGET := test-image-hotspot-jtreg-native, \
+    DEPS := build-test-hotspot-jtreg-native, \
+))
 
-build-test-jdk-jtreg-native:
-	+($(CD) $(TOPDIR)/make/test && $(MAKE) $(MAKE_ARGS) -f JtregNativeJdk.gmk \
-	    build-test-jdk-jtreg-native)
+$(eval $(call SetupTarget, build-test-jdk-jtreg-native, \
+    MAKEFILE := test/JtregNativeJdk, \
+    TARGET := build-test-jdk-jtreg-native, \
+    DEPS := buildtools-jdk java.base-libs, \
+))
 
-test-image-jdk-jtreg-native:
-	+($(CD) $(TOPDIR)/make/test && $(MAKE) $(MAKE_ARGS) -f JtregNativeJdk.gmk \
-	    test-image-jdk-jtreg-native)
+$(eval $(call SetupTarget, test-image-jdk-jtreg-native, \
+    MAKEFILE := test/JtregNativeJdk, \
+    TARGET := test-image-jdk-jtreg-native, \
+    DEPS := build-test-jdk-jtreg-native, \
+))
 
-build-test-hotspot-jtreg-graal:
-	+($(CD) $(TOPDIR)/make/test && $(MAKE) $(MAKE_ARGS) -f JtregGraalUnit.gmk \
-	     build-test-hotspot-jtreg-graal)
+$(eval $(call SetupTarget, build-test-hotspot-jtreg-graal, \
+    MAKEFILE := test/JtregGraalUnit, \
+    TARGET := build-test-hotspot-jtreg-graal, \
+    DEPS := exploded-image, \
+))
 
-test-image-hotspot-jtreg-graal:
-	+($(CD) $(TOPDIR)/make/test && $(MAKE) $(MAKE_ARGS) -f JtregGraalUnit.gmk \
-	     test-image-hotspot-jtreg-graal)
+$(eval $(call SetupTarget, test-image-hotspot-jtreg-graal, \
+    MAKEFILE := test/JtregGraalUnit, \
+    TARGET := test-image-hotspot-jtreg-graal, \
+    DEPS := build-test-hotspot-jtreg-graal, \
+))
 
 ifeq ($(BUILD_GTEST), true)
-  test-image-hotspot-gtest:
-	+($(CD) $(TOPDIR)/make/hotspot/test && $(MAKE) $(MAKE_ARGS) -f GtestImage.gmk)
+  $(eval $(call SetupTarget, test-image-hotspot-gtest, \
+      MAKEFILE := hotspot/test/GtestImage, \
+      DEPS := hotspot, \
+  ))
 endif
 
-build-test-lib:
-	+($(CD) $(TOPDIR)/make/test && $(MAKE) $(MAKE_ARGS) -f BuildTestLib.gmk)
+$(eval $(call SetupTarget, build-test-lib, \
+    MAKEFILE := test/BuildTestLib, \
+    DEPS := exploded-image, \
+))
 
 ifeq ($(BUILD_FAILURE_HANDLER), true)
   # Builds the failure handler jtreg extension
-  build-test-failure-handler:
-	+($(CD) $(TOPDIR)/make/test && $(MAKE) $(MAKE_ARGS) \
-	    -f BuildFailureHandler.gmk build)
+  $(eval $(call SetupTarget, build-test-failure-handler, \
+      MAKEFILE := test/BuildFailureHandler, \
+      TARGET := build, \
+      DEPS := interim-langtools, \
+  ))
 
   # Copies the failure handler jtreg extension into the test image
-  test-image-failure-handler:
-	+($(CD) $(TOPDIR)/make/test && $(MAKE) $(MAKE_ARGS) \
-	     -f BuildFailureHandler.gmk images)
+  $(eval $(call SetupTarget, test-image-failure-handler, \
+      MAKEFILE := test/BuildFailureHandler, \
+      TARGET := images, \
+      DEPS := build-test-failure-handler, \
+  ))
 endif
 
-build-microbenchmark:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f test/BuildMicrobenchmark.gmk)
-
-ALL_TARGETS += prepare-test-image build-test-hotspot-jtreg-native \
-    test-image-hotspot-jtreg-native build-test-jdk-jtreg-native \
-    test-image-jdk-jtreg-native build-test-lib build-test-failure-handler \
-    test-failure-handler test-image-failure-handler test-image-hotspot-gtest \
-    test-image-hotspot-jtreg-graal build-test-hotspot-jtreg-graal \
-    build-microbenchmark
+$(eval $(call SetupTarget, build-microbenchmark, \
+    MAKEFILE := test/BuildMicrobenchmark, \
+    DEPS := interim-langtools exploded-image, \
+))
 
 ################################################################################
 # Run tests
 
-test:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f RunTests.gmk \
-	    TEST="$(TEST)")
+$(eval $(call SetupTarget, test, \
+    MAKEFILE := RunTests, \
+    ARGS := TEST="$(TEST)", \
+    DEPS := jdk-image test-image, \
+))
 
-exploded-test:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f RunTests.gmk \
-	    TEST="$(TEST)" JDK_IMAGE_DIR=$(JDK_OUTPUTDIR))
+$(eval $(call SetupTarget, exploded-test, \
+    MAKEFILE := RunTests, \
+    ARGS := TEST="$(TEST)" JDK_IMAGE_DIR=$(JDK_OUTPUTDIR), \
+    DEPS := exploded-image test-image, \
+))
 
-jcov-test:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f RunTests.gmk \
-	    TEST="$(TEST)" TEST_OPTS_JCOV=true)
-
-ALL_TARGETS += test exploded-test jcov-test
+ifeq ($(JCOV_ENABLED), true)
+  $(eval $(call SetupTarget, jcov-test, \
+      MAKEFILE := RunTests, \
+      ARGS := TEST="$(TEST)" TEST_OPTS_JCOV=true, \
+      DEPS := jcov-image test-image, \
+  ))
+endif
 
 ################################################################################
 # Bundles
 
-product-bundles:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f Bundles.gmk product-bundles)
+$(eval $(call SetupTarget, product-bundles, \
+    MAKEFILE := Bundles, \
+    TARGET := product-bundles, \
+    DEPS := product-images, \
+))
 
-legacy-bundles:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f Bundles.gmk legacy-bundles)
+$(eval $(call SetupTarget, legacy-bundles, \
+    MAKEFILE := Bundles, \
+    TARGET := legacy-bundles, \
+    DEPS := legacy-images, \
+))
 
-test-bundles:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f Bundles.gmk test-bundles)
+$(eval $(call SetupTarget, test-bundles, \
+    MAKEFILE := Bundles, \
+    TARGET := test-bundles, \
+    DEPS := test-image, \
+))
 
-docs-bundles:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f Bundles.gmk docs-bundles)
+$(eval $(call SetupTarget, docs-bundles, \
+    MAKEFILE := Bundles, \
+    TARGET := docs-bundles, \
+    DEPS := docs-image, \
+))
 
-static-libs-bundles:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f Bundles.gmk static-libs-bundles)
+$(eval $(call SetupTarget, static-libs-bundles, \
+    MAKEFILE := Bundles, \
+    TARGET := static-libs-bundles, \
+    DEPS := static-libs-image, \
+))
 
 ifeq ($(JCOV_ENABLED), true)
-  jcov-bundles:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f Bundles.gmk jcov-bundles)
+  $(eval $(call SetupTarget, jcov-bundles, \
+      MAKEFILE := Bundles, \
+      TARGET := jcov-bundles, \
+      DEPS := jcov-image, \
+  ))
 endif
 
-ALL_TARGETS += product-bundles legacy-bundles test-bundles docs-bundles \
-    static-libs-bundles jcov-bundles
-
 ################################################################################
 # Install targets
 
-install:
-	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f Install.gmk)
-
-ALL_TARGETS += install
+$(eval $(call SetupTarget, install, \
+    MAKEFILE := Install, \
+    DEPS := product-images, \
+))
 
 ################################################################################
 #
@@ -654,19 +774,13 @@ ALL_TARGETS += install
 # recipe targets are disabled. This makes it possible to run a select set of
 # recipe targets in order. It's the responsibility of the user to make sure
 # all prerequisites are fulfilled.
-ifneq ($(findstring -only, $(MAKECMDGOALS)), )
+ifeq ($(DEPS), none)
   .NOTPARALLEL:
 else
   $(LANGTOOLS_GENSRC_TARGETS): buildtools-langtools
 
   interim-langtools: $(INTERIM_LANGTOOLS_GENSRC_TARGETS)
 
-  buildtools-jdk: interim-langtools interim-tzdb
-
-  buildtools-hotspot: interim-langtools
-
-  buildtools-modules: exploded-image-base
-
   $(HOTSPOT_GENSRC_TARGETS): interim-langtools buildtools-hotspot
 
   $(JDK_GENSRC_TARGETS): interim-langtools buildtools-jdk
@@ -683,10 +797,6 @@ else
       $(eval hotspot-$v-libs: hotspot-$v-gensrc java.base-copy) \
   )
 
-  hotspot-ide-project: hotspot exploded-image
-
-  generate-exported-symbols: java.base-libs jdk.jdwp.agent-libs
-
   # If not already set, set the JVM variant target so that the JVM will be built.
   JVM_MAIN_LIB_TARGETS ?= hotspot-$(JVM_VARIANT_MAIN)-libs
 
@@ -699,12 +809,6 @@ else
     $(LAUNCHER_TARGETS): generate-exported-symbols
   endif
 
-  # The demos are currently linking to libjvm and libjava, just like all other
-  # jdk libs, even though they don't need to. To avoid warnings, make sure they
-  # aren't built until after libjava and libjvm are available to link to.
-  demos-jdk: java.base-libs exploded-image
-  test-image-demos-jdk: demos-jdk
-
   # Declare dependency from -java to -gensrc
   $(foreach m, $(GENSRC_MODULES), $(eval $m-java: $m-gensrc))
 
@@ -792,11 +896,6 @@ else
   compile-commands-hotspot: $(COMPILE_COMMANDS_TARGETS_HOTSPOT)
   compile-commands: $(COMPILE_COMMANDS_TARGETS_HOTSPOT) $(COMPILE_COMMANDS_TARGETS_JDK)
 
-  vscode-project: compile-commands
-  vscode-project-clangd: compile-commands
-  vscode-project-rtags: compile-commands
-  vscode-project-ccls: compile-commands
-
   # The -static-libs targets depend on -java as well as java.base-copy.
   $(foreach m, $(filter $(JAVA_MODULES), $(STATIC_LIBS_MODULES)), \
     $(eval $m-static-libs: $m-java java.base-copy))
@@ -832,14 +931,7 @@ else
   # All modules include the main license files from java.base.
   $(JMOD_TARGETS): java.base-copy
 
-  zip-security: java.base-java java.security.jgss-java java.security.jgss-libs \
-      $(filter jdk.crypto%, $(JAVA_TARGETS))
-
-  zip-source: gensrc
-
-  jrtfs-jar: interim-langtools
-
-  build-microbenchmark: interim-langtools exploded-image
+  zip-security: $(filter jdk.crypto%, $(JAVA_TARGETS))
 
   ifeq ($(ENABLE_GENERATE_CLASSLIST), true)
     ifeq ($(CREATE_BUILDJDK), true)
@@ -857,29 +949,10 @@ else
     java.base-jmod jdk.jlink-jmod jdk-image legacy-jre-image: generate-link-opt-data
   endif
 
-  release-file: create-source-revision-tracker
-
-  jdk-image: jmods zip-source demos release-file
-  legacy-jre-image: jmods release-file
   symbols-image: $(LIBS_TARGETS) $(LAUNCHER_TARGETS)
 
   static-libs-image: $(STATIC_LIBS_TARGETS)
 
-  graal-builder-image: jdk-image static-libs-image
-
-  mac-jdk-bundle: jdk-image
-  mac-legacy-jre-bundle: legacy-jre-image
-
-  ifeq ($(JCOV_INPUT_JDK), )
-    jcov-image: jdk-image
-  endif
-
-  # The optimize target can run as soon as the modules dir has been completely
-  # populated (java, copy and gendata targets) and the basic libs and launchers
-  # have been built.
-  exploded-image-optimize: java copy gendata java.base-libs java.base-launchers \
-      buildtools-modules
-
   bootcycle-images: jdk-image
 
   docs-jdk-api-javadoc: $(GENSRC_TARGETS)
@@ -888,30 +961,13 @@ else
 
   docs-reference-api-javadoc: $(GENSRC_TARGETS)
 
-  docs-jdk-api-modulegraph: exploded-image buildtools-modules
-
-  docs-javase-api-modulegraph: exploded-image buildtools-modules
-
-  docs-reference-api-modulegraph: exploded-image buildtools-modules
-
   # If not already set, then set the JVM specific docs targets
   JVM_DOCS_TARGETS ?= hotspot-$(JVM_VARIANT_MAIN)-gensrc
 
-  # The gensrc steps for hotspot and jdk.jdi create html spec files.
-  docs-jdk-specs: buildtools-jdk $(JVM_DOCS_TARGETS) jdk.jdi-gensrc \
-      docs-jdk-index
-
-  docs-zip: docs-jdk
-
-  docs-specs-zip: docs-jdk-specs
+  # The gensrc steps for hotspot create html spec files.
+  docs-jdk-specs: $(JVM_DOCS_TARGETS)
 
   # Tests
-  test: jdk-image test-image
-
-  exploded-test: exploded-image test-image
-
-  jcov-test: jcov-image test-image
-
   test-make: clean-test-make compile-commands
 
   test-make-compile-commands: compile-commands
@@ -922,44 +978,7 @@ else
 
   interim-image: $(INTERIM_JMOD_TARGETS)
 
-  build-test-lib: exploded-image
-
-  build-test-failure-handler: interim-langtools
-
-  test-image-failure-handler: build-test-failure-handler
-
-  build-test-hotspot-jtreg-native: buildtools-jdk \
-      hotspot-$(JVM_VARIANT_MAIN)-libs
-
-  build-test-jdk-jtreg-native: buildtools-jdk java.base-libs
-
-  build-test-hotspot-jtreg-graal: exploded-image
-
-  test-image-hotspot-jtreg-native: build-test-hotspot-jtreg-native
-
-  test-image-jdk-jtreg-native: build-test-jdk-jtreg-native
-
-  test-image-hotspot-jtreg-graal: build-test-hotspot-jtreg-graal
-
-  test-image-hotspot-gtest: hotspot
-
-  install: product-images
-
-  product-bundles: product-images
-
-  legacy-bundles: legacy-images
-
-  test-bundles: test-image
-
-  docs-bundles: docs-image
-
-  jcov-bundles: jcov-image
-
-  static-libs-bundles: static-libs-image
-
-  generate-summary: jmods buildtools-modules
-
-  update-x11wrappers: java.base-copy buildtools-jdk
+  build-test-hotspot-jtreg-native: hotspot-$(JVM_VARIANT_MAIN)-libs
 
 endif
 
diff --git a/make/MainSupport.gmk b/make/MainSupport.gmk
index 5fdcd77e2f8..0e5068ea709 100644
--- a/make/MainSupport.gmk
+++ b/make/MainSupport.gmk
@@ -30,6 +30,27 @@
 ifndef _MAINSUPPORT_GMK
 _MAINSUPPORT_GMK := 1
 
+# Setup make rules for creating a top-level target.
+# Parameter 1 is the name of the rule. This name is used as variable prefix.
+#
+# Remaining parameters are named arguments. These include:
+#   MAKEFILE the makefile to delegate to
+#   TARGET the makefile target
+#   ARGS arguments to the makefile
+#   DEPS the target(s) this new rule depends on
+#
+SetupTarget = $(NamedParamsMacroTemplate)
+define SetupTargetBody
+  $1:
+	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f $$($1_MAKEFILE).gmk $$($1_TARGET) $$($1_ARGS))
+
+  ALL_TARGETS += $1
+
+  ifneq ($(DEPS), none)
+    $1: $$($1_DEPS)
+  endif
+endef
+
 define CleanDocs
 	@$(PRINTF) "Cleaning docs ..."
 	@$(PRINTF) "\n" $(LOG_DEBUG)

From a726aca6de59f038bd1a10ab07f585ee5962de4c Mon Sep 17 00:00:00 2001
From: Daniil Titov 
Date: Tue, 12 May 2020 09:45:24 -0700
Subject: [PATCH 027/143] 8242009: Review setting test.java/vm.opts in
 jcmd/jhsdb and debugger in serviceability tests

Reviewed-by: cjplummer
---
 .../serviceability/attach/ConcAttachTest.java |  4 +-
 .../attach/RemovingUnixDomainSocketTest.java  |  6 +-
 .../serviceability/sa/CDSJMapClstats.java     |  5 +-
 .../serviceability/sa/ClhsdbDumpclass.java    |  4 +-
 .../sa/ClhsdbJstackXcompStress.java           |  6 +-
 .../serviceability/sa/ClhsdbLauncher.java     |  6 +-
 .../sa/DeadlockDetectionTest.java             |  3 +-
 .../sa/JhsdbThreadInfoTest.java               | 19 +----
 .../sa/TestHeapDumpForInvokeDynamic.java      |  9 +--
 .../sa/TestJhsdbJstackLock.java               | 25 +-----
 .../sa/TestJhsdbJstackMixed.java              |  1 +
 .../jtreg/serviceability/sa/TestJmapCore.java |  3 +-
 .../jtreg/serviceability/sa/TestSysProps.java |  8 +-
 .../sa/jmap-hprof/JMapHProfLargeHeapTest.java |  3 +-
 .../sa/sadebugd/DebugdConnectTest.java        | 11 +--
 .../sa/sadebugd/DebugdUtils.java              |  4 +-
 .../sa/sadebugd/SADebugDTest.java             |  1 +
 .../tmtools/jstack/JstackThreadTest.java      |  3 +-
 test/jdk/sun/tools/jcmd/JcmdBase.java         |  4 +-
 .../tools/jcmd/JcmdOutputEncodingTest.java    |  4 +-
 test/jdk/sun/tools/jcmd/TestJcmdDefaults.java |  4 +-
 test/jdk/sun/tools/jcmd/TestJcmdSanity.java   |  4 +-
 .../sun/tools/jhsdb/BasicLauncherTest.java    |  2 +-
 test/jdk/sun/tools/jhsdb/HeapDumpTest.java    |  2 +
 .../sun/tools/jhsdb/JShellHeapDumpTest.java   |  2 +
 test/jdk/sun/tools/jinfo/BasicJInfoTest.java  |  4 +-
 test/jdk/sun/tools/jinfo/JInfoTest.java       |  2 +
 test/jdk/sun/tools/jmap/BasicJMapTest.java    |  4 +-
 test/jdk/sun/tools/jps/JpsHelper.java         |  1 +
 .../jdk/sun/tools/jstack/BasicJStackTest.java |  4 +-
 .../tools/jstack/DeadlockDetectionTest.java   |  1 +
 test/jdk/sun/tools/jstat/JStatInterval.java   |  4 +-
 test/jdk/sun/tools/jstatd/JstatdTest.java     |  8 +-
 .../jdk/sun/tools/jstatd/TestJstatdUsage.java |  2 +
 test/lib/jdk/test/lib/JDKToolLauncher.java    | 21 ++++-
 .../jdk/test/lib/process/OutputAnalyzer.java  | 76 ++++++++++++++-----
 36 files changed, 161 insertions(+), 109 deletions(-)

diff --git a/test/hotspot/jtreg/serviceability/attach/ConcAttachTest.java b/test/hotspot/jtreg/serviceability/attach/ConcAttachTest.java
index 53ac66b2db5..db2ea216b35 100644
--- a/test/hotspot/jtreg/serviceability/attach/ConcAttachTest.java
+++ b/test/hotspot/jtreg/serviceability/attach/ConcAttachTest.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
@@ -39,6 +39,7 @@ import java.util.concurrent.TimeUnit;
 import com.sun.tools.attach.VirtualMachine;
 import com.sun.tools.attach.AttachNotSupportedException;
 
+import jdk.test.lib.Utils;
 import jdk.test.lib.apps.LingeredApp;
 import jdk.test.lib.Asserts;
 import jdk.test.lib.JDKToolLauncher;
@@ -80,6 +81,7 @@ public class ConcAttachTest implements Runnable {
 
     private static void checkAttachListenerThread() throws InterruptedException, IOException {
         JDKToolLauncher jcmd = JDKToolLauncher.createUsingTestJDK("jcmd");
+        jcmd.addVMArgs(Utils.getTestJavaOpts());
         jcmd.addToolArg(strPID);
         jcmd.addToolArg("Thread.print");
 
diff --git a/test/hotspot/jtreg/serviceability/attach/RemovingUnixDomainSocketTest.java b/test/hotspot/jtreg/serviceability/attach/RemovingUnixDomainSocketTest.java
index fafbf6e4d84..2fd36be8840 100644
--- a/test/hotspot/jtreg/serviceability/attach/RemovingUnixDomainSocketTest.java
+++ b/test/hotspot/jtreg/serviceability/attach/RemovingUnixDomainSocketTest.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
@@ -32,6 +32,7 @@
 import java.io.IOException;
 import java.nio.file.Path;
 
+import jdk.test.lib.Utils;
 import jdk.test.lib.apps.LingeredApp;
 import jdk.test.lib.JDKToolLauncher;
 import jdk.test.lib.process.OutputAnalyzer;
@@ -40,6 +41,7 @@ public class RemovingUnixDomainSocketTest {
 
     private static void runJCmd(long pid) throws InterruptedException, IOException {
         JDKToolLauncher jcmd = JDKToolLauncher.createUsingTestJDK("jcmd");
+        jcmd.addVMArgs(Utils.getTestJavaOpts());
         jcmd.addToolArg(Long.toString(pid));
         jcmd.addToolArg("VM.version");
 
@@ -53,7 +55,7 @@ public class RemovingUnixDomainSocketTest {
         System.out.println(out.getStdout());
         System.err.println(out.getStderr());
 
-        out.stderrShouldBeEmpty();
+        out.stderrShouldBeEmptyIgnoreVMWarnings();
     }
 
     public static void main(String... args) throws Exception {
diff --git a/test/hotspot/jtreg/serviceability/sa/CDSJMapClstats.java b/test/hotspot/jtreg/serviceability/sa/CDSJMapClstats.java
index 88fd334dcae..8273132963d 100644
--- a/test/hotspot/jtreg/serviceability/sa/CDSJMapClstats.java
+++ b/test/hotspot/jtreg/serviceability/sa/CDSJMapClstats.java
@@ -30,9 +30,9 @@
  * @run main/othervm/timeout=2400 CDSJMapClstats
  */
 
-import java.util.List;
-import java.util.Arrays;
 import java.util.stream.Collectors;
+
+import jdk.test.lib.Utils;
 import jdk.test.lib.cds.CDSTestUtils;
 import jdk.test.lib.cds.CDSOptions;
 import jdk.test.lib.apps.LingeredApp;
@@ -46,6 +46,7 @@ public class CDSJMapClstats {
     private static void runClstats(long lingeredAppPid) throws Exception {
 
         JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jhsdb");
+        launcher.addVMArgs(Utils.getTestJavaOpts());
         launcher.addToolArg("jmap");
         launcher.addToolArg("--clstats");
         launcher.addToolArg("--pid");
diff --git a/test/hotspot/jtreg/serviceability/sa/ClhsdbDumpclass.java b/test/hotspot/jtreg/serviceability/sa/ClhsdbDumpclass.java
index 635161020fd..801a8646e8b 100644
--- a/test/hotspot/jtreg/serviceability/sa/ClhsdbDumpclass.java
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbDumpclass.java
@@ -27,11 +27,10 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import jdk.test.lib.Utils;
 import jdk.test.lib.apps.LingeredApp;
 import jdk.test.lib.JDKToolLauncher;
-import jdk.test.lib.JDKToolFinder;
 import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.SA.SATestUtils;
 import jtreg.SkippedException;
 
 /**
@@ -70,6 +69,7 @@ public class ClhsdbDumpclass {
 
             // Run javap on the generated class file to make sure it's valid.
             JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("javap");
+            launcher.addVMArgs(Utils.getTestJavaOpts());
             launcher.addToolArg(APP_DOT_CLASSNAME);
             System.out.println("> javap " + APP_DOT_CLASSNAME);
             List cmdStringList = Arrays.asList(launcher.getCommand());
diff --git a/test/hotspot/jtreg/serviceability/sa/ClhsdbJstackXcompStress.java b/test/hotspot/jtreg/serviceability/sa/ClhsdbJstackXcompStress.java
index 05a6bfcf24a..385a4c56bda 100644
--- a/test/hotspot/jtreg/serviceability/sa/ClhsdbJstackXcompStress.java
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbJstackXcompStress.java
@@ -22,11 +22,8 @@
  * questions.
  */
 
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
 import jdk.test.lib.JDKToolLauncher;
@@ -61,6 +58,7 @@ public class ClhsdbJstackXcompStress {
         for (int i = 0; i < MAX_ITERATIONS; i++) {
             JDKToolLauncher launcher = JDKToolLauncher
                     .createUsingTestJDK("jhsdb");
+            launcher.addVMArgs(Utils.getFilteredTestJavaOpts("-Xcomp"));
             launcher.addToolArg("jstack");
             launcher.addToolArg("--pid");
             launcher.addToolArg(Long.toString(app.getPid()));
@@ -76,7 +74,7 @@ public class ClhsdbJstackXcompStress {
                 System.err.println(out.getStderr());
             }
 
-            out.stderrShouldBeEmpty(); // NPE's are reported on the err stream
+            out.stderrShouldBeEmptyIgnoreVMWarnings();
             out.stdoutShouldNotContain("Error occurred during stack walking:");
             out.stdoutShouldContain(LingeredAppWithRecComputation.THREAD_NAME);
             List stdoutList = Arrays.asList(out.getStdout().split("\\R"));
diff --git a/test/hotspot/jtreg/serviceability/sa/ClhsdbLauncher.java b/test/hotspot/jtreg/serviceability/sa/ClhsdbLauncher.java
index 787293db15d..49388f5d526 100644
--- a/test/hotspot/jtreg/serviceability/sa/ClhsdbLauncher.java
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbLauncher.java
@@ -25,10 +25,8 @@ import java.io.IOException;
 import java.io.OutputStream;
 import java.util.List;
 import java.util.Map;
-import java.util.Arrays;
 
-import jdk.test.lib.apps.LingeredApp;
-import jdk.test.lib.Platform;
+import jdk.test.lib.Utils;
 import jdk.test.lib.JDKToolLauncher;
 import jdk.test.lib.JDKToolFinder;
 import jdk.test.lib.process.OutputAnalyzer;
@@ -56,6 +54,7 @@ public class ClhsdbLauncher {
     private void attach(long lingeredAppPid)
         throws IOException {
         JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jhsdb");
+        launcher.addVMArgs(Utils.getTestJavaOpts());
         launcher.addToolArg("clhsdb");
         if (lingeredAppPid != -1) {
             launcher.addToolArg("--pid=" + Long.toString(lingeredAppPid));
@@ -75,6 +74,7 @@ public class ClhsdbLauncher {
         throws IOException {
 
         JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jhsdb");
+        launcher.addVMArgs(Utils.getTestJavaOpts());
         launcher.addToolArg("clhsdb");
         launcher.addToolArg("--core=" + coreFileName);
         launcher.addToolArg("--exe=" + JDKToolFinder.getTestJDKTool("java"));
diff --git a/test/hotspot/jtreg/serviceability/sa/DeadlockDetectionTest.java b/test/hotspot/jtreg/serviceability/sa/DeadlockDetectionTest.java
index 95c4a2fd152..969c366ed3a 100644
--- a/test/hotspot/jtreg/serviceability/sa/DeadlockDetectionTest.java
+++ b/test/hotspot/jtreg/serviceability/sa/DeadlockDetectionTest.java
@@ -31,8 +31,6 @@
  * @run main DeadlockDetectionTest
  */
 
-import java.util.ArrayList;
-import java.util.List;
 import java.util.stream.Collectors;
 
 import jdk.test.lib.apps.LingeredApp;
@@ -51,6 +49,7 @@ public class DeadlockDetectionTest {
 
     private static OutputAnalyzer jstack(String... toolArgs) throws Exception {
         JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jhsdb");
+        launcher.addVMArgs(Utils.getTestJavaOpts());
         launcher.addToolArg("jstack");
         if (toolArgs != null) {
             for (String toolArg : toolArgs) {
diff --git a/test/hotspot/jtreg/serviceability/sa/JhsdbThreadInfoTest.java b/test/hotspot/jtreg/serviceability/sa/JhsdbThreadInfoTest.java
index 9e683cf62d9..a5cdb6fb177 100644
--- a/test/hotspot/jtreg/serviceability/sa/JhsdbThreadInfoTest.java
+++ b/test/hotspot/jtreg/serviceability/sa/JhsdbThreadInfoTest.java
@@ -21,14 +21,8 @@
  * questions.
  */
 
-import java.util.Arrays;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
 import jdk.test.lib.apps.LingeredApp;
 import jdk.test.lib.JDKToolLauncher;
-import jdk.test.lib.Platform;
 import jdk.test.lib.process.OutputAnalyzer;
 import jdk.test.lib.SA.SATestUtils;
 import jdk.test.lib.Utils;
@@ -50,6 +44,7 @@ public class JhsdbThreadInfoTest {
             System.out.println("Started LingeredApp with pid " + app.getPid());
 
             JDKToolLauncher jhsdbLauncher = JDKToolLauncher.createUsingTestJDK("jhsdb");
+            jhsdbLauncher.addVMArgs(Utils.getTestJavaOpts());
 
             jhsdbLauncher.addToolArg("jstack");
             jhsdbLauncher.addToolArg("--pid");
@@ -73,17 +68,7 @@ public class JhsdbThreadInfoTest {
             out.shouldNotContain(" prio=0 ");
             out.shouldNotContain("   java.lang.Thread.State: UNKNOWN");
 
-            // stderr should be empty except for VM warnings.
-            if (!out.getStderr().isEmpty()) {
-                List lines = Arrays.asList(out.getStderr().split("(\\r\\n|\\n|\\r)"));
-                Pattern p = Pattern.compile(".*VM warning.*");
-                for (String line : lines) {
-                    Matcher m = p.matcher(line);
-                    if (!m.matches()) {
-                        throw new RuntimeException("Stderr has output other than VM warnings");
-                    }
-                }
-            }
+            out.stderrShouldBeEmptyIgnoreVMWarnings();
 
             System.out.println("Test Completed");
         } catch (Exception ex) {
diff --git a/test/hotspot/jtreg/serviceability/sa/TestHeapDumpForInvokeDynamic.java b/test/hotspot/jtreg/serviceability/sa/TestHeapDumpForInvokeDynamic.java
index 80571f7dc21..028e25fd7e4 100644
--- a/test/hotspot/jtreg/serviceability/sa/TestHeapDumpForInvokeDynamic.java
+++ b/test/hotspot/jtreg/serviceability/sa/TestHeapDumpForInvokeDynamic.java
@@ -21,28 +21,20 @@
  * questions.
  */
 
-import java.util.ArrayList;
-import java.util.List;
 import java.io.File;
-import java.nio.file.Files;
 import java.io.IOException;
 import java.io.BufferedInputStream;
 import java.util.stream.Collectors;
 import java.io.FileInputStream;
 
-import sun.jvm.hotspot.HotSpotAgent;
-import sun.jvm.hotspot.debugger.*;
 
 import jdk.test.lib.apps.LingeredApp;
 import jdk.test.lib.Asserts;
 import jdk.test.lib.JDKToolLauncher;
-import jdk.test.lib.JDKToolFinder;
-import jdk.test.lib.Platform;
 import jdk.test.lib.process.ProcessTools;
 import jdk.test.lib.process.OutputAnalyzer;
 import jdk.test.lib.SA.SATestUtils;
 import jdk.test.lib.Utils;
-import jdk.test.lib.hprof.HprofParser;
 import jdk.test.lib.hprof.parser.HprofReader;
 import jdk.test.lib.hprof.parser.PositionDataInputStream;
 import jdk.test.lib.hprof.model.Snapshot;
@@ -91,6 +83,7 @@ public class TestHeapDumpForInvokeDynamic {
                                             long lingeredAppPid) throws Exception {
 
         JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jhsdb");
+        launcher.addVMArgs(Utils.getTestJavaOpts());
         launcher.addToolArg("jmap");
         launcher.addToolArg("--binaryheap");
         launcher.addToolArg("--dumpfile");
diff --git a/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackLock.java b/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackLock.java
index 9f9dc61703c..60d990d76fe 100644
--- a/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackLock.java
+++ b/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackLock.java
@@ -21,20 +21,9 @@
  * questions.
  */
 
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
 import jdk.test.lib.apps.LingeredApp;
-import jdk.test.lib.Asserts;
 import jdk.test.lib.JDKToolLauncher;
-import jdk.test.lib.Platform;
 import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.process.ProcessTools;
 import jdk.test.lib.SA.SATestUtils;
 import jdk.test.lib.Utils;
 
@@ -57,6 +46,7 @@ public class TestJhsdbJstackLock {
             System.out.println ("Started LingeredApp with pid " + app.getPid());
 
             JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jhsdb");
+            launcher.addVMArgs(Utils.getTestJavaOpts());
             launcher.addToolArg("jstack");
             launcher.addToolArg("--pid");
             launcher.addToolArg(Long.toString(app.getPid()));
@@ -75,18 +65,7 @@ public class TestJhsdbJstackLock {
             out.shouldMatch("^\\s+- locked <0x[0-9a-f]+> \\(a java\\.lang\\.Thread\\)$");
             out.shouldMatch("^\\s+- locked <0x[0-9a-f]+> \\(a java\\.lang\\.Class for int\\)$");
 
-            // stderr should be empty except for VM warnings.
-            if (!out.getStderr().isEmpty()) {
-                List lines = Arrays.asList(out.getStderr().split("(\\r\\n|\\n|\\r)"));
-                Pattern p = Pattern.compile(".*VM warning.*");
-                for (String line : lines) {
-                    Matcher m = p.matcher(line);
-                    if (!m.matches()) {
-                        throw new RuntimeException("Stderr has output other than VM warnings");
-                    }
-                }
-            }
-
+            out.stderrShouldBeEmptyIgnoreVMWarnings();
 
             System.out.println("Test Completed");
         } finally {
diff --git a/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackMixed.java b/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackMixed.java
index e5db380e1fb..149a7028be8 100644
--- a/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackMixed.java
+++ b/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackMixed.java
@@ -132,6 +132,7 @@ public class TestJhsdbJstackMixed {
         for (int i = 0; i < MAX_ITERATIONS; i++) {
             JDKToolLauncher launcher = JDKToolLauncher
                     .createUsingTestJDK("jhsdb");
+            launcher.addVMArgs(Utils.getTestJavaOpts());
             launcher.addToolArg("jstack");
             launcher.addToolArg("--mixed");
             launcher.addToolArg("--pid");
diff --git a/test/hotspot/jtreg/serviceability/sa/TestJmapCore.java b/test/hotspot/jtreg/serviceability/sa/TestJmapCore.java
index e236db618d7..1c5780a1957 100644
--- a/test/hotspot/jtreg/serviceability/sa/TestJmapCore.java
+++ b/test/hotspot/jtreg/serviceability/sa/TestJmapCore.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
@@ -120,6 +120,7 @@ public class TestJmapCore {
 
         File dumpFile = new File("heap.hprof");
         JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jhsdb");
+        launcher.addVMArgs(Utils.getTestJavaOpts());
         launcher.addToolArg("jmap");
         launcher.addToolArg("--binaryheap");
         launcher.addToolArg("--dumpfile=" + dumpFile);
diff --git a/test/hotspot/jtreg/serviceability/sa/TestSysProps.java b/test/hotspot/jtreg/serviceability/sa/TestSysProps.java
index 524a9c8dfc0..0f8e05bb994 100644
--- a/test/hotspot/jtreg/serviceability/sa/TestSysProps.java
+++ b/test/hotspot/jtreg/serviceability/sa/TestSysProps.java
@@ -21,10 +21,10 @@
  * questions.
  */
 
-import java.io.OutputStream;
 import java.util.Arrays;
 import java.util.List;
 
+import jdk.test.lib.Utils;
 import jdk.test.lib.apps.LingeredApp;
 import jdk.test.lib.JDKToolLauncher;
 import jdk.test.lib.Platform;
@@ -58,7 +58,9 @@ public class TestSysProps {
     public static void countProps(String[] propLines, int expectedCount, String cmdName) {
         int numProps = 0;
         for (String propLine : propLines) {
-            if (propLine.indexOf("=") != -1) {
+            // Ignore the debug output lines (they start with '[' and printed
+            // in the output when the test is run with -Xlog VM option).
+            if (!propLine.startsWith("[") && propLine.indexOf("=") != -1) {
                 numProps++;
             }
         }
@@ -79,6 +81,7 @@ public class TestSysProps {
             // Get properties using the SA version of jinfo
 
             JDKToolLauncher jhsdbLauncher = JDKToolLauncher.createUsingTestJDK("jhsdb");
+            jhsdbLauncher.addVMArgs(Utils.getTestJavaOpts());
             jhsdbLauncher.addToolArg("jinfo");
             jhsdbLauncher.addToolArg("--sysprops");
             jhsdbLauncher.addToolArg("--pid");
@@ -99,6 +102,7 @@ public class TestSysProps {
             // Get the properties using the Attach API version of jinfo
 
             JDKToolLauncher jinfoLauncher = JDKToolLauncher.createUsingTestJDK("jinfo");
+            jinfoLauncher.addVMArgs(Utils.getTestJavaOpts());
             jinfoLauncher.addToolArg("-sysprops");
             jinfoLauncher.addToolArg(Long.toString(app.getPid()));
 
diff --git a/test/hotspot/jtreg/serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java b/test/hotspot/jtreg/serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java
index 7f0bc7c21ef..ecadb102909 100644
--- a/test/hotspot/jtreg/serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java
+++ b/test/hotspot/jtreg/serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java
@@ -33,7 +33,7 @@ import java.util.Scanner;
 
 import jdk.test.lib.Asserts;
 import jdk.test.lib.JDKToolLauncher;
-import jdk.test.lib.Platform;
+import jdk.test.lib.Utils;
 import jdk.test.lib.process.OutputAnalyzer;
 import jdk.test.lib.process.ProcessTools;
 import jdk.test.lib.SA.SATestUtils;
@@ -98,6 +98,7 @@ public class JMapHProfLargeHeapTest {
 
             JDKToolLauncher jMapLauncher = JDKToolLauncher
                     .createUsingTestJDK("jhsdb");
+            jMapLauncher.addVMArgs(Utils.getTestJavaOpts());
             jMapLauncher.addToolArg("jmap");
             jMapLauncher.addToolArg("--binaryheap");
             jMapLauncher.addToolArg("--pid");
diff --git a/test/hotspot/jtreg/serviceability/sa/sadebugd/DebugdConnectTest.java b/test/hotspot/jtreg/serviceability/sa/sadebugd/DebugdConnectTest.java
index 4de2281f134..75d12e59e50 100644
--- a/test/hotspot/jtreg/serviceability/sa/sadebugd/DebugdConnectTest.java
+++ b/test/hotspot/jtreg/serviceability/sa/sadebugd/DebugdConnectTest.java
@@ -37,6 +37,7 @@ import java.io.IOException;
 
 import jdk.test.lib.JDKToolLauncher;
 import jdk.test.lib.SA.SATestUtils;
+import jdk.test.lib.Utils;
 import jdk.test.lib.apps.LingeredApp;
 import jdk.test.lib.process.OutputAnalyzer;
 
@@ -45,6 +46,7 @@ public class DebugdConnectTest {
 
     private static OutputAnalyzer runJHSDB(String command, String id) throws IOException, InterruptedException {
         JDKToolLauncher jhsdbLauncher = JDKToolLauncher.createUsingTestJDK("jhsdb");
+        jhsdbLauncher.addVMArgs(Utils.getFilteredTestJavaOpts("-Xcomp"));
         jhsdbLauncher.addToolArg(command);
         jhsdbLauncher.addToolArg("--connect");
         if (id != null) {
@@ -68,7 +70,7 @@ public class DebugdConnectTest {
         OutputAnalyzer out = runJHSDB("jstack", id);
 
         out.shouldContain("LingeredApp");
-        out.stderrShouldBeEmpty();
+        out.stderrShouldBeEmptyIgnoreVMWarnings();
         out.shouldHaveExitValue(0);
     }
 
@@ -76,7 +78,7 @@ public class DebugdConnectTest {
         OutputAnalyzer out = runJHSDB("jmap", id);
 
         out.shouldContain("JVM version is");
-        out.stderrShouldBeEmpty();
+        out.stderrShouldBeEmptyIgnoreVMWarnings();
         out.shouldHaveExitValue(0);
     }
 
@@ -84,7 +86,7 @@ public class DebugdConnectTest {
         OutputAnalyzer out = runJHSDB("jinfo", id);
 
         out.shouldContain("Java System Properties:");
-        out.stderrShouldBeEmpty();
+        out.stderrShouldBeEmptyIgnoreVMWarnings();
         out.shouldHaveExitValue(0);
     }
 
@@ -92,7 +94,7 @@ public class DebugdConnectTest {
         OutputAnalyzer out = runJHSDB("jsnap", id);
 
         out.shouldContain("java.vm.name=");
-        out.stderrShouldBeEmpty();
+        out.stderrShouldBeEmptyIgnoreVMWarnings();
         out.shouldHaveExitValue(0);
     }
 
@@ -128,5 +130,4 @@ public class DebugdConnectTest {
         }
 
     }
-
 }
diff --git a/test/hotspot/jtreg/serviceability/sa/sadebugd/DebugdUtils.java b/test/hotspot/jtreg/serviceability/sa/sadebugd/DebugdUtils.java
index 39bcf023843..7c6c4d8c749 100644
--- a/test/hotspot/jtreg/serviceability/sa/sadebugd/DebugdUtils.java
+++ b/test/hotspot/jtreg/serviceability/sa/sadebugd/DebugdUtils.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,6 +26,7 @@ import java.io.InputStreamReader;
 import java.io.IOException;
 
 import jdk.test.lib.JDKToolLauncher;
+import jdk.test.lib.Utils;
 
 
 public class DebugdUtils {
@@ -43,6 +44,7 @@ public class DebugdUtils {
 
     public void attach(long pid) throws IOException {
         JDKToolLauncher jhsdbLauncher = JDKToolLauncher.createUsingTestJDK("jhsdb");
+        jhsdbLauncher.addVMArgs(Utils.getTestJavaOpts());
         jhsdbLauncher.addToolArg("debugd");
         jhsdbLauncher.addToolArg("--pid");
         jhsdbLauncher.addToolArg(Long.toString(pid));
diff --git a/test/hotspot/jtreg/serviceability/sa/sadebugd/SADebugDTest.java b/test/hotspot/jtreg/serviceability/sa/sadebugd/SADebugDTest.java
index 89117c690c3..eb488c957d2 100644
--- a/test/hotspot/jtreg/serviceability/sa/sadebugd/SADebugDTest.java
+++ b/test/hotspot/jtreg/serviceability/sa/sadebugd/SADebugDTest.java
@@ -94,6 +94,7 @@ public class SADebugDTest {
                 testResult = false;
                 portInUse = false;
                 JDKToolLauncher jhsdbLauncher = JDKToolLauncher.createUsingTestJDK("jhsdb");
+                jhsdbLauncher.addVMArgs(Utils.getFilteredTestJavaOpts("-Xcomp"));
                 jhsdbLauncher.addToolArg("debugd");
                 jhsdbLauncher.addToolArg("--pid");
                 jhsdbLauncher.addToolArg(Long.toString(app.getPid()));
diff --git a/test/hotspot/jtreg/serviceability/tmtools/jstack/JstackThreadTest.java b/test/hotspot/jtreg/serviceability/tmtools/jstack/JstackThreadTest.java
index 2de069b1b21..e09dfd45dad 100644
--- a/test/hotspot/jtreg/serviceability/tmtools/jstack/JstackThreadTest.java
+++ b/test/hotspot/jtreg/serviceability/tmtools/jstack/JstackThreadTest.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
@@ -69,6 +69,7 @@ public class JstackThreadTest {
     thread.start();
     ProcessBuilder processBuilder = new ProcessBuilder();
     JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jstack");
+    launcher.addVMArgs(jdk.test.lib.Utils.getTestJavaOpts());
     launcher.addToolArg("-l");
     launcher.addToolArg(Long.toString(ProcessTools.getProcessId()));
     processBuilder.command(launcher.getCommand());
diff --git a/test/jdk/sun/tools/jcmd/JcmdBase.java b/test/jdk/sun/tools/jcmd/JcmdBase.java
index 2e4c8eaa1eb..b0315673133 100644
--- a/test/jdk/sun/tools/jcmd/JcmdBase.java
+++ b/test/jdk/sun/tools/jcmd/JcmdBase.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
@@ -23,6 +23,7 @@
 
 import java.util.Arrays;
 
+import jdk.test.lib.Utils;
 import jdk.test.lib.process.OutputAnalyzer;
 import jdk.test.lib.process.ProcessTools;
 import jdk.test.lib.JDKToolLauncher;
@@ -95,6 +96,7 @@ public final class JcmdBase {
     private static final OutputAnalyzer jcmd(boolean requestToCurrentProcess,
             String[] vmArgs, String[] jcmdArgs) throws Exception {
         JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jcmd");
+        launcher.addVMArgs(Utils.getTestJavaOpts());
         if (vmArgs != null) {
             for (String vmArg : vmArgs) {
                 launcher.addVMArg(vmArg);
diff --git a/test/jdk/sun/tools/jcmd/JcmdOutputEncodingTest.java b/test/jdk/sun/tools/jcmd/JcmdOutputEncodingTest.java
index e5c267d11ea..45ba91f2f7e 100644
--- a/test/jdk/sun/tools/jcmd/JcmdOutputEncodingTest.java
+++ b/test/jdk/sun/tools/jcmd/JcmdOutputEncodingTest.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,6 +25,7 @@ import java.util.Arrays;
 import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
 
+import jdk.test.lib.Utils;
 import jdk.test.lib.process.OutputAnalyzer;
 import jdk.test.lib.process.ProcessTools;
 import jdk.test.lib.JDKToolLauncher;
@@ -48,6 +49,7 @@ public class JcmdOutputEncodingTest {
         Thread.currentThread().setName(marker);
 
         JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jcmd");
+        launcher.addVMArgs(Utils.getTestJavaOpts());
         launcher.addVMArg("-Dfile.encoding=" + cs);
         launcher.addToolArg(Long.toString(ProcessTools.getProcessId()));
         launcher.addToolArg("Thread.print");
diff --git a/test/jdk/sun/tools/jcmd/TestJcmdDefaults.java b/test/jdk/sun/tools/jcmd/TestJcmdDefaults.java
index 6e57ddeac34..b0f369b55e3 100644
--- a/test/jdk/sun/tools/jcmd/TestJcmdDefaults.java
+++ b/test/jdk/sun/tools/jcmd/TestJcmdDefaults.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2018, 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
@@ -90,7 +90,7 @@ public class TestJcmdDefaults {
      * @param output The generated output from the jcmd.
      */
     private static void matchListedProcesses(OutputAnalyzer output) {
-        output.shouldMatchByLine(JCMD_LIST_REGEX);
+        output.shouldMatchByLineIgnoreVMWarnings(JCMD_LIST_REGEX);
     }
 
     private static void verifyOutputAgainstFile(OutputAnalyzer output) throws IOException {
diff --git a/test/jdk/sun/tools/jcmd/TestJcmdSanity.java b/test/jdk/sun/tools/jcmd/TestJcmdSanity.java
index d3806fbfd2b..6e2343ee08a 100644
--- a/test/jdk/sun/tools/jcmd/TestJcmdSanity.java
+++ b/test/jdk/sun/tools/jcmd/TestJcmdSanity.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2018, 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
@@ -152,7 +152,7 @@ public class TestJcmdSanity {
      * @throws Exception
      */
     private static void matchPerfCounters(OutputAnalyzer output) {
-        output.shouldMatchByLineFrom(PERF_COUNTER_REGEX,
+        output.shouldMatchByLineIgnoreVMWarnings(PERF_COUNTER_REGEX, null,
                 PERF_COUNTER_REGEX);
     }
 
diff --git a/test/jdk/sun/tools/jhsdb/BasicLauncherTest.java b/test/jdk/sun/tools/jhsdb/BasicLauncherTest.java
index 06a239735d1..401dfe6ca31 100644
--- a/test/jdk/sun/tools/jhsdb/BasicLauncherTest.java
+++ b/test/jdk/sun/tools/jhsdb/BasicLauncherTest.java
@@ -63,7 +63,7 @@ public class BasicLauncherTest {
         else {
             launcher = JDKToolLauncher.createUsingTestJDK("jhsdb");
         }
-
+        launcher.addVMArgs(Utils.getFilteredTestJavaOpts("-Xcomp"));
         return launcher;
     }
 
diff --git a/test/jdk/sun/tools/jhsdb/HeapDumpTest.java b/test/jdk/sun/tools/jhsdb/HeapDumpTest.java
index 3222685f14f..69b46b684a3 100644
--- a/test/jdk/sun/tools/jhsdb/HeapDumpTest.java
+++ b/test/jdk/sun/tools/jhsdb/HeapDumpTest.java
@@ -38,6 +38,7 @@ import java.io.File;
 import java.util.List;
 import java.util.Arrays;
 
+import jdk.test.lib.Utils;
 import jdk.test.lib.apps.LingeredApp;
 import jdk.test.lib.hprof.parser.HprofReader;
 import jdk.test.lib.JDKToolLauncher;
@@ -65,6 +66,7 @@ public class HeapDumpTest {
             System.out.println(theApp.\u00CB);
             System.out.println("Starting " + toolArgs.get(0) + " against " + theApp.getPid());
             JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jhsdb");
+            launcher.addVMArgs(Utils.getFilteredTestJavaOpts("-Xcomp"));
 
             for (String cmd : toolArgs) {
                 launcher.addToolArg(cmd);
diff --git a/test/jdk/sun/tools/jhsdb/JShellHeapDumpTest.java b/test/jdk/sun/tools/jhsdb/JShellHeapDumpTest.java
index 78cb35be400..6c16ec2d293 100644
--- a/test/jdk/sun/tools/jhsdb/JShellHeapDumpTest.java
+++ b/test/jdk/sun/tools/jhsdb/JShellHeapDumpTest.java
@@ -38,6 +38,7 @@ import java.util.List;
 import java.util.Arrays;
 import java.util.Map;
 
+import jdk.test.lib.Utils;
 import jdk.test.lib.hprof.parser.HprofReader;
 import jdk.test.lib.JDKToolLauncher;
 import jdk.test.lib.JDKToolFinder;
@@ -61,6 +62,7 @@ public class JShellHeapDumpTest {
 
             System.out.println("Starting " + toolArgs.get(0) + " against " + jShellPID);
             JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jhsdb");
+            launcher.addVMArgs(Utils.getFilteredTestJavaOpts("-Xcomp"));
 
             for (String cmd : toolArgs) {
                 launcher.addToolArg(cmd);
diff --git a/test/jdk/sun/tools/jinfo/BasicJInfoTest.java b/test/jdk/sun/tools/jinfo/BasicJInfoTest.java
index b1ddf8b8f6b..ae1124982c2 100644
--- a/test/jdk/sun/tools/jinfo/BasicJInfoTest.java
+++ b/test/jdk/sun/tools/jinfo/BasicJInfoTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2018, 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
@@ -24,6 +24,7 @@
 import java.util.Arrays;
 
 import jdk.test.lib.JDKToolLauncher;
+import jdk.test.lib.Utils;
 import jdk.test.lib.process.OutputAnalyzer;
 import jdk.test.lib.process.ProcessTools;
 
@@ -70,6 +71,7 @@ public class BasicJInfoTest {
 
     private static OutputAnalyzer jinfo(String... toolArgs) throws Exception {
         JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jinfo");
+        launcher.addVMArgs(Utils.getTestJavaOpts());
         if (toolArgs != null) {
             for (String toolArg : toolArgs) {
                 launcher.addToolArg(toolArg);
diff --git a/test/jdk/sun/tools/jinfo/JInfoTest.java b/test/jdk/sun/tools/jinfo/JInfoTest.java
index 0534843cdb9..bea0e4b796c 100644
--- a/test/jdk/sun/tools/jinfo/JInfoTest.java
+++ b/test/jdk/sun/tools/jinfo/JInfoTest.java
@@ -29,6 +29,7 @@ import java.util.regex.Pattern;
 import java.io.IOException;
 
 import jdk.test.lib.JDKToolLauncher;
+import jdk.test.lib.Utils;
 import jdk.test.lib.process.OutputAnalyzer;
 import jdk.test.lib.process.ProcessTools;
 import jdk.test.lib.apps.LingeredApp;
@@ -114,6 +115,7 @@ public class JInfoTest {
 
     private static OutputAnalyzer jinfo(String... toolArgs) throws Exception {
         JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jinfo");
+        launcher.addVMArgs(Utils.getTestJavaOpts());
         if (toolArgs != null) {
             for (String toolArg : toolArgs) {
                 launcher.addToolArg(toolArg);
diff --git a/test/jdk/sun/tools/jmap/BasicJMapTest.java b/test/jdk/sun/tools/jmap/BasicJMapTest.java
index 88d95164087..a4c240a6bf6 100644
--- a/test/jdk/sun/tools/jmap/BasicJMapTest.java
+++ b/test/jdk/sun/tools/jmap/BasicJMapTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2019, 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
@@ -28,6 +28,7 @@ import java.io.File;
 import java.util.Arrays;
 
 import jdk.test.lib.JDKToolLauncher;
+import jdk.test.lib.Utils;
 import jdk.test.lib.hprof.HprofParser;
 import jdk.test.lib.process.OutputAnalyzer;
 import jdk.test.lib.process.ProcessTools;
@@ -179,6 +180,7 @@ public class BasicJMapTest {
 
     private static OutputAnalyzer jmap(String... toolArgs) throws Exception {
         JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jmap");
+        launcher.addVMArgs(Utils.getTestJavaOpts());
         if (toolArgs != null) {
             for (String toolArg : toolArgs) {
                 launcher.addToolArg(toolArg);
diff --git a/test/jdk/sun/tools/jps/JpsHelper.java b/test/jdk/sun/tools/jps/JpsHelper.java
index a186c0d80b2..c70b3790182 100644
--- a/test/jdk/sun/tools/jps/JpsHelper.java
+++ b/test/jdk/sun/tools/jps/JpsHelper.java
@@ -152,6 +152,7 @@ public final class JpsHelper {
      */
     public static OutputAnalyzer jps(List vmArgs, List toolArgs) throws Exception {
         JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jps");
+        launcher.addVMArgs(Utils.getFilteredTestJavaOpts("-XX:+UsePerfData"));
         launcher.addVMArg("-XX:+UsePerfData");
         if (vmArgs != null) {
             for (String vmArg : vmArgs) {
diff --git a/test/jdk/sun/tools/jstack/BasicJStackTest.java b/test/jdk/sun/tools/jstack/BasicJStackTest.java
index aeadedcfa54..23559f85700 100644
--- a/test/jdk/sun/tools/jstack/BasicJStackTest.java
+++ b/test/jdk/sun/tools/jstack/BasicJStackTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2019, 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
@@ -25,6 +25,7 @@ import java.util.Arrays;
 import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
 
+import jdk.test.lib.Utils;
 import jdk.test.lib.process.OutputAnalyzer;
 import jdk.test.lib.process.ProcessTools;
 import jdk.test.lib.JDKToolLauncher;
@@ -70,6 +71,7 @@ public class BasicJStackTest {
         Charset cs = StandardCharsets.UTF_8;
         Thread.currentThread().setName(marker);
         JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jstack");
+        launcher.addVMArgs(Utils.getFilteredTestJavaOpts("-XX:+UsePerfData"));
         launcher.addVMArg("-XX:+UsePerfData");
         launcher.addVMArg("-Dfile.encoding=" + cs);
         if (toolArgs != null) {
diff --git a/test/jdk/sun/tools/jstack/DeadlockDetectionTest.java b/test/jdk/sun/tools/jstack/DeadlockDetectionTest.java
index 7761474bab3..80eda6fc091 100644
--- a/test/jdk/sun/tools/jstack/DeadlockDetectionTest.java
+++ b/test/jdk/sun/tools/jstack/DeadlockDetectionTest.java
@@ -50,6 +50,7 @@ public class DeadlockDetectionTest {
 
     private static OutputAnalyzer jstack(String... toolArgs) throws Exception {
         JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jstack");
+        launcher.addVMArgs(Utils.getFilteredTestJavaOpts("-XX:+UsePerfData"));
         launcher.addVMArg("-XX:+UsePerfData");
         if (toolArgs != null) {
             for (String toolArg : toolArgs) {
diff --git a/test/jdk/sun/tools/jstat/JStatInterval.java b/test/jdk/sun/tools/jstat/JStatInterval.java
index edd7a788752..c3ff9404745 100644
--- a/test/jdk/sun/tools/jstat/JStatInterval.java
+++ b/test/jdk/sun/tools/jstat/JStatInterval.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2018, 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
@@ -34,6 +34,7 @@
  */
 
 import jdk.test.lib.JDKToolLauncher;
+import jdk.test.lib.Utils;
 import jdk.test.lib.process.ProcessTools;
 
 import java.util.concurrent.TimeUnit;
@@ -87,6 +88,7 @@ public class JStatInterval {
 
         String pidStr = String.valueOf(app.pid());
         JDKToolLauncher l = JDKToolLauncher.createUsingTestJDK("jstat");
+        l.addVMArgs(Utils.getTestJavaOpts());
         l.addToolArg("-compiler");
         l.addToolArg(pidStr);
         l.addToolArg("100");
diff --git a/test/jdk/sun/tools/jstatd/JstatdTest.java b/test/jdk/sun/tools/jstatd/JstatdTest.java
index 2925a223098..56c86cbfa07 100644
--- a/test/jdk/sun/tools/jstatd/JstatdTest.java
+++ b/test/jdk/sun/tools/jstatd/JstatdTest.java
@@ -27,6 +27,7 @@ import java.rmi.RemoteException;
 import java.rmi.registry.LocateRegistry;
 import java.rmi.registry.Registry;
 import java.util.Arrays;
+import java.util.List;
 
 import static jdk.test.lib.Asserts.*;
 import jdk.test.lib.Utils;
@@ -127,6 +128,7 @@ public final class JstatdTest {
      */
     private OutputAnalyzer runJps() throws Exception {
         JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jps");
+        launcher.addVMArgs(Utils.getFilteredTestJavaOpts("-XX:+UsePerfData"));
         launcher.addVMArg("-XX:+UsePerfData");
         launcher.addToolArg(getDestination());
 
@@ -156,7 +158,7 @@ public final class JstatdTest {
         assertFalse(output.getOutput().isEmpty(), "Output should not be empty");
 
         boolean foundFirstLineWithPid = false;
-        String[] lines = output.getOutput().split(Utils.NEW_LINE);
+        List lines = output.asLinesWithoutVMWarnings();
         for (String line : lines) {
             if (!foundFirstLineWithPid) {
                 foundFirstLineWithPid = line.matches(JPS_OUTPUT_REGEX);
@@ -353,9 +355,7 @@ public final class JstatdTest {
 
         // Verify output from jstatd
         OutputAnalyzer output = jstatdThread.getOutput();
-        assertTrue(output.getOutput().isEmpty(),
-                "jstatd should get an empty output, got: "
-                + Utils.NEW_LINE + output.getOutput());
+        output.shouldBeEmptyIgnoreVMWarnings();
         assertNotEquals(output.getExitValue(), 0,
                 "jstatd process exited with unexpected exit code");
     }
diff --git a/test/jdk/sun/tools/jstatd/TestJstatdUsage.java b/test/jdk/sun/tools/jstatd/TestJstatdUsage.java
index d80fe952f45..345cf8357b7 100644
--- a/test/jdk/sun/tools/jstatd/TestJstatdUsage.java
+++ b/test/jdk/sun/tools/jstatd/TestJstatdUsage.java
@@ -22,6 +22,7 @@
  */
 
 import jdk.test.lib.JDKToolLauncher;
+import jdk.test.lib.Utils;
 import jdk.test.lib.process.OutputAnalyzer;
 import jdk.test.lib.process.ProcessTools;
 
@@ -42,6 +43,7 @@ public class TestJstatdUsage {
 
     private static void testUsage(String option) throws Exception {
         JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jstatd");
+        launcher.addVMArgs(Utils.getTestJavaOpts());
         launcher.addToolArg(option);
         ProcessBuilder processBuilder = new ProcessBuilder(launcher.getCommand());
         OutputAnalyzer output = ProcessTools.executeProcess(processBuilder);
diff --git a/test/lib/jdk/test/lib/JDKToolLauncher.java b/test/lib/jdk/test/lib/JDKToolLauncher.java
index 6c264700215..0dae2dabfaf 100644
--- a/test/lib/jdk/test/lib/JDKToolLauncher.java
+++ b/test/lib/jdk/test/lib/JDKToolLauncher.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, 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
@@ -25,6 +25,7 @@ package jdk.test.lib;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.stream.Stream;
 
 /**
  * A utility for constructing command lines for starting JDK tool processes.
@@ -102,6 +103,24 @@ public class JDKToolLauncher {
         return this;
     }
 
+    /**
+     * Adds arguments to the JVM running the tool.
+     *
+     * The JVM arguments are passed to the underlying JVM running the tool.
+     * Arguments will automatically be prepended with "-J".
+     *
+     * Any platform specific arguments required for running the tool are
+     * automatically added.
+     *
+     * @param args
+     *            The arguments to VM running the tool
+     * @return The JDKToolLauncher instance
+     */
+    public JDKToolLauncher addVMArgs(String[] args) {
+        Stream.of(args).forEach(vmArgs::add);
+        return this;
+    }
+
     /**
      * Adds an argument to the tool.
      *
diff --git a/test/lib/jdk/test/lib/process/OutputAnalyzer.java b/test/lib/jdk/test/lib/process/OutputAnalyzer.java
index a2af1a914d3..c8653ea9bb2 100644
--- a/test/lib/jdk/test/lib/process/OutputAnalyzer.java
+++ b/test/lib/jdk/test/lib/process/OutputAnalyzer.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
@@ -38,6 +38,15 @@ import java.util.regex.Pattern;
 
 public final class OutputAnalyzer {
 
+    private static final String JVM_WARNING_MSG = ".* VM warning:.*";
+    private static final String JAVA_VERSION_MSG = "^java version .*|^Java\\(TM\\).*|^Java HotSpot\\(TM\\).*|" +
+            "^openjdk version .*|^OpenJDK .*";
+    private static final String JAVA_WARNINGS_AND_VERSION = JVM_WARNING_MSG + "|" + JAVA_VERSION_MSG;
+    private static final Pattern JAVA_WARNINGS_AND_VERSION_PATTERN =
+            Pattern.compile(JAVA_WARNINGS_AND_VERSION.replaceAll("\\|", "\\\\R|") + "\\R",
+                    Pattern.MULTILINE);
+
+
     private final OutputBuffer buffer;
     /**
      * Create an OutputAnalyzer, a utility class for verifying output and exit
@@ -132,13 +141,13 @@ public final class OutputAnalyzer {
 
     /**
      * Verify that the stderr contents of output buffer is empty,
-     * after filtering out the Hotspot warning messages
+     * after filtering out the HotSpot warning and Java version messages.
      *
      * @throws RuntimeException
      *             If stderr was not empty
      */
     public OutputAnalyzer stderrShouldBeEmptyIgnoreVMWarnings() {
-        if (!getStderr().replaceAll(jvmwarningmsg + "\\R", "").isEmpty()) {
+        if (!JAVA_WARNINGS_AND_VERSION_PATTERN.matcher(getStderr()).replaceAll("").isEmpty()) {
             reportDiagnosticSummary();
             throw new RuntimeException("stderr was not empty");
         }
@@ -561,12 +570,15 @@ public final class OutputAnalyzer {
         return Arrays.asList(buffer.split("\\R"));
     }
 
-
-    private static final String jvmwarningmsg = ".* VM warning:.*";
+    private List asLinesWithoutVMWarnings(String buffer) {
+        return Arrays.stream(buffer.split("\\R"))
+                .filter(Pattern.compile(JAVA_WARNINGS_AND_VERSION).asPredicate().negate())
+                .collect(Collectors.toList());
+    }
 
     /**
      * Verifies that the stdout and stderr contents of output buffer are empty, after
-     * filtering out the HotSpot warning messages.
+     * filtering out the HotSpot warning and Java version messages.
      *
      * @throws RuntimeException If the stdout and stderr are not empty
      */
@@ -577,22 +589,19 @@ public final class OutputAnalyzer {
             reportDiagnosticSummary();
             throw new RuntimeException("stdout was not empty");
         }
-        if (!stderr.replaceAll(jvmwarningmsg + "\\R", "").isEmpty()) {
-            reportDiagnosticSummary();
-            throw new RuntimeException("stderr was not empty");
-        }
+        stderrShouldBeEmptyIgnoreVMWarnings();
         return this;
     }
 
     /**
      * Verify that the stderr contents of output buffer matches the pattern,
-     * after filtering out the Hotespot warning messages
+     * after filtering out the HotSpot warning and Java version messages.
      *
      * @param pattern
      * @throws RuntimeException If the pattern was not found
      */
     public OutputAnalyzer stderrShouldMatchIgnoreVMWarnings(String pattern) {
-        String stderr = getStderr().replaceAll(jvmwarningmsg + "\\R", "");
+        String stderr = JAVA_WARNINGS_AND_VERSION_PATTERN.matcher(getStderr()).replaceAll("");
         Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
         if (!matcher.find()) {
             reportDiagnosticSummary();
@@ -604,16 +613,28 @@ public final class OutputAnalyzer {
 
     /**
      * Returns the contents of the output buffer (stdout and stderr), without those
-     * JVM warning msgs, as list of strings. Output is split by newlines.
+     * JVM warning and Java version messages, as list of strings. Output is split
+     * by newlines.
      *
      * @return Contents of the output buffer as list of strings
      */
     public List asLinesWithoutVMWarnings() {
         return Arrays.stream(getOutput().split("\\R"))
-                     .filter(Pattern.compile(jvmwarningmsg).asPredicate().negate())
+                     .filter(Pattern.compile(JAVA_WARNINGS_AND_VERSION).asPredicate().negate())
                      .collect(Collectors.toList());
     }
 
+    /**
+     * Verify that the stdout and stderr contents of output buffer match the
+     * {@code pattern} line by line ignoring HotSpot warning and version messages.
+     *
+     * @param pattern
+     *            Matching pattern
+     */
+    public OutputAnalyzer shouldMatchByLineIgnoreVMWarnings(String pattern) {
+        return shouldMatchByLine(getOutput(), null, null, pattern, true);
+    }
+
     /**
      * @see #shouldMatchByLine(String, String, String)
      */
@@ -657,7 +678,25 @@ public final class OutputAnalyzer {
      *            Matching pattern
      */
     public OutputAnalyzer shouldMatchByLine(String from, String to, String pattern) {
-        return shouldMatchByLine(getOutput(), from, to, pattern);
+        return shouldMatchByLine(getOutput(), from, to, pattern, false);
+    }
+
+    /**
+     * Verify that the stdout and stderr contents of output buffer match the
+     * {@code pattern} line by line ignoring HotSpot warnings and version messages.
+     * The whole output could be matched or just a subset of it.
+     *
+     * @param from
+     *            The line (excluded) from where output will be matched.
+     *            Set {@code from} to null for matching from the first line.
+     * @param to
+     *            The line (excluded) until where output will be matched.
+     *            Set {@code to} to null for matching until the last line.
+     * @param pattern
+     *            Matching pattern
+     */
+    public OutputAnalyzer shouldMatchByLineIgnoreVMWarnings(String from, String to, String pattern) {
+        return shouldMatchByLine(getOutput(), from, to, pattern, true);
     }
 
     /**
@@ -675,11 +714,12 @@ public final class OutputAnalyzer {
      *            Matching pattern
      */
     public OutputAnalyzer stdoutShouldMatchByLine(String from, String to, String pattern) {
-        return shouldMatchByLine(getStdout(), from, to, pattern);
+        return shouldMatchByLine(getStdout(), from, to, pattern, false);
     }
 
-    private OutputAnalyzer shouldMatchByLine(String buffer, String from, String to, String pattern) {
-        List lines = asLines(buffer);
+    private OutputAnalyzer shouldMatchByLine(String buffer, String from, String to, String pattern,
+                                             boolean ignoreVMWarnings) {
+        List lines = ignoreVMWarnings ? asLinesWithoutVMWarnings() : asLines(buffer);
 
         int fromIndex = 0;
         if (from != null) {

From be6f74718e8721f16c41af1319aa12ceef7252f8 Mon Sep 17 00:00:00 2001
From: Magnus Ihse Bursie 
Date: Tue, 12 May 2020 19:48:50 +0200
Subject: [PATCH 028/143] 8244844: javac command line is not re-executable

Reviewed-by: erikj
---
 make/common/JavaCompilation.gmk | 22 +++++++++++++++-------
 1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/make/common/JavaCompilation.gmk b/make/common/JavaCompilation.gmk
index ade1b6bcdfa..d7ba9ec9b25 100644
--- a/make/common/JavaCompilation.gmk
+++ b/make/common/JavaCompilation.gmk
@@ -382,6 +382,8 @@ define SetupJavaCompilationBody
     $1_REWRITE_INTO_CLASSES:=$$(foreach i,$$($1_SRC),-e 's|$$i/||g') -e 's|/|.|g' -e 's|.java$$$$||g'
 
     $1_COMPILE_TARGET := $$($1_BIN)$$($1_MODULE_SUBDIR)/_the.$1_batch
+    $1_FILELIST := $$($1_BIN)$$($1_MODULE_SUBDIR)/_the.$1_batch.filelist
+
     $1_API_TARGET := $$($1_BIN)$$($1_MODULE_SUBDIR)/_the.$1_pubapi
 
     # Put headers in a temp dir to filter out those that actually
@@ -421,17 +423,23 @@ define SetupJavaCompilationBody
       $1_EXTRA_DEPS := $$(BUILDTOOLS_OUTPUTDIR)/depend/_the.COMPILE_DEPEND_batch
     endif
 
-    # Pass along all sources to javac using an @file.
-    $$($1_COMPILE_TARGET): $$($1_SRCS) $$($1_DEPENDS) $$($1_VARDEPS_FILE) \
-        $$($1_EXTRA_DEPS)
+    # Create a file with all sources, to pass to javac in an @file.
+    # $$($1_VARDEPS_FILE) is used as dependency to track changes in set of
+    # list of files.
+    $$($1_FILELIST): $$($1_SRCS) $$($1_VARDEPS_FILE)
+		$$(call MakeDir, $$(@D))
+		$$(call LogWarn, Compiling $$($1_SRCS) files for $1)
+		$$(eval $$(call ListPathsSafely, $1_SRCS, $$($1_FILELIST)))
+
+    # Do the actual compilation
+    $$($1_COMPILE_TARGET): $$($1_SRCS) $$($1_FILELIST) $$($1_DEPENDS) \
+        $$($1_VARDEPS_FILE) $$($1_EXTRA_DEPS)
 		$$(call MakeDir, $$(@D))
-		$$(eval $$(call ListPathsSafely,$1_SRCS, $$@.tmp))
-		$$(call LogWarn, Compiling $$(words $$($1_SRCS)) files for $1)
 		$$(call ExecuteWithLog, $$($1_BIN)$$($1_MODULE_SUBDIR)/_the.$$($1_SAFE_NAME)_batch, \
 		    $$($1_JAVAC_CMD) $$($1_FLAGS) \
 		        $$($1_API_DIGEST_FLAGS) \
-		        -d $$($1_BIN) $$($1_HEADERS_ARG) @$$@.tmp) && \
-		$(MV) $$@.tmp $$@
+		        -d $$($1_BIN) $$($1_HEADERS_ARG) @$$($1_FILELIST)) && \
+		$(TOUCH) $$@
 
     # Add all targets to main variable
     $1 := $$($1_ALL_COPY_TARGETS) $$($1_ALL_COPY_CLEAN_TARGETS) $$($1_COMPILE_TARGET) \

From 06d623421307a53c5103c39ffa1bb03625e4aabe Mon Sep 17 00:00:00 2001
From: Johannes Kuhn 
Date: Tue, 12 May 2020 11:20:34 -0700
Subject: [PATCH 029/143] 8244767: Potential non-terminated string in
 getEncodingInternal() on Windows

Reviewed-by: bpb, naoto
---
 src/java.base/windows/native/libjava/java_props_md.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/java.base/windows/native/libjava/java_props_md.c b/src/java.base/windows/native/libjava/java_props_md.c
index aad374a88ae..96599034c15 100644
--- a/src/java.base/windows/native/libjava/java_props_md.c
+++ b/src/java.base/windows/native/libjava/java_props_md.c
@@ -73,6 +73,7 @@ getEncodingInternal(LCID lcid)
                       LOCALE_IDEFAULTANSICODEPAGE,
                       ret+2, 14) == 0) {
         codepage = 1252;
+        strcpy(ret+2, "1252");
     } else {
         codepage = atoi(ret+2);
     }

From cdf8cc57060a7497e1f598b9533b91365904dd49 Mon Sep 17 00:00:00 2001
From: Brent Christian 
Date: Tue, 12 May 2020 14:19:21 -0700
Subject: [PATCH 030/143] 8244855: Remove unused "getParent" function from
 Windows jni_util_md.c

Reviewed-by: lancea, naoto
---
 src/java.base/windows/native/libjava/jni_util_md.c | 13 +------------
 1 file changed, 1 insertion(+), 12 deletions(-)

diff --git a/src/java.base/windows/native/libjava/jni_util_md.c b/src/java.base/windows/native/libjava/jni_util_md.c
index 5b48b64884e..9ed2d384aed 100644
--- a/src/java.base/windows/native/libjava/jni_util_md.c
+++ b/src/java.base/windows/native/libjava/jni_util_md.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 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,17 +31,6 @@
 #include "jni.h"
 #include "jni_util.h"
 
-static void getParent(const TCHAR *path, TCHAR *dest) {
-    char* lastSlash = max(strrchr(path, '\\'), strrchr(path, '/'));
-    if (lastSlash == NULL) {
-        *dest = 0;
-        return;
-    }
-    if (path != dest)
-        strcpy(dest, path);
-    *lastSlash = 0;
-}
-
 void* getProcessHandle() {
     return (void*)GetModuleHandle(NULL);
 }

From dc54da232dd74dcfe1ee38038e080e5f7be42eb9 Mon Sep 17 00:00:00 2001
From: Yong Zhou 
Date: Wed, 13 May 2020 07:25:47 +0800
Subject: [PATCH 031/143] 8244407: JVM crashes after transformation in C2
 IdealLoopTree::split_fall_in

Reviewed-by: thartmann, kvn
---
 src/hotspot/share/opto/loopnode.cpp           | 14 +++-
 .../loopopts/TestBeautifyLoops_2.java         | 81 +++++++++++++++++++
 2 files changed, 92 insertions(+), 3 deletions(-)
 create mode 100644 test/hotspot/jtreg/compiler/loopopts/TestBeautifyLoops_2.java

diff --git a/src/hotspot/share/opto/loopnode.cpp b/src/hotspot/share/opto/loopnode.cpp
index 1814624ac0f..8b3b355e7ce 100644
--- a/src/hotspot/share/opto/loopnode.cpp
+++ b/src/hotspot/share/opto/loopnode.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -2098,10 +2098,18 @@ bool IdealLoopTree::beautify_loops( PhaseIdealLoop *phase ) {
   // If I am a shared header (multiple backedges), peel off the many
   // backedges into a private merge point and use the merge point as
   // the one true backedge.
-  if (_head->req() > 3 && !_irreducible) {
+  if (_head->req() > 3) {
     // Merge the many backedges into a single backedge but leave
     // the hottest backedge as separate edge for the following peel.
-    merge_many_backedges( phase );
+    if (!_irreducible) {
+      merge_many_backedges( phase );
+    }
+
+    // When recursively beautify my children, split_fall_in can change
+    // loop tree structure when I am an irreducible loop. Then the head
+    // of my children has a req() not bigger than 3. Here we need to set
+    // result to true to catch that case in order to tell the caller to
+    // rebuild loop tree. See issue JDK-8244407 for details.
     result = true;
   }
 
diff --git a/test/hotspot/jtreg/compiler/loopopts/TestBeautifyLoops_2.java b/test/hotspot/jtreg/compiler/loopopts/TestBeautifyLoops_2.java
new file mode 100644
index 00000000000..c53f33ff2e2
--- /dev/null
+++ b/test/hotspot/jtreg/compiler/loopopts/TestBeautifyLoops_2.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2020, Huawei Technologies Co. Ltd. All rights reserved.
+ * 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 8244407
+ * @summary JVM crashes after transformation in C2 IdealLoopTree::split_fall_in
+ *
+ * @run main/othervm -Xcomp -XX:-BackgroundCompilation
+ *      -XX:CompileCommand=compileonly,compiler.loopopts.TestBeautifyLoops_2::testMethod
+ *      compiler.loopopts.TestBeautifyLoops_2
+ */
+
+package compiler.loopopts;
+
+public class TestBeautifyLoops_2 {
+
+    private class X {
+        public int x() {
+            return -1;
+        }
+    }
+
+    private int mI = 0;
+    private float mF = 0;
+    private boolean mZ = false;
+    private X mX = new X();
+    private long[] mArray = new long[331];
+
+    private void testMethod() {
+        double d = 0;
+
+        for (int i = 0; i < 331; i++) {
+            if (mZ) {
+                continue;
+            }
+
+            try {
+                for (int j = mArray.length - 1; j >= 0; j--) {
+                    for (int k = 0; k < 331; k++) {
+                        d += ((double) new Double(d));
+                        switch (267) {
+                            case 256:
+                            default: {
+                                mF += (mX.x());
+                                break;
+                            }
+                        }
+                    }
+                }
+            } catch (Exception ignore) {
+            }
+        }
+    }
+
+    public static void main(String[] args) {
+        TestBeautifyLoops_2 obj = new TestBeautifyLoops_2();
+        obj.testMethod();
+    }
+
+}

From e48410a46644fb1b8340fd96e684c6e16f41e0ec Mon Sep 17 00:00:00 2001
From: Alexey Semenyuk 
Date: Tue, 12 May 2020 19:34:59 -0400
Subject: [PATCH 032/143] 8244634: LoadLibraryW failed from tools/jpackage
 tests after JDK-8242302

Reviewed-by: herrick, almatvee
---
 .../share/native/applauncher/JvmLauncher.h    |  4 +
 .../native/applauncher/WinLauncher.cpp        | 81 ++++++++++++++++++-
 .../windows/native/common/WinSysInfo.cpp      | 10 +++
 .../windows/native/common/WinSysInfo.h        |  4 +-
 4 files changed, 96 insertions(+), 3 deletions(-)

diff --git a/src/jdk.incubator.jpackage/share/native/applauncher/JvmLauncher.h b/src/jdk.incubator.jpackage/share/native/applauncher/JvmLauncher.h
index 972feb8532b..cffc0bac95d 100644
--- a/src/jdk.incubator.jpackage/share/native/applauncher/JvmLauncher.h
+++ b/src/jdk.incubator.jpackage/share/native/applauncher/JvmLauncher.h
@@ -46,6 +46,10 @@ public:
         return *this;
     }
 
+    tstring getPath() const {
+        return jvmPath;
+    }
+
     void launch();
 
 private:
diff --git a/src/jdk.incubator.jpackage/windows/native/applauncher/WinLauncher.cpp b/src/jdk.incubator.jpackage/windows/native/applauncher/WinLauncher.cpp
index 8849e3951d8..6644900e754 100644
--- a/src/jdk.incubator.jpackage/windows/native/applauncher/WinLauncher.cpp
+++ b/src/jdk.incubator.jpackage/windows/native/applauncher/WinLauncher.cpp
@@ -28,10 +28,14 @@
 #include 
 
 #include "AppLauncher.h"
+#include "JvmLauncher.h"
 #include "Log.h"
+#include "Dll.h"
+#include "Toolbox.h"
 #include "FileUtils.h"
 #include "UniqueHandle.h"
 #include "ErrorHandling.h"
+#include "WinSysInfo.h"
 #include "WinErrorHandling.h"
 
 
@@ -41,6 +45,61 @@
 
 namespace {
 
+std::unique_ptr loadDllWithAlteredPATH(const tstring& dllFullPath) {
+    LOG_TRACE_FUNCTION();
+
+    const tstring vanillaPathEnvVariable = SysInfo::getEnvVariable(_T("PATH"));
+
+    tstring pathEnvVariable = vanillaPathEnvVariable
+            + _T(";")
+            + FileUtils::dirname(dllFullPath);
+
+    SysInfo::setEnvVariable(_T("PATH"), pathEnvVariable);
+
+    LOG_TRACE(tstrings::any() << "New value of PATH: " << pathEnvVariable);
+
+    // Schedule restore of PATH after attempt to load the given dll
+    const auto resetPATH = runAtEndOfScope([&vanillaPathEnvVariable]() -> void {
+        SysInfo::setEnvVariable(_T("PATH"), vanillaPathEnvVariable);
+    });
+
+    return std::unique_ptr(new Dll(dllFullPath));
+}
+
+std::unique_ptr loadDllWithAddDllDirectory(const tstring& dllFullPath) {
+    LOG_TRACE_FUNCTION();
+
+    const tstring dirPath = FileUtils::dirname(dllFullPath);
+
+    typedef DLL_DIRECTORY_COOKIE(WINAPI *AddDllDirectoryFunc)(PCWSTR);
+
+    DllFunction _AddDllDirectory(
+            Dll("kernel32.dll", Dll::System()), "AddDllDirectory");
+
+    AddDllDirectoryFunc func = _AddDllDirectory;
+    DLL_DIRECTORY_COOKIE res = func(dirPath.c_str());
+    if (!res) {
+        JP_THROW(SysError(tstrings::any()
+                << "AddDllDirectory(" << dirPath << ") failed", func));
+    }
+
+    LOG_TRACE(tstrings::any() << "AddDllDirectory(" << dirPath << "): OK");
+
+    // Important: use LOAD_LIBRARY_SEARCH_DEFAULT_DIRS flag,
+    // but not LOAD_LIBRARY_SEARCH_USER_DIRS!
+    HMODULE dllHandle = LoadLibraryEx(dllFullPath.c_str(), NULL,
+            LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
+
+    LOG_TRACE(tstrings::any() << "LoadLibraryEx(" << dllFullPath
+            << ", LOAD_LIBRARY_SEARCH_DEFAULT_DIRS): " << dllHandle);
+
+    const auto freeDll = runAtEndOfScope([&dllHandle]() -> void {
+        Dll::freeLibrary(dllHandle);
+    });
+
+    return std::unique_ptr(new Dll(dllFullPath));
+}
+
 void launchApp() {
     // [RT-31061] otherwise UI can be left in back of other windows.
     ::AllowSetForegroundWindow(ASFW_ANY);
@@ -48,13 +107,31 @@ void launchApp() {
     const tstring launcherPath = SysInfo::getProcessModulePath();
     const tstring appImageRoot = FileUtils::dirname(launcherPath);
 
-    AppLauncher()
+    std::unique_ptr jvm(AppLauncher()
         .setImageRoot(appImageRoot)
         .addJvmLibName(_T("bin\\jli.dll"))
         .setAppDir(FileUtils::mkpath() << appImageRoot << _T("app"))
         .setDefaultRuntimePath(FileUtils::mkpath() << appImageRoot
                 << _T("runtime"))
-        .launch();
+        .createJvmLauncher());
+
+    std::unique_ptr jvmDll;
+    try {
+        // Try load JVM DLL.
+        jvmDll = std::unique_ptr(new Dll(jvm->getPath()));
+    } catch (const std::exception&) {
+        // JVM DLL load failed, though it exists in file system.
+        try {
+            // Try adjust the DLL search paths with AddDllDirectory() WINAPI CALL
+            jvmDll = loadDllWithAddDllDirectory(jvm->getPath());
+        } catch (const std::exception&) {
+            // AddDllDirectory() didn't work. Try altering PATH environment
+            // variable as the last resort.
+            jvmDll = loadDllWithAlteredPATH(jvm->getPath());
+        }
+    }
+
+    jvm->launch();
 }
 
 } // namespace
diff --git a/src/jdk.incubator.jpackage/windows/native/common/WinSysInfo.cpp b/src/jdk.incubator.jpackage/windows/native/common/WinSysInfo.cpp
index 5ae98f8cee6..b09454e5262 100644
--- a/src/jdk.incubator.jpackage/windows/native/common/WinSysInfo.cpp
+++ b/src/jdk.incubator.jpackage/windows/native/common/WinSysInfo.cpp
@@ -114,6 +114,16 @@ HMODULE getCurrentModuleHandle()
     return hmodule;
 }
 
+void setEnvVariable(const tstring& name, const tstring& value)
+{
+    if (!SetEnvironmentVariable(name.c_str(), value.c_str())) {
+        JP_THROW(SysError(tstrings::any()
+                << "SetEnvironmentVariable("
+                << name << ", " << value
+                << ") failed", SetEnvironmentVariable));
+    }
+}
+
 tstring getCurrentModulePath()
 {
     return getModulePath(getCurrentModuleHandle());
diff --git a/src/jdk.incubator.jpackage/windows/native/common/WinSysInfo.h b/src/jdk.incubator.jpackage/windows/native/common/WinSysInfo.h
index 6cba0d173f6..dbe147405c5 100644
--- a/src/jdk.incubator.jpackage/windows/native/common/WinSysInfo.h
+++ b/src/jdk.incubator.jpackage/windows/native/common/WinSysInfo.h
@@ -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
@@ -43,6 +43,8 @@ namespace SysInfo {
     // Returns handle of the current module (exe or dll).
     // The function assumes this code is statically linked to the module.
     HMODULE getCurrentModuleHandle();
+
+    void setEnvVariable(const tstring& name, const tstring& value);
 }
 
 

From 820f7227b776658db13c108c29a79f38fb8a7ffa Mon Sep 17 00:00:00 2001
From: Nick Gasson 
Date: Wed, 29 Apr 2020 16:15:14 +0800
Subject: [PATCH 033/143] 8242188: [TESTBUG] error in jtreg test
 jdk/jfr/api/consumer/TestRecordedFrame.java on linux-aarch64

Reviewed-by: egahlin
---
 test/jdk/jdk/jfr/api/consumer/TestRecordedFrame.java | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/test/jdk/jdk/jfr/api/consumer/TestRecordedFrame.java b/test/jdk/jdk/jfr/api/consumer/TestRecordedFrame.java
index afb5be2246f..7eedf159d5e 100644
--- a/test/jdk/jdk/jfr/api/consumer/TestRecordedFrame.java
+++ b/test/jdk/jdk/jfr/api/consumer/TestRecordedFrame.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
@@ -50,10 +50,17 @@ import jdk.test.lib.jfr.SimpleEvent;
 public final class TestRecordedFrame {
 
     public static void main(String[] args) throws IOException {
-        System.out.println(); // Makes BCI for method larger than 0
+        doSomething(); // Makes BCI for method larger than 0
         test(); // Records the line number and BCI for the main method/frame
     }
 
+    static void doSomething() {
+        // Don't actually do anything: on platforms that do not support
+        // patching (AArch64) -Xcomp is very sensitive to class load
+        // order and calling other methods here might result in main()
+        // being deoptimized, failing the test below.
+    }
+
     static void test() throws IOException {
         try (Recording recording = new Recording()) {
             recording.start();

From 7345502884ba79a60b1ea43adc1db6b345ca2eaf Mon Sep 17 00:00:00 2001
From: Magnus Ihse Bursie 
Date: Wed, 13 May 2020 10:35:08 +0200
Subject: [PATCH 034/143] 8244928: Build log output too verbose after
 JDK-8244844

Reviewed-by: alanb
---
 make/common/JavaCompilation.gmk | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/make/common/JavaCompilation.gmk b/make/common/JavaCompilation.gmk
index d7ba9ec9b25..e0b1fb003d4 100644
--- a/make/common/JavaCompilation.gmk
+++ b/make/common/JavaCompilation.gmk
@@ -428,7 +428,7 @@ define SetupJavaCompilationBody
     # list of files.
     $$($1_FILELIST): $$($1_SRCS) $$($1_VARDEPS_FILE)
 		$$(call MakeDir, $$(@D))
-		$$(call LogWarn, Compiling $$($1_SRCS) files for $1)
+		$$(call LogWarn, Compiling $$(words $$($1_SRCS)) files for $1)
 		$$(eval $$(call ListPathsSafely, $1_SRCS, $$($1_FILELIST)))
 
     # Do the actual compilation

From 0dab1819933049e1a67d3e19d5a625763b0aa2f7 Mon Sep 17 00:00:00 2001
From: Thomas Schatzl 
Date: Wed, 13 May 2020 12:47:07 +0200
Subject: [PATCH 035/143] 8244714: G1 young gen sizer allows zero young gen
 with huge -XX:NewRatio

Reviewed-by: sjohanss
---
 src/hotspot/share/gc/g1/g1YoungGenSizer.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/hotspot/share/gc/g1/g1YoungGenSizer.cpp b/src/hotspot/share/gc/g1/g1YoungGenSizer.cpp
index 5c0428f29ec..7dea6238b6d 100644
--- a/src/hotspot/share/gc/g1/g1YoungGenSizer.cpp
+++ b/src/hotspot/share/gc/g1/g1YoungGenSizer.cpp
@@ -102,7 +102,7 @@ void G1YoungGenSizer::recalculate_min_max_young_length(uint number_of_heap_regio
       // Do nothing. Values set on the command line, don't update them at runtime.
       break;
     case SizerNewRatio:
-      *min_young_length = number_of_heap_regions / (NewRatio + 1);
+      *min_young_length = MAX2((uint)(number_of_heap_regions / (NewRatio + 1)), 1u);
       *max_young_length = *min_young_length;
       break;
     default:

From 9651edd24797630f05b35df715b202fed6ab9c30 Mon Sep 17 00:00:00 2001
From: Thomas Schatzl 
Date: Wed, 13 May 2020 12:47:49 +0200
Subject: [PATCH 036/143] 8244815: Always log MMU information in G1

Reviewed-by: sjohanss, kbarrett
---
 src/hotspot/share/gc/g1/g1MMUTracker.cpp | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/src/hotspot/share/gc/g1/g1MMUTracker.cpp b/src/hotspot/share/gc/g1/g1MMUTracker.cpp
index 058e4c9574e..60d6c65db33 100644
--- a/src/hotspot/share/gc/g1/g1MMUTracker.cpp
+++ b/src/hotspot/share/gc/g1/g1MMUTracker.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
@@ -107,8 +107,12 @@ void G1MMUTrackerQueue::add_pause(double start, double end) {
   double slice_time = calculate_gc_time(end);
   G1MMUTracer::report_mmu(_time_slice, slice_time, _max_gc_time);
 
-  if (slice_time >= _max_gc_time) {
-    log_info(gc, mmu)("MMU target violated: %.1lfms (%.1lfms/%.1lfms)", slice_time * 1000.0, _max_gc_time * 1000.0, _time_slice * 1000);
+  if (slice_time < _max_gc_time) {
+    log_debug(gc, mmu)("MMU: %.1lfms (%.1lfms/%.1lfms)",
+                       slice_time * 1000.0, _max_gc_time * 1000.0, _time_slice * 1000);
+  } else {
+    log_info(gc, mmu)("MMU target violated: %.1lfms (%.1lfms/%.1lfms)",
+                      slice_time * 1000.0, _max_gc_time * 1000.0, _time_slice * 1000);
   }
 }
 

From 382e5dc334502d9147977d50a210ed503ca9fe3e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Erik=20=C3=96sterlund?= 
Date: Wed, 13 May 2020 09:36:12 +0000
Subject: [PATCH 037/143] 8241825: Make compressed oops and compressed class
 pointers independent (x86_64, PPC, S390)

Reviewed-by: coleenp, fparain, stuefe, mdoerr
---
 .../cpu/aarch64/globalDefinitions_aarch64.hpp |   2 +
 src/hotspot/cpu/ppc/globalDefinitions_ppc.hpp |   2 +
 .../cpu/s390/globalDefinitions_s390.hpp       |   2 +
 .../cpu/sparc/globalDefinitions_sparc.hpp     |   2 +
 src/hotspot/cpu/x86/c1_FrameMap_x86.hpp       |   2 +-
 src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp   |  44 +++---
 src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp |   9 +-
 src/hotspot/cpu/x86/c1_Runtime1_x86.cpp       |   3 +-
 src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp |   3 +-
 src/hotspot/cpu/x86/globalDefinitions_x86.hpp |   6 +
 src/hotspot/cpu/x86/interp_masm_x86.cpp       |   6 +-
 src/hotspot/cpu/x86/macroAssembler_x86.cpp    | 111 +++++++-------
 src/hotspot/cpu/x86/macroAssembler_x86.hpp    |  20 ++-
 src/hotspot/cpu/x86/methodHandles_x86.cpp     |   8 +-
 src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp  |   2 +-
 src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp  |   6 +-
 src/hotspot/cpu/x86/stubGenerator_x86_64.cpp  |  19 ++-
 src/hotspot/cpu/x86/templateTable_x86.cpp     |  30 ++--
 src/hotspot/cpu/x86/vtableStubs_x86_32.cpp    |   4 +-
 src/hotspot/cpu/x86/vtableStubs_x86_64.cpp    |   7 +-
 src/hotspot/cpu/x86/x86_64.ad                 |  50 +++----
 .../share/classfile/fieldLayoutBuilder.cpp    |  79 +---------
 .../share/classfile/fieldLayoutBuilder.hpp    |   2 -
 src/hotspot/share/classfile/javaClasses.cpp   |  18 +--
 src/hotspot/share/gc/z/zArguments.cpp         |   3 +-
 src/hotspot/share/memory/metaspace.cpp        |   7 +-
 src/hotspot/share/oops/instanceOop.hpp        |  16 ++-
 src/hotspot/share/opto/lcm.cpp                |   4 +-
 src/hotspot/share/runtime/arguments.cpp       |  27 ++--
 .../gc/metaspace/TestSizeTransitions.java     |  24 ++--
 .../CompressedClassPointers.java              | 136 +++++++++++++++++-
 .../CompressedClassSpaceSize.java             |   8 --
 .../appcds/TestCombinedCompressedFlags.java   |   8 +-
 .../runtime/cds/appcds/TestZGCWithCDS.java    |  36 ++++-
 ...CountAfterGCEventWithG1ConcurrentMark.java |   2 +-
 ...CountAfterGCEventWithG1FullCollection.java |   2 +-
 ...bjectCountAfterGCEventWithParallelOld.java |   2 +-
 ...TestObjectCountAfterGCEventWithSerial.java |   2 +-
 .../gc/objectcount/TestObjectCountEvent.java  |   2 +-
 39 files changed, 407 insertions(+), 309 deletions(-)

diff --git a/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp b/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp
index 8b0e99c5a02..9a1c547b3b5 100644
--- a/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp
+++ b/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp
@@ -58,4 +58,6 @@ const bool CCallingConventionRequiresIntsAsLongs = false;
 
 #define PREFERRED_METASPACE_ALIGNMENT
 
+#define COMPRESSED_CLASS_POINTERS_DEPENDS_ON_COMPRESSED_OOPS true
+
 #endif // CPU_AARCH64_GLOBALDEFINITIONS_AARCH64_HPP
diff --git a/src/hotspot/cpu/ppc/globalDefinitions_ppc.hpp b/src/hotspot/cpu/ppc/globalDefinitions_ppc.hpp
index f6904ecb3d5..7db26a318e9 100644
--- a/src/hotspot/cpu/ppc/globalDefinitions_ppc.hpp
+++ b/src/hotspot/cpu/ppc/globalDefinitions_ppc.hpp
@@ -69,4 +69,6 @@ const bool CCallingConventionRequiresIntsAsLongs = true;
 // Define the condition to use this -XX flag.
 #define USE_POLL_BIT_ONLY UseSIGTRAP
 
+#define COMPRESSED_CLASS_POINTERS_DEPENDS_ON_COMPRESSED_OOPS false
+
 #endif // CPU_PPC_GLOBALDEFINITIONS_PPC_HPP
diff --git a/src/hotspot/cpu/s390/globalDefinitions_s390.hpp b/src/hotspot/cpu/s390/globalDefinitions_s390.hpp
index d496fff1cdb..d184b8f7a22 100644
--- a/src/hotspot/cpu/s390/globalDefinitions_s390.hpp
+++ b/src/hotspot/cpu/s390/globalDefinitions_s390.hpp
@@ -56,4 +56,6 @@ const bool CCallingConventionRequiresIntsAsLongs = true;
 
 #define SUPPORT_RESERVED_STACK_AREA
 
+#define COMPRESSED_CLASS_POINTERS_DEPENDS_ON_COMPRESSED_OOPS false
+
 #endif // CPU_S390_GLOBALDEFINITIONS_S390_HPP
diff --git a/src/hotspot/cpu/sparc/globalDefinitions_sparc.hpp b/src/hotspot/cpu/sparc/globalDefinitions_sparc.hpp
index e764c5cfe36..0bbdfe264ed 100644
--- a/src/hotspot/cpu/sparc/globalDefinitions_sparc.hpp
+++ b/src/hotspot/cpu/sparc/globalDefinitions_sparc.hpp
@@ -56,4 +56,6 @@ const bool CCallingConventionRequiresIntsAsLongs = true;
 #define SUPPORT_RESERVED_STACK_AREA
 #endif
 
+#define COMPRESSED_CLASS_POINTERS_DEPENDS_ON_COMPRESSED_OOPS true
+
 #endif // CPU_SPARC_GLOBALDEFINITIONS_SPARC_HPP
diff --git a/src/hotspot/cpu/x86/c1_FrameMap_x86.hpp b/src/hotspot/cpu/x86/c1_FrameMap_x86.hpp
index b6091c494bd..a49e2f39a83 100644
--- a/src/hotspot/cpu/x86/c1_FrameMap_x86.hpp
+++ b/src/hotspot/cpu/x86/c1_FrameMap_x86.hpp
@@ -148,7 +148,7 @@
 
   static int adjust_reg_range(int range) {
     // Reduce the number of available regs (to free r12) in case of compressed oops
-    if (UseCompressedOops || UseCompressedClassPointers) return range - 1;
+    if (UseCompressedOops) return range - 1;
     return range;
   }
 
diff --git a/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp b/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp
index 032c74e2bee..8a0200a18dc 100644
--- a/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp
+++ b/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp
@@ -1185,6 +1185,7 @@ void LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_Patch
 
   LIR_Address* addr = src->as_address_ptr();
   Address from_addr = as_Address(addr);
+  Register tmp_load_klass = LP64_ONLY(rscratch1) NOT_LP64(noreg);
 
   if (addr->base()->type() == T_OBJECT) {
     __ verify_oop(addr->base()->as_pointer_register());
@@ -1370,7 +1371,7 @@ void LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_Patch
   } else if (type == T_ADDRESS && addr->disp() == oopDesc::klass_offset_in_bytes()) {
 #ifdef _LP64
     if (UseCompressedClassPointers) {
-      __ decode_klass_not_null(dest->as_register());
+      __ decode_klass_not_null(dest->as_register(), tmp_load_klass);
     }
 #endif
   }
@@ -1698,6 +1699,7 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L
   Register dst = op->result_opr()->as_register();
   ciKlass* k = op->klass();
   Register Rtmp1 = noreg;
+  Register tmp_load_klass = LP64_ONLY(rscratch1) NOT_LP64(noreg);
 
   // check if it needs to be profiled
   ciMethodData* md = NULL;
@@ -1761,7 +1763,7 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L
     // not a safepoint as obj null check happens earlier
 #ifdef _LP64
     if (UseCompressedClassPointers) {
-      __ load_klass(Rtmp1, obj);
+      __ load_klass(Rtmp1, obj, tmp_load_klass);
       __ cmpptr(k_RInfo, Rtmp1);
     } else {
       __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes()));
@@ -1778,7 +1780,7 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L
   } else {
     // get object class
     // not a safepoint as obj null check happens earlier
-    __ load_klass(klass_RInfo, obj);
+    __ load_klass(klass_RInfo, obj, tmp_load_klass);
     if (k->is_loaded()) {
       // See if we get an immediate positive hit
 #ifdef _LP64
@@ -1833,7 +1835,7 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L
     Register mdo  = klass_RInfo, recv = k_RInfo;
     __ bind(profile_cast_success);
     __ mov_metadata(mdo, md->constant_encoding());
-    __ load_klass(recv, obj);
+    __ load_klass(recv, obj, tmp_load_klass);
     type_profile_helper(mdo, md, data, recv, success);
     __ jmp(*success);
 
@@ -1848,6 +1850,7 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L
 
 
 void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) {
+  Register tmp_load_klass = LP64_ONLY(rscratch1) NOT_LP64(noreg);
   LIR_Code code = op->code();
   if (code == lir_store_check) {
     Register value = op->object()->as_register();
@@ -1893,8 +1896,8 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) {
     }
 
     add_debug_info_for_null_check_here(op->info_for_exception());
-    __ load_klass(k_RInfo, array);
-    __ load_klass(klass_RInfo, value);
+    __ load_klass(k_RInfo, array, tmp_load_klass);
+    __ load_klass(klass_RInfo, value, tmp_load_klass);
 
     // get instance klass (it's already uncompressed)
     __ movptr(k_RInfo, Address(k_RInfo, ObjArrayKlass::element_klass_offset()));
@@ -1915,7 +1918,7 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) {
       Register mdo  = klass_RInfo, recv = k_RInfo;
       __ bind(profile_cast_success);
       __ mov_metadata(mdo, md->constant_encoding());
-      __ load_klass(recv, value);
+      __ load_klass(recv, value, tmp_load_klass);
       type_profile_helper(mdo, md, data, recv, &done);
       __ jmpb(done);
 
@@ -3107,6 +3110,7 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
   Register dst_pos = op->dst_pos()->as_register();
   Register length  = op->length()->as_register();
   Register tmp = op->tmp()->as_register();
+  Register tmp_load_klass = LP64_ONLY(rscratch1) NOT_LP64(noreg);
 
   __ resolve(ACCESS_READ, src);
   __ resolve(ACCESS_WRITE, dst);
@@ -3254,13 +3258,13 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
   // an instance type.
   if (flags & LIR_OpArrayCopy::type_check) {
     if (!(flags & LIR_OpArrayCopy::dst_objarray)) {
-      __ load_klass(tmp, dst);
+      __ load_klass(tmp, dst, tmp_load_klass);
       __ cmpl(Address(tmp, in_bytes(Klass::layout_helper_offset())), Klass::_lh_neutral_value);
       __ jcc(Assembler::greaterEqual, *stub->entry());
     }
 
     if (!(flags & LIR_OpArrayCopy::src_objarray)) {
-      __ load_klass(tmp, src);
+      __ load_klass(tmp, src, tmp_load_klass);
       __ cmpl(Address(tmp, in_bytes(Klass::layout_helper_offset())), Klass::_lh_neutral_value);
       __ jcc(Assembler::greaterEqual, *stub->entry());
     }
@@ -3317,8 +3321,8 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
       __ push(src);
       __ push(dst);
 
-      __ load_klass(src, src);
-      __ load_klass(dst, dst);
+      __ load_klass(src, src, tmp_load_klass);
+      __ load_klass(dst, dst, tmp_load_klass);
 
       __ check_klass_subtype_fast_path(src, dst, tmp, &cont, &slow, NULL);
 
@@ -3346,9 +3350,9 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
           assert(flags & mask, "one of the two should be known to be an object array");
 
           if (!(flags & LIR_OpArrayCopy::src_objarray)) {
-            __ load_klass(tmp, src);
+            __ load_klass(tmp, src, tmp_load_klass);
           } else if (!(flags & LIR_OpArrayCopy::dst_objarray)) {
-            __ load_klass(tmp, dst);
+            __ load_klass(tmp, dst, tmp_load_klass);
           }
           int lh_offset = in_bytes(Klass::layout_helper_offset());
           Address klass_lh_addr(tmp, lh_offset);
@@ -3392,14 +3396,14 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
 #ifdef _WIN64
         // Allocate abi space for args but be sure to keep stack aligned
         __ subptr(rsp, 6*wordSize);
-        __ load_klass(c_rarg3, dst);
+        __ load_klass(c_rarg3, dst, tmp_load_klass);
         __ movptr(c_rarg3, Address(c_rarg3, ObjArrayKlass::element_klass_offset()));
         store_parameter(c_rarg3, 4);
         __ movl(c_rarg3, Address(c_rarg3, Klass::super_check_offset_offset()));
         __ call(RuntimeAddress(copyfunc_addr));
         __ addptr(rsp, 6*wordSize);
 #else
-        __ load_klass(c_rarg4, dst);
+        __ load_klass(c_rarg4, dst, tmp_load_klass);
         __ movptr(c_rarg4, Address(c_rarg4, ObjArrayKlass::element_klass_offset()));
         __ movl(c_rarg3, Address(c_rarg4, Klass::super_check_offset_offset()));
         __ call(RuntimeAddress(copyfunc_addr));
@@ -3464,7 +3468,7 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
     __ mov_metadata(tmp, default_type->constant_encoding());
 #ifdef _LP64
     if (UseCompressedClassPointers) {
-      __ encode_klass_not_null(tmp);
+      __ encode_klass_not_null(tmp, rscratch1);
     }
 #endif
 
@@ -3569,6 +3573,7 @@ void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) {
   ciMethod* method = op->profiled_method();
   int bci          = op->profiled_bci();
   ciMethod* callee = op->profiled_callee();
+  Register tmp_load_klass = LP64_ONLY(rscratch1) NOT_LP64(noreg);
 
   // Update counter for all call types
   ciMethodData* md = method->method_data_or_null();
@@ -3621,7 +3626,7 @@ void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) {
         }
       }
     } else {
-      __ load_klass(recv, recv);
+      __ load_klass(recv, recv, tmp_load_klass);
       Label update_done;
       type_profile_helper(mdo, md, data, recv, &update_done);
       // Receiver did not match any saved receiver and there is no empty row for it.
@@ -3639,6 +3644,7 @@ void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) {
 void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
   Register obj = op->obj()->as_register();
   Register tmp = op->tmp()->as_pointer_register();
+  Register tmp_load_klass = LP64_ONLY(rscratch1) NOT_LP64(noreg);
   Address mdo_addr = as_Address(op->mdp()->as_address_ptr());
   ciKlass* exact_klass = op->exact_klass();
   intptr_t current_klass = op->current_klass();
@@ -3685,7 +3691,7 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
 #ifdef ASSERT
     if (exact_klass != NULL) {
       Label ok;
-      __ load_klass(tmp, tmp);
+      __ load_klass(tmp, tmp, tmp_load_klass);
       __ push(tmp);
       __ mov_metadata(tmp, exact_klass->constant_encoding());
       __ cmpptr(tmp, Address(rsp, 0));
@@ -3700,7 +3706,7 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
         if (exact_klass != NULL) {
           __ mov_metadata(tmp, exact_klass->constant_encoding());
         } else {
-          __ load_klass(tmp, tmp);
+          __ load_klass(tmp, tmp, tmp_load_klass);
         }
 
         __ xorptr(tmp, mdo_addr);
diff --git a/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp b/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp
index 5ab461b9e1a..6a3cd0878c6 100644
--- a/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp
+++ b/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp
@@ -53,7 +53,8 @@ int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr
 
   if (UseBiasedLocking) {
     assert(scratch != noreg, "should have scratch register at this point");
-    null_check_offset = biased_locking_enter(disp_hdr, obj, hdr, scratch, false, done, &slow_case);
+    Register rklass_decode_tmp = LP64_ONLY(rscratch1) NOT_LP64(noreg);
+    null_check_offset = biased_locking_enter(disp_hdr, obj, hdr, scratch, rklass_decode_tmp, false, done, &slow_case);
   } else {
     null_check_offset = offset();
   }
@@ -150,6 +151,7 @@ void C1_MacroAssembler::try_allocate(Register obj, Register var_size_in_bytes, i
 
 void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register len, Register t1, Register t2) {
   assert_different_registers(obj, klass, len);
+  Register tmp_encode_klass = LP64_ONLY(rscratch1) NOT_LP64(noreg);
   if (UseBiasedLocking && !len->is_valid()) {
     assert_different_registers(obj, klass, len, t1, t2);
     movptr(t1, Address(klass, Klass::prototype_header_offset()));
@@ -161,7 +163,7 @@ void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register
 #ifdef _LP64
   if (UseCompressedClassPointers) { // Take care not to kill klass
     movptr(t1, klass);
-    encode_klass_not_null(t1);
+    encode_klass_not_null(t1, tmp_encode_klass);
     movl(Address(obj, oopDesc::klass_offset_in_bytes()), t1);
   } else
 #endif
@@ -296,9 +298,10 @@ void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) {
   // check against inline cache
   assert(!MacroAssembler::needs_explicit_null_check(oopDesc::klass_offset_in_bytes()), "must add explicit null check");
   int start_offset = offset();
+  Register tmp_load_klass = LP64_ONLY(rscratch2) NOT_LP64(noreg);
 
   if (UseCompressedClassPointers) {
-    load_klass(rscratch1, receiver);
+    load_klass(rscratch1, receiver, tmp_load_klass);
     cmpptr(rscratch1, iCache);
   } else {
     cmpptr(iCache, Address(receiver, oopDesc::klass_offset_in_bytes()));
diff --git a/src/hotspot/cpu/x86/c1_Runtime1_x86.cpp b/src/hotspot/cpu/x86/c1_Runtime1_x86.cpp
index db9d306946f..53935539a36 100644
--- a/src/hotspot/cpu/x86/c1_Runtime1_x86.cpp
+++ b/src/hotspot/cpu/x86/c1_Runtime1_x86.cpp
@@ -1248,8 +1248,9 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
 
         // load the klass and check the has finalizer flag
         Label register_finalizer;
+        Register tmp_load_klass = LP64_ONLY(rscratch1) NOT_LP64(noreg);
         Register t = rsi;
-        __ load_klass(t, rax);
+        __ load_klass(t, rax, tmp_load_klass);
         __ movl(t, Address(t, Klass::access_flags_offset()));
         __ testl(t, JVM_ACC_HAS_FINALIZER);
         __ jcc(Assembler::notZero, register_finalizer);
diff --git a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp
index 08192635e22..a61435b7671 100644
--- a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp
+++ b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp
@@ -442,7 +442,6 @@ void C2_MacroAssembler::fast_lock(Register objReg, Register boxReg, Register tmp
   if (use_rtm) {
     assert_different_registers(objReg, boxReg, tmpReg, scrReg, cx1Reg, cx2Reg);
   } else {
-    assert(cx1Reg == noreg, "");
     assert(cx2Reg == noreg, "");
     assert_different_registers(objReg, boxReg, tmpReg, scrReg);
   }
@@ -478,7 +477,7 @@ void C2_MacroAssembler::fast_lock(Register objReg, Register boxReg, Register tmp
   // at [FETCH], below, will never observe a biased encoding (*101b).
   // If this invariant is not held we risk exclusion (safety) failure.
   if (UseBiasedLocking && !UseOptoBiasInlining) {
-    biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, counters);
+    biased_locking_enter(boxReg, objReg, tmpReg, scrReg, cx1Reg, false, DONE_LABEL, NULL, counters);
   }
 
 #if INCLUDE_RTM_OPT
diff --git a/src/hotspot/cpu/x86/globalDefinitions_x86.hpp b/src/hotspot/cpu/x86/globalDefinitions_x86.hpp
index 7a9c7578d65..63d0759feb2 100644
--- a/src/hotspot/cpu/x86/globalDefinitions_x86.hpp
+++ b/src/hotspot/cpu/x86/globalDefinitions_x86.hpp
@@ -69,4 +69,10 @@ const bool CCallingConventionRequiresIntsAsLongs = false;
 #define SUPPORT_RESERVED_STACK_AREA
 #endif
 
+#if INCLUDE_JVMCI
+#define COMPRESSED_CLASS_POINTERS_DEPENDS_ON_COMPRESSED_OOPS (EnableJVMCI || UseAOT)
+#else
+#define COMPRESSED_CLASS_POINTERS_DEPENDS_ON_COMPRESSED_OOPS false
+#endif
+
 #endif // CPU_X86_GLOBALDEFINITIONS_X86_HPP
diff --git a/src/hotspot/cpu/x86/interp_masm_x86.cpp b/src/hotspot/cpu/x86/interp_masm_x86.cpp
index 8c2d4e6c2a2..7af7527f5b3 100644
--- a/src/hotspot/cpu/x86/interp_masm_x86.cpp
+++ b/src/hotspot/cpu/x86/interp_masm_x86.cpp
@@ -59,7 +59,8 @@ void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& md
   jmpb(next);
 
   bind(update);
-  load_klass(obj, obj);
+  Register tmp_load_klass = LP64_ONLY(rscratch1) NOT_LP64(noreg);
+  load_klass(obj, obj, tmp_load_klass);
 
   xorptr(obj, mdo_addr);
   testptr(obj, TypeEntries::type_klass_mask);
@@ -1197,7 +1198,8 @@ void InterpreterMacroAssembler::lock_object(Register lock_reg) {
     movptr(obj_reg, Address(lock_reg, obj_offset));
 
     if (UseBiasedLocking) {
-      biased_locking_enter(lock_reg, obj_reg, swap_reg, tmp_reg, false, done, &slow_case);
+      Register rklass_decode_tmp = LP64_ONLY(rscratch1) NOT_LP64(noreg);
+      biased_locking_enter(lock_reg, obj_reg, swap_reg, tmp_reg, rklass_decode_tmp, false, done, &slow_case);
     }
 
     // Load immediate 1 into swap_reg %rax
diff --git a/src/hotspot/cpu/x86/macroAssembler_x86.cpp b/src/hotspot/cpu/x86/macroAssembler_x86.cpp
index 45355c2d54b..633b317fc77 100644
--- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp
@@ -1084,6 +1084,7 @@ int MacroAssembler::biased_locking_enter(Register lock_reg,
                                          Register obj_reg,
                                          Register swap_reg,
                                          Register tmp_reg,
+                                         Register tmp_reg2,
                                          bool swap_reg_contains_mark,
                                          Label& done,
                                          Label* slow_case,
@@ -1128,7 +1129,7 @@ int MacroAssembler::biased_locking_enter(Register lock_reg,
   if (swap_reg_contains_mark) {
     null_check_offset = offset();
   }
-  load_prototype_header(tmp_reg, obj_reg);
+  load_prototype_header(tmp_reg, obj_reg, tmp_reg2);
 #ifdef _LP64
   orptr(tmp_reg, r15_thread);
   xorptr(tmp_reg, swap_reg);
@@ -1214,7 +1215,7 @@ int MacroAssembler::biased_locking_enter(Register lock_reg,
   //
   // FIXME: due to a lack of registers we currently blow away the age
   // bits in this situation. Should attempt to preserve them.
-  load_prototype_header(tmp_reg, obj_reg);
+  load_prototype_header(tmp_reg, obj_reg, tmp_reg2);
 #ifdef _LP64
   orptr(tmp_reg, r15_thread);
 #else
@@ -1249,7 +1250,7 @@ int MacroAssembler::biased_locking_enter(Register lock_reg,
   // FIXME: due to a lack of registers we currently blow away the age
   // bits in this situation. Should attempt to preserve them.
   NOT_LP64( movptr(swap_reg, saved_mark_addr); )
-  load_prototype_header(tmp_reg, obj_reg);
+  load_prototype_header(tmp_reg, obj_reg, tmp_reg2);
   lock();
   cmpxchgptr(tmp_reg, mark_addr); // compare tmp_reg and swap_reg
   // Fall through to the normal CAS-based lock, because no matter what
@@ -1511,7 +1512,7 @@ void MacroAssembler::call_VM_base(Register oop_result,
 #ifdef ASSERT
   // TraceBytecodes does not use r12 but saves it over the call, so don't verify
   // r12 is the heapbase.
-  LP64_ONLY(if ((UseCompressedOops || UseCompressedClassPointers) && !TraceBytecodes) verify_heapbase("call_VM_base: heap base corrupted?");)
+  LP64_ONLY(if (UseCompressedOops && !TraceBytecodes) verify_heapbase("call_VM_base: heap base corrupted?");)
 #endif // ASSERT
 
   assert(java_thread != oop_result  , "cannot use the same register for java_thread & oop_result");
@@ -4323,25 +4324,29 @@ void MacroAssembler::load_method_holder(Register holder, Register method) {
   movptr(holder, Address(holder, ConstantPool::pool_holder_offset_in_bytes())); // InstanceKlass*
 }
 
-void MacroAssembler::load_klass(Register dst, Register src) {
+void MacroAssembler::load_klass(Register dst, Register src, Register tmp) {
+  assert_different_registers(src, tmp);
+  assert_different_registers(dst, tmp);
 #ifdef _LP64
   if (UseCompressedClassPointers) {
     movl(dst, Address(src, oopDesc::klass_offset_in_bytes()));
-    decode_klass_not_null(dst);
+    decode_klass_not_null(dst, tmp);
   } else
 #endif
     movptr(dst, Address(src, oopDesc::klass_offset_in_bytes()));
 }
 
-void MacroAssembler::load_prototype_header(Register dst, Register src) {
-  load_klass(dst, src);
+void MacroAssembler::load_prototype_header(Register dst, Register src, Register tmp) {
+  load_klass(dst, src, tmp);
   movptr(dst, Address(dst, Klass::prototype_header_offset()));
 }
 
-void MacroAssembler::store_klass(Register dst, Register src) {
+void MacroAssembler::store_klass(Register dst, Register src, Register tmp) {
+  assert_different_registers(src, tmp);
+  assert_different_registers(dst, tmp);
 #ifdef _LP64
   if (UseCompressedClassPointers) {
-    encode_klass_not_null(src);
+    encode_klass_not_null(src, tmp);
     movl(Address(dst, oopDesc::klass_offset_in_bytes()), src);
   } else
 #endif
@@ -4555,61 +4560,38 @@ void  MacroAssembler::decode_heap_oop_not_null(Register dst, Register src) {
   }
 }
 
-void MacroAssembler::encode_klass_not_null(Register r) {
+void MacroAssembler::encode_klass_not_null(Register r, Register tmp) {
+  assert_different_registers(r, tmp);
   if (CompressedKlassPointers::base() != NULL) {
-    // Use r12 as a scratch register in which to temporarily load the narrow_klass_base.
-    assert(r != r12_heapbase, "Encoding a klass in r12");
-    mov64(r12_heapbase, (int64_t)CompressedKlassPointers::base());
-    subq(r, r12_heapbase);
+    mov64(tmp, (int64_t)CompressedKlassPointers::base());
+    subq(r, tmp);
   }
   if (CompressedKlassPointers::shift() != 0) {
     assert (LogKlassAlignmentInBytes == CompressedKlassPointers::shift(), "decode alg wrong");
     shrq(r, LogKlassAlignmentInBytes);
   }
-  if (CompressedKlassPointers::base() != NULL) {
-    reinit_heapbase();
-  }
 }
 
-void MacroAssembler::encode_klass_not_null(Register dst, Register src) {
-  if (dst == src) {
-    encode_klass_not_null(src);
-  } else {
-    if (CompressedKlassPointers::base() != NULL) {
-      mov64(dst, (int64_t)CompressedKlassPointers::base());
-      negq(dst);
-      addq(dst, src);
-    } else {
-      movptr(dst, src);
-    }
-    if (CompressedKlassPointers::shift() != 0) {
-      assert (LogKlassAlignmentInBytes == CompressedKlassPointers::shift(), "decode alg wrong");
-      shrq(dst, LogKlassAlignmentInBytes);
-    }
-  }
-}
-
-// Function instr_size_for_decode_klass_not_null() counts the instructions
-// generated by decode_klass_not_null(register r) and reinit_heapbase(),
-// when (Universe::heap() != NULL).  Hence, if the instructions they
-// generate change, then this method needs to be updated.
-int MacroAssembler::instr_size_for_decode_klass_not_null() {
-  assert (UseCompressedClassPointers, "only for compressed klass ptrs");
+void MacroAssembler::encode_and_move_klass_not_null(Register dst, Register src) {
+  assert_different_registers(src, dst);
   if (CompressedKlassPointers::base() != NULL) {
-    // mov64 + addq + shlq? + mov64  (for reinit_heapbase()).
-    return (CompressedKlassPointers::shift() == 0 ? 20 : 24);
+    mov64(dst, -(int64_t)CompressedKlassPointers::base());
+    addq(dst, src);
   } else {
-    // longest load decode klass function, mov64, leaq
-    return 16;
+    movptr(dst, src);
+  }
+  if (CompressedKlassPointers::shift() != 0) {
+    assert (LogKlassAlignmentInBytes == CompressedKlassPointers::shift(), "decode alg wrong");
+    shrq(dst, LogKlassAlignmentInBytes);
   }
 }
 
 // !!! If the instructions that get generated here change then function
 // instr_size_for_decode_klass_not_null() needs to get updated.
-void  MacroAssembler::decode_klass_not_null(Register r) {
+void  MacroAssembler::decode_klass_not_null(Register r, Register tmp) {
+  assert_different_registers(r, tmp);
   // Note: it will change flags
-  assert (UseCompressedClassPointers, "should only be used for compressed headers");
-  assert(r != r12_heapbase, "Decoding a klass in r12");
+  assert(UseCompressedClassPointers, "should only be used for compressed headers");
   // Cannot assert, unverified entry point counts instructions (see .ad file)
   // vtableStubs also counts instructions in pd_code_size_limit.
   // Also do not verify_oop as this is called by verify_oop.
@@ -4617,24 +4599,31 @@ void  MacroAssembler::decode_klass_not_null(Register r) {
     assert(LogKlassAlignmentInBytes == CompressedKlassPointers::shift(), "decode alg wrong");
     shlq(r, LogKlassAlignmentInBytes);
   }
-  // Use r12 as a scratch register in which to temporarily load the narrow_klass_base.
   if (CompressedKlassPointers::base() != NULL) {
-    mov64(r12_heapbase, (int64_t)CompressedKlassPointers::base());
-    addq(r, r12_heapbase);
-    reinit_heapbase();
+    mov64(tmp, (int64_t)CompressedKlassPointers::base());
+    addq(r, tmp);
   }
 }
 
-void  MacroAssembler::decode_klass_not_null(Register dst, Register src) {
+void  MacroAssembler::decode_and_move_klass_not_null(Register dst, Register src) {
+  assert_different_registers(src, dst);
   // Note: it will change flags
   assert (UseCompressedClassPointers, "should only be used for compressed headers");
-  if (dst == src) {
-    decode_klass_not_null(dst);
+  // Cannot assert, unverified entry point counts instructions (see .ad file)
+  // vtableStubs also counts instructions in pd_code_size_limit.
+  // Also do not verify_oop as this is called by verify_oop.
+
+  if (CompressedKlassPointers::base() == NULL &&
+      CompressedKlassPointers::shift() == 0) {
+    // The best case scenario is that there is no base or shift. Then it is already
+    // a pointer that needs nothing but a register rename.
+    movl(dst, src);
   } else {
-    // Cannot assert, unverified entry point counts instructions (see .ad file)
-    // vtableStubs also counts instructions in pd_code_size_limit.
-    // Also do not verify_oop as this is called by verify_oop.
-    mov64(dst, (int64_t)CompressedKlassPointers::base());
+    if (CompressedKlassPointers::base() != NULL) {
+      mov64(dst, (int64_t)CompressedKlassPointers::base());
+    } else {
+      xorq(dst, dst);
+    }
     if (CompressedKlassPointers::shift() != 0) {
       assert(LogKlassAlignmentInBytes == CompressedKlassPointers::shift(), "decode alg wrong");
       assert(LogKlassAlignmentInBytes == Address::times_8, "klass not aligned on 64bits?");
@@ -4714,7 +4703,7 @@ void  MacroAssembler::cmp_narrow_klass(Address dst, Klass* k) {
 }
 
 void MacroAssembler::reinit_heapbase() {
-  if (UseCompressedOops || UseCompressedClassPointers) {
+  if (UseCompressedOops) {
     if (Universe::heap() != NULL) {
       if (CompressedOops::base() == NULL) {
         MacroAssembler::xorptr(r12_heapbase, r12_heapbase);
diff --git a/src/hotspot/cpu/x86/macroAssembler_x86.hpp b/src/hotspot/cpu/x86/macroAssembler_x86.hpp
index 8354371c42f..58b9e1f77bb 100644
--- a/src/hotspot/cpu/x86/macroAssembler_x86.hpp
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.hpp
@@ -315,8 +315,8 @@ class MacroAssembler: public Assembler {
   void load_method_holder(Register holder, Register method);
 
   // oop manipulations
-  void load_klass(Register dst, Register src);
-  void store_klass(Register dst, Register src);
+  void load_klass(Register dst, Register src, Register tmp);
+  void store_klass(Register dst, Register src, Register tmp);
 
   void access_load_at(BasicType type, DecoratorSet decorators, Register dst, Address src,
                       Register tmp1, Register thread_tmp);
@@ -338,7 +338,7 @@ class MacroAssembler: public Assembler {
   // stored using routines that take a jobject.
   void store_heap_oop_null(Address dst);
 
-  void load_prototype_header(Register dst, Register src);
+  void load_prototype_header(Register dst, Register src, Register tmp);
 
 #ifdef _LP64
   void store_klass_gap(Register dst, Register src);
@@ -361,19 +361,15 @@ class MacroAssembler: public Assembler {
   void cmp_narrow_oop(Register dst, jobject obj);
   void cmp_narrow_oop(Address dst, jobject obj);
 
-  void encode_klass_not_null(Register r);
-  void decode_klass_not_null(Register r);
-  void encode_klass_not_null(Register dst, Register src);
-  void decode_klass_not_null(Register dst, Register src);
+  void encode_klass_not_null(Register r, Register tmp);
+  void decode_klass_not_null(Register r, Register tmp);
+  void encode_and_move_klass_not_null(Register dst, Register src);
+  void decode_and_move_klass_not_null(Register dst, Register src);
   void set_narrow_klass(Register dst, Klass* k);
   void set_narrow_klass(Address dst, Klass* k);
   void cmp_narrow_klass(Register dst, Klass* k);
   void cmp_narrow_klass(Address dst, Klass* k);
 
-  // Returns the byte size of the instructions generated by decode_klass_not_null()
-  // when compressed klass pointers are being used.
-  static int instr_size_for_decode_klass_not_null();
-
   // if heap base register is used - reinit it with the correct value
   void reinit_heapbase();
 
@@ -671,7 +667,7 @@ class MacroAssembler: public Assembler {
   // the calling code has already passed any potential faults.
   int biased_locking_enter(Register lock_reg, Register obj_reg,
                            Register swap_reg, Register tmp_reg,
-                           bool swap_reg_contains_mark,
+                           Register tmp_reg2, bool swap_reg_contains_mark,
                            Label& done, Label* slow_case = NULL,
                            BiasedLockingCounters* counters = NULL);
   void biased_locking_exit (Register obj_reg, Register temp_reg, Label& done);
diff --git a/src/hotspot/cpu/x86/methodHandles_x86.cpp b/src/hotspot/cpu/x86/methodHandles_x86.cpp
index fa3e087ed3c..fa5b6f8e2bc 100644
--- a/src/hotspot/cpu/x86/methodHandles_x86.cpp
+++ b/src/hotspot/cpu/x86/methodHandles_x86.cpp
@@ -74,7 +74,7 @@ void MethodHandles::verify_klass(MacroAssembler* _masm,
   Klass* klass = SystemDictionary::well_known_klass(klass_id);
   Register temp = rdi;
   Register temp2 = noreg;
-  LP64_ONLY(temp2 = rscratch1);  // used by MacroAssembler::cmpptr
+  LP64_ONLY(temp2 = rscratch1);  // used by MacroAssembler::cmpptr and load_klass
   Label L_ok, L_bad;
   BLOCK_COMMENT("verify_klass {");
   __ verify_oop(obj);
@@ -82,7 +82,7 @@ void MethodHandles::verify_klass(MacroAssembler* _masm,
   __ jcc(Assembler::zero, L_bad);
   __ push(temp); if (temp2 != noreg)  __ push(temp2);
 #define UNPUSH { if (temp2 != noreg)  __ pop(temp2);  __ pop(temp); }
-  __ load_klass(temp, obj);
+  __ load_klass(temp, obj, temp2);
   __ cmpptr(temp, ExternalAddress((address) klass_addr));
   __ jcc(Assembler::equal, L_ok);
   intptr_t super_check_offset = klass->super_check_offset();
@@ -352,7 +352,7 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
       } else {
         // load receiver klass itself
         __ null_check(receiver_reg, oopDesc::klass_offset_in_bytes());
-        __ load_klass(temp1_recv_klass, receiver_reg);
+        __ load_klass(temp1_recv_klass, receiver_reg, temp2);
         __ verify_klass_ptr(temp1_recv_klass);
       }
       BLOCK_COMMENT("check_receiver {");
@@ -360,7 +360,7 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
       // Check the receiver against the MemberName.clazz
       if (VerifyMethodHandles && iid == vmIntrinsics::_linkToSpecial) {
         // Did not load it above...
-        __ load_klass(temp1_recv_klass, receiver_reg);
+        __ load_klass(temp1_recv_klass, receiver_reg, temp2);
         __ verify_klass_ptr(temp1_recv_klass);
       }
       if (VerifyMethodHandles && iid != vmIntrinsics::_linkToInterface) {
diff --git a/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp b/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp
index 2cb99b413c8..17b6be9ca9f 100644
--- a/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp
+++ b/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp
@@ -2109,7 +2109,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
 
     if (UseBiasedLocking) {
       // Note that oop_handle_reg is trashed during this call
-      __ biased_locking_enter(lock_reg, obj_reg, swap_reg, oop_handle_reg, false, lock_done, &slow_path_lock);
+      __ biased_locking_enter(lock_reg, obj_reg, swap_reg, oop_handle_reg, noreg, false, lock_done, &slow_path_lock);
     }
 
     // Load immediate 1 into swap_reg %rax,
diff --git a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp
index 28c1e529747..e309c2f3870 100644
--- a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp
+++ b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp
@@ -955,7 +955,7 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm
   Register temp = rbx;
 
   {
-    __ load_klass(temp, receiver);
+    __ load_klass(temp, receiver, rscratch1);
     __ cmpptr(temp, Address(holder, CompiledICHolder::holder_klass_offset()));
     __ movptr(rbx, Address(holder, CompiledICHolder::holder_metadata_offset()));
     __ jcc(Assembler::equal, ok);
@@ -2139,7 +2139,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
 
   assert_different_registers(ic_reg, receiver, rscratch1);
   __ verify_oop(receiver);
-  __ load_klass(rscratch1, receiver);
+  __ load_klass(rscratch1, receiver, rscratch2);
   __ cmpq(ic_reg, rscratch1);
   __ jcc(Assembler::equal, hit);
 
@@ -2483,7 +2483,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
 
     __ resolve(IS_NOT_NULL, obj_reg);
     if (UseBiasedLocking) {
-      __ biased_locking_enter(lock_reg, obj_reg, swap_reg, rscratch1, false, lock_done, &slow_path_lock);
+      __ biased_locking_enter(lock_reg, obj_reg, swap_reg, rscratch1, rscratch2, false, lock_done, &slow_path_lock);
     }
 
     // Load immediate 1 into swap_reg %rax
diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp
index 295240fdf06..4037c6648fb 100644
--- a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp
+++ b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp
@@ -1083,11 +1083,8 @@ class StubGenerator: public StubCodeGenerator {
     __ cmpptr(c_rarg2, c_rarg3);
     __ jcc(Assembler::notZero, error);
 
-    // set r12 to heapbase for load_klass()
-    __ reinit_heapbase();
-
     // make sure klass is 'reasonable', which is not zero.
-    __ load_klass(rax, rax);  // get klass
+    __ load_klass(rax, rax, rscratch1);  // get klass
     __ testptr(rax, rax);
     __ jcc(Assembler::zero, error); // if klass is NULL it is broken
 
@@ -2525,7 +2522,7 @@ class StubGenerator: public StubCodeGenerator {
     __ testptr(rax_oop, rax_oop);
     __ jcc(Assembler::zero, L_store_element);
 
-    __ load_klass(r11_klass, rax_oop);// query the object klass
+    __ load_klass(r11_klass, rax_oop, rscratch1);// query the object klass
     generate_type_check(r11_klass, ckoff, ckval, L_store_element);
     // ======== end loop ========
 
@@ -2689,8 +2686,10 @@ class StubGenerator: public StubCodeGenerator {
     const Register dst_pos    = c_rarg3;  // destination position
 #ifndef _WIN64
     const Register length     = c_rarg4;
+    const Register rklass_tmp = r9;  // load_klass
 #else
     const Address  length(rsp, 6 * wordSize);  // elements count is on stack on Win64
+    const Register rklass_tmp = rdi;  // load_klass
 #endif
 
     { int modulus = CodeEntryAlignment;
@@ -2763,7 +2762,7 @@ class StubGenerator: public StubCodeGenerator {
     __ testl(r11_length, r11_length);
     __ jccb(Assembler::negative, L_failed_0);
 
-    __ load_klass(r10_src_klass, src);
+    __ load_klass(r10_src_klass, src, rklass_tmp);
 #ifdef ASSERT
     //  assert(src->klass() != NULL);
     {
@@ -2774,7 +2773,7 @@ class StubGenerator: public StubCodeGenerator {
       __ bind(L1);
       __ stop("broken null klass");
       __ bind(L2);
-      __ load_klass(rax, dst);
+      __ load_klass(rax, dst, rklass_tmp);
       __ cmpq(rax, 0);
       __ jcc(Assembler::equal, L1);     // this would be broken also
       BLOCK_COMMENT("} assert klasses not null done");
@@ -2797,7 +2796,7 @@ class StubGenerator: public StubCodeGenerator {
     __ jcc(Assembler::equal, L_objArray);
 
     //  if (src->klass() != dst->klass()) return -1;
-    __ load_klass(rax, dst);
+    __ load_klass(rax, dst, rklass_tmp);
     __ cmpq(r10_src_klass, rax);
     __ jcc(Assembler::notEqual, L_failed);
 
@@ -2896,7 +2895,7 @@ class StubGenerator: public StubCodeGenerator {
 
     Label L_plain_copy, L_checkcast_copy;
     //  test array classes for subtyping
-    __ load_klass(rax, dst);
+    __ load_klass(rax, dst, rklass_tmp);
     __ cmpq(r10_src_klass, rax); // usual case is exact equality
     __ jcc(Assembler::notEqual, L_checkcast_copy);
 
@@ -2924,7 +2923,7 @@ class StubGenerator: public StubCodeGenerator {
                              rax, L_failed);
 
       const Register r11_dst_klass = r11;
-      __ load_klass(r11_dst_klass, dst); // reload
+      __ load_klass(r11_dst_klass, dst, rklass_tmp); // reload
 
       // Marshal the base address arguments now, freeing registers.
       __ lea(from, Address(src, src_pos, TIMES_OOP,
diff --git a/src/hotspot/cpu/x86/templateTable_x86.cpp b/src/hotspot/cpu/x86/templateTable_x86.cpp
index b23ddf9062e..2a6f3928001 100644
--- a/src/hotspot/cpu/x86/templateTable_x86.cpp
+++ b/src/hotspot/cpu/x86/templateTable_x86.cpp
@@ -1128,10 +1128,11 @@ void TemplateTable::aastore() {
   __ testptr(rax, rax);
   __ jcc(Assembler::zero, is_null);
 
+  Register tmp_load_klass = LP64_ONLY(rscratch1) NOT_LP64(noreg);
   // Move subklass into rbx
-  __ load_klass(rbx, rax);
+  __ load_klass(rbx, rax, tmp_load_klass);
   // Move superklass into rax
-  __ load_klass(rax, rdx);
+  __ load_klass(rax, rdx, tmp_load_klass);
   __ movptr(rax, Address(rax,
                          ObjArrayKlass::element_klass_offset()));
 
@@ -1174,7 +1175,8 @@ void TemplateTable::bastore() {
   index_check(rdx, rbx); // prefer index in rbx
   // Need to check whether array is boolean or byte
   // since both types share the bastore bytecode.
-  __ load_klass(rcx, rdx);
+  Register tmp_load_klass = LP64_ONLY(rscratch1) NOT_LP64(noreg);
+  __ load_klass(rcx, rdx, tmp_load_klass);
   __ movl(rcx, Address(rcx, Klass::layout_helper_offset()));
   int diffbit = Klass::layout_helper_boolean_diffbit();
   __ testl(rcx, diffbit);
@@ -2644,7 +2646,8 @@ void TemplateTable::_return(TosState state) {
     assert(state == vtos, "only valid state");
     Register robj = LP64_ONLY(c_rarg1) NOT_LP64(rax);
     __ movptr(robj, aaddress(0));
-    __ load_klass(rdi, robj);
+    Register tmp_load_klass = LP64_ONLY(rscratch1) NOT_LP64(noreg);
+    __ load_klass(rdi, robj, tmp_load_klass);
     __ movl(rdi, Address(rdi, Klass::access_flags_offset()));
     __ testl(rdi, JVM_ACC_HAS_FINALIZER);
     Label skip_register_finalizer;
@@ -3737,7 +3740,8 @@ void TemplateTable::invokevirtual_helper(Register index,
 
   // get receiver klass
   __ null_check(recv, oopDesc::klass_offset_in_bytes());
-  __ load_klass(rax, recv);
+  Register tmp_load_klass = LP64_ONLY(rscratch1) NOT_LP64(noreg);
+  __ load_klass(rax, recv, tmp_load_klass);
 
   // profile this call
   __ profile_virtual_call(rax, rlocals, rdx);
@@ -3829,7 +3833,8 @@ void TemplateTable::invokeinterface(int byte_no) {
 
   // Get receiver klass into rlocals - also a null check
   __ null_check(rcx, oopDesc::klass_offset_in_bytes());
-  __ load_klass(rlocals, rcx);
+  Register tmp_load_klass = LP64_ONLY(rscratch1) NOT_LP64(noreg);
+  __ load_klass(rlocals, rcx, tmp_load_klass);
 
   Label subtype;
   __ check_klass_subtype(rlocals, rax, rbcp, subtype);
@@ -3852,7 +3857,7 @@ void TemplateTable::invokeinterface(int byte_no) {
   // Get receiver klass into rdx - also a null check
   __ restore_locals();  // restore r14
   __ null_check(rcx, oopDesc::klass_offset_in_bytes());
-  __ load_klass(rdx, rcx);
+  __ load_klass(rdx, rcx, tmp_load_klass);
 
   Label no_such_method;
 
@@ -4113,7 +4118,8 @@ void TemplateTable::_new() {
     __ xorl(rsi, rsi); // use zero reg to clear memory (shorter code)
     __ store_klass_gap(rax, rsi);  // zero klass gap for compressed oops
 #endif
-    __ store_klass(rax, rcx);  // klass
+    Register tmp_store_klass = LP64_ONLY(rscratch1) NOT_LP64(noreg);
+    __ store_klass(rax, rcx, tmp_store_klass);  // klass
 
     {
       SkipIfEqual skip_if(_masm, &DTraceAllocProbes, 0);
@@ -4207,7 +4213,8 @@ void TemplateTable::checkcast() {
   __ load_resolved_klass_at_index(rax, rcx, rbx);
 
   __ bind(resolved);
-  __ load_klass(rbx, rdx);
+  Register tmp_load_klass = LP64_ONLY(rscratch1) NOT_LP64(noreg);
+  __ load_klass(rbx, rdx, tmp_load_klass);
 
   // Generate subtype check.  Blows rcx, rdi.  Object in rdx.
   // Superklass in rax.  Subklass in rbx.
@@ -4264,12 +4271,13 @@ void TemplateTable::instanceof() {
 
   __ pop_ptr(rdx); // restore receiver
   __ verify_oop(rdx);
-  __ load_klass(rdx, rdx);
+  Register tmp_load_klass = LP64_ONLY(rscratch1) NOT_LP64(noreg);
+  __ load_klass(rdx, rdx, tmp_load_klass);
   __ jmpb(resolved);
 
   // Get superklass in rax and subklass in rdx
   __ bind(quicked);
-  __ load_klass(rdx, rax);
+  __ load_klass(rdx, rax, tmp_load_klass);
   __ load_resolved_klass_at_index(rax, rcx, rbx);
 
   __ bind(resolved);
diff --git a/src/hotspot/cpu/x86/vtableStubs_x86_32.cpp b/src/hotspot/cpu/x86/vtableStubs_x86_32.cpp
index 24e080dbe45..09322205f06 100644
--- a/src/hotspot/cpu/x86/vtableStubs_x86_32.cpp
+++ b/src/hotspot/cpu/x86/vtableStubs_x86_32.cpp
@@ -195,7 +195,7 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) {
   // get receiver klass (also an implicit null-check)
   assert(VtableStub::receiver_location() ==  rcx->as_VMReg(), "receiver expected in  rcx");
   address npe_addr = __ pc();
-  __ load_klass(recv_klass_reg, rcx);
+  __ load_klass(recv_klass_reg, rcx, noreg);
 
   start_pc = __ pc();
 
@@ -213,7 +213,7 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) {
 
   // Get selected method from declaring class and itable index
   const Register method = rbx;
-  __ load_klass(recv_klass_reg, rcx); // restore recv_klass_reg
+  __ load_klass(recv_klass_reg, rcx, noreg); // restore recv_klass_reg
   __ lookup_interface_method(// inputs: rec. class, interface, itable index
                              recv_klass_reg, holder_klass_reg, itable_index,
                              // outputs: method, scan temp. reg
diff --git a/src/hotspot/cpu/x86/vtableStubs_x86_64.cpp b/src/hotspot/cpu/x86/vtableStubs_x86_64.cpp
index bf67008f3dd..e626f95b33b 100644
--- a/src/hotspot/cpu/x86/vtableStubs_x86_64.cpp
+++ b/src/hotspot/cpu/x86/vtableStubs_x86_64.cpp
@@ -48,6 +48,7 @@ extern "C" void bad_compiled_vtable_index(JavaThread* thread, oop receiver, int
 VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
   // Read "A word on VtableStub sizing" in share/code/vtableStubs.hpp for details on stub sizing.
   const int stub_code_length = code_size_limit(true);
+  Register tmp_load_klass = rscratch1;
   VtableStub* s = new(stub_code_length) VtableStub(true, vtable_index);
   // Can be NULL if there is no free space in the code cache.
   if (s == NULL) {
@@ -80,7 +81,7 @@ VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
 
   // get receiver klass
   address npe_addr = __ pc();
-  __ load_klass(rax, j_rarg0);
+  __ load_klass(rax, j_rarg0, tmp_load_klass);
 
 #ifndef PRODUCT
   if (DebugVtables) {
@@ -186,7 +187,7 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) {
   // get receiver klass (also an implicit null-check)
   assert(VtableStub::receiver_location() == j_rarg0->as_VMReg(), "receiver expected in j_rarg0");
   address npe_addr = __ pc();
-  __ load_klass(recv_klass_reg, j_rarg0);
+  __ load_klass(recv_klass_reg, j_rarg0, temp_reg);
 
   start_pc = __ pc();
 
@@ -204,7 +205,7 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) {
 
   // Get selected method from declaring class and itable index
   const Register method = rbx;
-  __ load_klass(recv_klass_reg, j_rarg0);   // restore recv_klass_reg
+  __ load_klass(recv_klass_reg, j_rarg0, temp_reg);   // restore recv_klass_reg
   __ lookup_interface_method(// inputs: rec. class, interface, itable index
                              recv_klass_reg, holder_klass_reg, itable_index,
                              // outputs: method, scan temp. reg
diff --git a/src/hotspot/cpu/x86/x86_64.ad b/src/hotspot/cpu/x86/x86_64.ad
index 222d6c563c7..63aa78d5d0c 100644
--- a/src/hotspot/cpu/x86/x86_64.ad
+++ b/src/hotspot/cpu/x86/x86_64.ad
@@ -357,7 +357,7 @@ RegMask _STACK_OR_LONG_REG_mask;
 RegMask _STACK_OR_INT_REG_mask;
 
 static bool need_r12_heapbase() {
-  return UseCompressedOops || UseCompressedClassPointers;
+  return UseCompressedOops;
 }
 
 void reg_mask_init() {
@@ -1549,7 +1549,7 @@ void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
   MacroAssembler masm(&cbuf);
   uint insts_size = cbuf.insts_size();
   if (UseCompressedClassPointers) {
-    masm.load_klass(rscratch1, j_rarg0);
+    masm.load_klass(rscratch1, j_rarg0, rscratch2);
     masm.cmpptr(rax, rscratch1);
   } else {
     masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes()));
@@ -5956,7 +5956,7 @@ instruct storeP(memory mem, any_RegP src)
 
 instruct storeImmP0(memory mem, immP0 zero)
 %{
-  predicate(UseCompressedOops && (CompressedOops::base() == NULL) && (CompressedKlassPointers::base() == NULL));
+  predicate(UseCompressedOops && (CompressedOops::base() == NULL));
   match(Set mem (StoreP mem zero));
 
   ins_cost(125); // XXX
@@ -6006,7 +6006,7 @@ instruct storeNKlass(memory mem, rRegN src)
 
 instruct storeImmN0(memory mem, immN0 zero)
 %{
-  predicate(CompressedOops::base() == NULL && CompressedKlassPointers::base() == NULL);
+  predicate(CompressedOops::base() == NULL);
   match(Set mem (StoreN mem zero));
 
   ins_cost(125); // XXX
@@ -6049,7 +6049,7 @@ instruct storeImmNKlass(memory mem, immNKlass src)
 // Store Integer Immediate
 instruct storeImmI0(memory mem, immI0 zero)
 %{
-  predicate(UseCompressedOops && (CompressedOops::base() == NULL) && (CompressedKlassPointers::base() == NULL));
+  predicate(UseCompressedOops && (CompressedOops::base() == NULL));
   match(Set mem (StoreI mem zero));
 
   ins_cost(125); // XXX
@@ -6074,7 +6074,7 @@ instruct storeImmI(memory mem, immI src)
 // Store Long Immediate
 instruct storeImmL0(memory mem, immL0 zero)
 %{
-  predicate(UseCompressedOops && (CompressedOops::base() == NULL) && (CompressedKlassPointers::base() == NULL));
+  predicate(UseCompressedOops && (CompressedOops::base() == NULL));
   match(Set mem (StoreL mem zero));
 
   ins_cost(125); // XXX
@@ -6099,7 +6099,7 @@ instruct storeImmL(memory mem, immL32 src)
 // Store Short/Char Immediate
 instruct storeImmC0(memory mem, immI0 zero)
 %{
-  predicate(UseCompressedOops && (CompressedOops::base() == NULL) && (CompressedKlassPointers::base() == NULL));
+  predicate(UseCompressedOops && (CompressedOops::base() == NULL));
   match(Set mem (StoreC mem zero));
 
   ins_cost(125); // XXX
@@ -6125,7 +6125,7 @@ instruct storeImmI16(memory mem, immI16 src)
 // Store Byte Immediate
 instruct storeImmB0(memory mem, immI0 zero)
 %{
-  predicate(UseCompressedOops && (CompressedOops::base() == NULL) && (CompressedKlassPointers::base() == NULL));
+  predicate(UseCompressedOops && (CompressedOops::base() == NULL));
   match(Set mem (StoreB mem zero));
 
   ins_cost(125); // XXX
@@ -6150,7 +6150,7 @@ instruct storeImmB(memory mem, immI8 src)
 // Store CMS card-mark Immediate
 instruct storeImmCM0_reg(memory mem, immI0 zero)
 %{
-  predicate(UseCompressedOops && (CompressedOops::base() == NULL) && (CompressedKlassPointers::base() == NULL));
+  predicate(UseCompressedOops && (CompressedOops::base() == NULL));
   match(Set mem (StoreCM mem zero));
 
   ins_cost(125); // XXX
@@ -6188,7 +6188,7 @@ instruct storeF(memory mem, regF src)
 // Store immediate Float value (it is faster than store from XMM register)
 instruct storeF0(memory mem, immF0 zero)
 %{
-  predicate(UseCompressedOops && (CompressedOops::base() == NULL) && (CompressedKlassPointers::base() == NULL));
+  predicate(UseCompressedOops && (CompressedOops::base() == NULL));
   match(Set mem (StoreF mem zero));
 
   ins_cost(25); // XXX
@@ -6238,7 +6238,7 @@ instruct storeD0_imm(memory mem, immD0 src)
 
 instruct storeD0(memory mem, immD0 zero)
 %{
-  predicate(UseCompressedOops && (CompressedOops::base() == NULL) && (CompressedKlassPointers::base() == NULL));
+  predicate(UseCompressedOops && (CompressedOops::base() == NULL));
   match(Set mem (StoreD mem zero));
 
   ins_cost(25); // XXX
@@ -6791,31 +6791,24 @@ instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{
 
 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{
   match(Set dst (EncodePKlass src));
-  effect(KILL cr);
-  format %{ "encode_klass_not_null $dst,$src" %}
+  effect(TEMP dst, KILL cr);
+  format %{ "encode_and_move_klass_not_null $dst,$src" %}
   ins_encode %{
-    __ encode_klass_not_null($dst$$Register, $src$$Register);
+    __ encode_and_move_klass_not_null($dst$$Register, $src$$Register);
   %}
   ins_pipe(ialu_reg_long);
 %}
 
 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{
   match(Set dst (DecodeNKlass src));
-  effect(KILL cr);
-  format %{ "decode_klass_not_null $dst,$src" %}
+  effect(TEMP dst, KILL cr);
+  format %{ "decode_and_move_klass_not_null $dst,$src" %}
   ins_encode %{
-    Register s = $src$$Register;
-    Register d = $dst$$Register;
-    if (s != d) {
-      __ decode_klass_not_null(d, s);
-    } else {
-      __ decode_klass_not_null(d);
-    }
+    __ decode_and_move_klass_not_null($dst$$Register, $src$$Register);
   %}
   ins_pipe(ialu_reg_long);
 %}
 
-
 //----------Conditional Move---------------------------------------------------
 // Jump
 // dummy instruction for generating temp registers
@@ -11723,7 +11716,6 @@ instruct testP_mem(rFlagsReg cr, memory op, immP0 zero)
 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero)
 %{
   predicate(UseCompressedOops && (CompressedOops::base() == NULL) &&
-            (CompressedKlassPointers::base() == NULL) &&
             n->in(1)->as_Load()->barrier_data() == 0);
   match(Set cr (CmpP (LoadP mem) zero));
 
@@ -11819,7 +11811,7 @@ instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero)
 
 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero)
 %{
-  predicate(CompressedOops::base() == NULL && (CompressedKlassPointers::base() == NULL));
+  predicate(CompressedOops::base() == NULL);
   match(Set cr (CmpN (LoadN mem) zero));
 
   format %{ "cmpl    R12, $mem\t# compressed ptr (R12_heapbase==0)" %}
@@ -12466,15 +12458,15 @@ instruct cmpFastLockRTM(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp,
   ins_pipe(pipe_slow);
 %}
 
-instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{
+instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr, rRegP cx1) %{
   predicate(!Compile::current()->use_rtm());
   match(Set cr (FastLock object box));
-  effect(TEMP tmp, TEMP scr, USE_KILL box);
+  effect(TEMP tmp, TEMP scr, TEMP cx1, USE_KILL box);
   ins_cost(300);
   format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %}
   ins_encode %{
     __ fast_lock($object$$Register, $box$$Register, $tmp$$Register,
-                 $scr$$Register, noreg, noreg, _counters, NULL, NULL, NULL, false, false);
+                 $scr$$Register, $cx1$$Register, noreg, _counters, NULL, NULL, NULL, false, false);
   %}
   ins_pipe(pipe_slow);
 %}
diff --git a/src/hotspot/share/classfile/fieldLayoutBuilder.cpp b/src/hotspot/share/classfile/fieldLayoutBuilder.cpp
index 5f30f61597e..06907a56ba1 100644
--- a/src/hotspot/share/classfile/fieldLayoutBuilder.cpp
+++ b/src/hotspot/share/classfile/fieldLayoutBuilder.cpp
@@ -643,69 +643,6 @@ void FieldLayoutBuilder::compute_regular_layout() {
   epilogue();
 }
 
-// Compute layout of the java/lang/ref/Reference class according
-// to the hard coded offsets of its fields
-void FieldLayoutBuilder::compute_java_lang_ref_Reference_layout() {
-  prologue();
-  regular_field_sorting();
-
-  assert(_contended_groups.is_empty(), "java.lang.Reference has no @Contended annotations");
-  assert(_root_group->primitive_fields() == NULL, "java.lang.Reference has no nonstatic primitive fields");
-  int field_count = 0;
-  int offset = -1;
-  for (int i = 0; i < _root_group->oop_fields()->length(); i++) {
-    LayoutRawBlock* b = _root_group->oop_fields()->at(i);
-    FieldInfo* fi = FieldInfo::from_field_array(_fields, b->field_index());
-    if (fi->name(_constant_pool)->equals("referent")) {
-      offset = java_lang_ref_Reference::referent_offset;
-    } else if (fi->name(_constant_pool)->equals("queue")) {
-      offset = java_lang_ref_Reference::queue_offset;
-    } else if (fi->name(_constant_pool)->equals("next")) {
-      offset = java_lang_ref_Reference::next_offset;
-    } else if (fi->name(_constant_pool)->equals("discovered")) {
-      offset = java_lang_ref_Reference::discovered_offset;
-    }
-    assert(offset != -1, "Unknown field");
-    _layout->add_field_at_offset(b, offset);
-    field_count++;
-  }
-  assert(field_count == 4, "Wrong number of fields in java.lang.ref.Reference");
-
-  _static_layout->add_contiguously(this->_static_fields->oop_fields());
-  _static_layout->add(this->_static_fields->primitive_fields());
-
-  epilogue();
-}
-
-// Compute layout of the boxing class according
-// to the hard coded offsets of their fields
-void FieldLayoutBuilder::compute_boxing_class_layout() {
-  prologue();
-  regular_field_sorting();
-
-  assert(_contended_groups.is_empty(), "Boxing classes have no @Contended annotations");
-  assert(_root_group->oop_fields() == NULL, "Boxing classes have no nonstatic oops fields");
-  int field_count = 0;
-  int offset = -1;
-
-  for (int i = 0; i < _root_group->primitive_fields()->length(); i++) {
-    LayoutRawBlock* b = _root_group->primitive_fields()->at(i);
-    FieldInfo* fi = FieldInfo::from_field_array(_fields, b->field_index());
-    assert(fi->name(_constant_pool)->equals("value"), "Boxing classes have a single nonstatic field named 'value'");
-    BasicType type = Signature::basic_type(fi->signature(_constant_pool));
-    offset = java_lang_boxing_object::value_offset_in_bytes(type);
-    assert(offset != -1, "Unknown field");
-    _layout->add_field_at_offset(b, offset);
-    field_count++;
-  }
-  assert(field_count == 1, "Wrong number of fields for a boxing class");
-
-  _static_layout->add_contiguously(this->_static_fields->oop_fields());
-  _static_layout->add(this->_static_fields->primitive_fields());
-
-  epilogue();
-}
-
 void FieldLayoutBuilder::epilogue() {
   // Computing oopmaps
   int super_oop_map_count = (_super_klass == NULL) ? 0 :_super_klass->nonstatic_oop_map_count();
@@ -764,19 +701,5 @@ void FieldLayoutBuilder::epilogue() {
 }
 
 void FieldLayoutBuilder::build_layout() {
-  if (_classname == vmSymbols::java_lang_ref_Reference()) {
-    compute_java_lang_ref_Reference_layout();
-  } else if (_classname == vmSymbols::java_lang_Boolean() ||
-             _classname == vmSymbols::java_lang_Character() ||
-             _classname == vmSymbols::java_lang_Float() ||
-             _classname == vmSymbols::java_lang_Double() ||
-             _classname == vmSymbols::java_lang_Byte() ||
-             _classname == vmSymbols::java_lang_Short() ||
-             _classname == vmSymbols::java_lang_Integer() ||
-             _classname == vmSymbols::java_lang_Long()) {
-    compute_boxing_class_layout();
-  } else {
-    compute_regular_layout();
-  }
+  compute_regular_layout();
 }
-
diff --git a/src/hotspot/share/classfile/fieldLayoutBuilder.hpp b/src/hotspot/share/classfile/fieldLayoutBuilder.hpp
index 96c1eb3195f..462ba7d5ff5 100644
--- a/src/hotspot/share/classfile/fieldLayoutBuilder.hpp
+++ b/src/hotspot/share/classfile/fieldLayoutBuilder.hpp
@@ -253,8 +253,6 @@ class FieldLayoutBuilder : public ResourceObj {
 
   void build_layout();
   void compute_regular_layout();
-  void compute_java_lang_ref_Reference_layout();
-  void compute_boxing_class_layout();
   void insert_contended_padding(LayoutRawBlock* slot);
 
  private:
diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp
index 92b01bb83ab..cc5e02243de 100644
--- a/src/hotspot/share/classfile/javaClasses.cpp
+++ b/src/hotspot/share/classfile/javaClasses.cpp
@@ -4738,8 +4738,10 @@ jboolean java_lang_Boolean::value(oop obj) {
    return v.z;
 }
 
-static int member_offset(int hardcoded_offset) {
-  return (hardcoded_offset * heapOopSize) + instanceOopDesc::base_offset_in_bytes();
+// Use with care. This function makes a lot of assumptions about the contents of the object.
+// So naturally, only hardcode offsets if you know what you are doing.
+static int member_offset(int hardcoded_offset, int elementSize) {
+  return align_up((hardcoded_offset * elementSize) + instanceOopDesc::base_offset_in_bytes(), elementSize);
 }
 
 #define RECORDCOMPONENT_FIELDS_DO(macro) \
@@ -4797,14 +4799,14 @@ void java_lang_reflect_RecordComponent::set_typeAnnotations(oop element, oop val
 void JavaClasses::compute_hard_coded_offsets() {
 
   // java_lang_boxing_object
-  java_lang_boxing_object::value_offset      = member_offset(java_lang_boxing_object::hc_value_offset);
-  java_lang_boxing_object::long_value_offset = align_up(member_offset(java_lang_boxing_object::hc_value_offset), BytesPerLong);
+  java_lang_boxing_object::value_offset      = member_offset(java_lang_boxing_object::hc_value_offset, BytesPerInt);
+  java_lang_boxing_object::long_value_offset = member_offset(java_lang_boxing_object::hc_value_offset, BytesPerLong);
 
   // java_lang_ref_Reference
-  java_lang_ref_Reference::referent_offset    = member_offset(java_lang_ref_Reference::hc_referent_offset);
-  java_lang_ref_Reference::queue_offset       = member_offset(java_lang_ref_Reference::hc_queue_offset);
-  java_lang_ref_Reference::next_offset        = member_offset(java_lang_ref_Reference::hc_next_offset);
-  java_lang_ref_Reference::discovered_offset  = member_offset(java_lang_ref_Reference::hc_discovered_offset);
+  java_lang_ref_Reference::referent_offset    = member_offset(java_lang_ref_Reference::hc_referent_offset, heapOopSize);
+  java_lang_ref_Reference::queue_offset       = member_offset(java_lang_ref_Reference::hc_queue_offset, heapOopSize);
+  java_lang_ref_Reference::next_offset        = member_offset(java_lang_ref_Reference::hc_next_offset, heapOopSize);
+  java_lang_ref_Reference::discovered_offset  = member_offset(java_lang_ref_Reference::hc_discovered_offset, heapOopSize);
 }
 
 #define DO_COMPUTE_OFFSETS(k) k::compute_offsets();
diff --git a/src/hotspot/share/gc/z/zArguments.cpp b/src/hotspot/share/gc/z/zArguments.cpp
index bf8c2066210..e227bddf7e7 100644
--- a/src/hotspot/share/gc/z/zArguments.cpp
+++ b/src/hotspot/share/gc/z/zArguments.cpp
@@ -85,9 +85,8 @@ void ZArguments::initialize() {
   }
 #endif
 
-  // CompressedOops/UseCompressedClassPointers not supported
+  // CompressedOops not supported
   FLAG_SET_DEFAULT(UseCompressedOops, false);
-  FLAG_SET_DEFAULT(UseCompressedClassPointers, false);
 
   // Verification before startup and after exit not (yet) supported
   FLAG_SET_DEFAULT(VerifyDuringStartup, false);
diff --git a/src/hotspot/share/memory/metaspace.cpp b/src/hotspot/share/memory/metaspace.cpp
index ae541f287d5..dca02183885 100644
--- a/src/hotspot/share/memory/metaspace.cpp
+++ b/src/hotspot/share/memory/metaspace.cpp
@@ -1248,7 +1248,12 @@ void Metaspace::global_initialize() {
 
 #ifdef _LP64
   if (using_class_space() && !class_space_inited) {
-    char* base = (char*)align_up(CompressedOops::end(), _reserve_alignment);
+    char* base;
+    if (UseCompressedOops) {
+      base = (char*)align_up(CompressedOops::end(), _reserve_alignment);
+    } else {
+      base = (char*)HeapBaseMinAddress;
+    }
     ReservedSpace dummy;
     allocate_metaspace_compressed_klass_ptrs(dummy, base, 0);
   }
diff --git a/src/hotspot/share/oops/instanceOop.hpp b/src/hotspot/share/oops/instanceOop.hpp
index a6bf15d2b4b..e681e5d0a30 100644
--- a/src/hotspot/share/oops/instanceOop.hpp
+++ b/src/hotspot/share/oops/instanceOop.hpp
@@ -37,11 +37,17 @@ class instanceOopDesc : public oopDesc {
 
   // If compressed, the offset of the fields of the instance may not be aligned.
   static int base_offset_in_bytes() {
-    // offset computation code breaks if UseCompressedClassPointers
-    // only is true
-    return (UseCompressedOops && UseCompressedClassPointers) ?
-             klass_gap_offset_in_bytes() :
-             sizeof(instanceOopDesc);
+    if (UseNewFieldLayout) {
+      return (UseCompressedClassPointers) ?
+              klass_gap_offset_in_bytes() :
+              sizeof(instanceOopDesc);
+    } else {
+      // The old layout could not deal with compressed oops being off and compressed
+      // class pointers being off.
+      return (UseCompressedOops && UseCompressedClassPointers) ?
+              klass_gap_offset_in_bytes() :
+              sizeof(instanceOopDesc);
+    }
   }
 };
 
diff --git a/src/hotspot/share/opto/lcm.cpp b/src/hotspot/share/opto/lcm.cpp
index 6198b5a736c..270e4e7ec11 100644
--- a/src/hotspot/share/opto/lcm.cpp
+++ b/src/hotspot/share/opto/lcm.cpp
@@ -265,8 +265,8 @@ void PhaseCFG::implicit_null_check(Block* block, Node *proj, Node *val, int allo
         // cannot reason about it; is probably not implicit null exception
       } else {
         const TypePtr* tptr;
-        if (UseCompressedOops && (CompressedOops::shift() == 0 ||
-                                  CompressedKlassPointers::shift() == 0)) {
+        if ((UseCompressedOops || UseCompressedClassPointers) &&
+            (CompressedOops::shift() == 0 || CompressedKlassPointers::shift() == 0)) {
           // 32-bits narrow oop can be the base of address expressions
           tptr = base->get_ptr_type();
         } else {
diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp
index fb92c365f18..fd8f9b3388a 100644
--- a/src/hotspot/share/runtime/arguments.cpp
+++ b/src/hotspot/share/runtime/arguments.cpp
@@ -1666,7 +1666,9 @@ void Arguments::set_use_compressed_oops() {
     if (UseCompressedOops && !FLAG_IS_DEFAULT(UseCompressedOops)) {
       warning("Max heap size too large for Compressed Oops");
       FLAG_SET_DEFAULT(UseCompressedOops, false);
-      FLAG_SET_DEFAULT(UseCompressedClassPointers, false);
+      if (COMPRESSED_CLASS_POINTERS_DEPENDS_ON_COMPRESSED_OOPS) {
+        FLAG_SET_DEFAULT(UseCompressedClassPointers, false);
+      }
     }
   }
 #endif // _LP64
@@ -1679,8 +1681,14 @@ void Arguments::set_use_compressed_oops() {
 void Arguments::set_use_compressed_klass_ptrs() {
 #ifndef ZERO
 #ifdef _LP64
-  // UseCompressedOops must be on for UseCompressedClassPointers to be on.
-  if (!UseCompressedOops) {
+  // On some architectures, the use of UseCompressedClassPointers implies the use of
+  // UseCompressedOops. The reason is that the rheap_base register of said platforms
+  // is reused to perform some optimized spilling, in order to use rheap_base as a
+  // temp register. But by treating it as any other temp register, spilling can typically
+  // be completely avoided instead. So it is better not to perform this trick. And by
+  // not having that reliance, large heaps, or heaps not supporting compressed oops,
+  // can still use compressed class pointers.
+  if (COMPRESSED_CLASS_POINTERS_DEPENDS_ON_COMPRESSED_OOPS && !UseCompressedOops) {
     if (UseCompressedClassPointers) {
       warning("UseCompressedClassPointers requires UseCompressedOops");
     }
@@ -1809,10 +1817,7 @@ void Arguments::set_heap_size() {
     }
 
 #ifdef _LP64
-    if (UseCompressedOops) {
-      // Limit the heap size to the maximum possible when using compressed oops
-      julong max_coop_heap = (julong)max_heap_for_compressed_oops();
-
+    if (UseCompressedOops || UseCompressedClassPointers) {
       // HeapBaseMinAddress can be greater than default but not less than.
       if (!FLAG_IS_DEFAULT(HeapBaseMinAddress)) {
         if (HeapBaseMinAddress < DefaultHeapBaseMinAddress) {
@@ -1825,6 +1830,10 @@ void Arguments::set_heap_size() {
           FLAG_SET_ERGO(HeapBaseMinAddress, DefaultHeapBaseMinAddress);
         }
       }
+    }
+    if (UseCompressedOops) {
+      // Limit the heap size to the maximum possible when using compressed oops
+      julong max_coop_heap = (julong)max_heap_for_compressed_oops();
 
       if (HeapBaseMinAddress + MaxHeapSize < max_coop_heap) {
         // Heap should be above HeapBaseMinAddress to get zero based compressed oops
@@ -1843,7 +1852,9 @@ void Arguments::set_heap_size() {
             "Please check the setting of MaxRAMPercentage %5.2f."
             ,(size_t)reasonable_max, (size_t)max_coop_heap, MaxRAMPercentage);
           FLAG_SET_ERGO(UseCompressedOops, false);
-          FLAG_SET_ERGO(UseCompressedClassPointers, false);
+          if (COMPRESSED_CLASS_POINTERS_DEPENDS_ON_COMPRESSED_OOPS) {
+            FLAG_SET_ERGO(UseCompressedClassPointers, false);
+          }
         } else {
           reasonable_max = MIN2(reasonable_max, max_coop_heap);
         }
diff --git a/test/hotspot/jtreg/gc/metaspace/TestSizeTransitions.java b/test/hotspot/jtreg/gc/metaspace/TestSizeTransitions.java
index e37e3d03b72..3d9ce71e88a 100644
--- a/test/hotspot/jtreg/gc/metaspace/TestSizeTransitions.java
+++ b/test/hotspot/jtreg/gc/metaspace/TestSizeTransitions.java
@@ -79,13 +79,13 @@ public class TestSizeTransitions {
   private static final String SIZE_TRANSITION_REGEX = "\\d+K\\(\\d+K\\)->\\d+K\\(\\d+K\\)";
 
   // matches -coops metaspace size transitions
-  private static final String NO_COOPS_REGEX =
+  private static final String NO_COMPRESSED_KLASS_POINTERS_REGEX =
     String.format("^%s.* Metaspace: %s$",
                   LOG_TAGS_REGEX,
                   SIZE_TRANSITION_REGEX);
 
   // matches +coops metaspace size transitions
-  private static final String COOPS_REGEX =
+  private static final String COMPRESSED_KLASS_POINTERS_REGEX =
     String.format("^%s.* Metaspace: %s NonClass: %s Class: %s$",
                   LOG_TAGS_REGEX,
                   SIZE_TRANSITION_REGEX,
@@ -98,19 +98,19 @@ public class TestSizeTransitions {
       throw new RuntimeException("wrong number of args: " + args.length);
     }
 
-    final boolean hasCoops = Platform.is64bit();
-    final boolean useCoops = Boolean.parseBoolean(args[0]);
+    final boolean hasCompressedKlassPointers = Platform.is64bit();
+    final boolean useCompressedKlassPointers = Boolean.parseBoolean(args[0]);
     final String gcArg = args[1];
 
-    if (!hasCoops && useCoops) {
+    if (!hasCompressedKlassPointers && useCompressedKlassPointers) {
        // No need to run this configuration.
        System.out.println("Skipping test.");
        return;
     }
 
     List jvmArgs = new ArrayList<>();
-    if (hasCoops) {
-      jvmArgs.add(useCoops ? "-XX:+UseCompressedOops" : "-XX:-UseCompressedOops");
+    if (hasCompressedKlassPointers) {
+      jvmArgs.add(useCompressedKlassPointers ? "-XX:+UseCompressedClassPointers" : "-XX:-UseCompressedClassPointers");
     }
     jvmArgs.add(gcArg);
     jvmArgs.add("-Xmx256m");
@@ -127,12 +127,12 @@ public class TestSizeTransitions {
     System.out.println(output.getStdout());
     output.shouldHaveExitValue(0);
 
-    if (useCoops) {
-      output.stdoutShouldMatch(COOPS_REGEX);
-      output.stdoutShouldNotMatch(NO_COOPS_REGEX);
+    if (useCompressedKlassPointers) {
+      output.stdoutShouldMatch(COMPRESSED_KLASS_POINTERS_REGEX);
+      output.stdoutShouldNotMatch(NO_COMPRESSED_KLASS_POINTERS_REGEX);
     } else {
-      output.stdoutShouldMatch(NO_COOPS_REGEX);
-      output.stdoutShouldNotMatch(COOPS_REGEX);
+      output.stdoutShouldMatch(NO_COMPRESSED_KLASS_POINTERS_REGEX);
+      output.stdoutShouldNotMatch(COMPRESSED_KLASS_POINTERS_REGEX);
     }
   }
 }
diff --git a/test/hotspot/jtreg/runtime/CompressedOops/CompressedClassPointers.java b/test/hotspot/jtreg/runtime/CompressedOops/CompressedClassPointers.java
index 50b019bbfd7..f03c9f4cbdd 100644
--- a/test/hotspot/jtreg/runtime/CompressedOops/CompressedClassPointers.java
+++ b/test/hotspot/jtreg/runtime/CompressedOops/CompressedClassPointers.java
@@ -25,7 +25,7 @@
  * @test
  * @bug 8024927
  * @summary Testing address of compressed class pointer space as best as possible.
- * @requires vm.bits == 64 & vm.opt.final.UseCompressedOops == true & os.family != "windows"
+ * @requires vm.bits == 64 & os.family != "windows" & !vm.graal.enabled
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
  *          java.management
@@ -141,6 +141,123 @@ public class CompressedClassPointers {
         }
     }
 
+    public static void smallHeapTestNoCoop() throws Exception {
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+            "-XX:-UseCompressedOops",
+            "-XX:+UseCompressedClassPointers",
+            "-XX:+UnlockDiagnosticVMOptions",
+            "-XX:SharedBaseAddress=8g",
+            "-Xmx128m",
+            "-Xlog:gc+metaspace=trace",
+            "-Xshare:off",
+            "-Xlog:cds=trace",
+            "-XX:+VerifyBeforeGC", "-version");
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        output.shouldContain("Narrow klass base: 0x0000000000000000");
+        output.shouldHaveExitValue(0);
+    }
+
+    public static void smallHeapTestWith1GNoCoop() throws Exception {
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+            "-XX:-UseCompressedOops",
+            "-XX:+UseCompressedClassPointers",
+            "-XX:+UnlockDiagnosticVMOptions",
+            "-XX:CompressedClassSpaceSize=1g",
+            "-Xmx128m",
+            "-Xlog:gc+metaspace=trace",
+            "-Xshare:off",
+            "-Xlog:cds=trace",
+            "-XX:+VerifyBeforeGC", "-version");
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        output.shouldContain("Narrow klass base: 0x0000000000000000");
+        output.shouldContain("Narrow klass shift: 0");
+        output.shouldHaveExitValue(0);
+    }
+
+    public static void largeHeapTestNoCoop() throws Exception {
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+            "-XX:-UseCompressedOops",
+            "-XX:+UseCompressedClassPointers",
+            "-XX:+UnlockDiagnosticVMOptions",
+            "-XX:+UnlockExperimentalVMOptions",
+            "-Xmx30g",
+            "-XX:-UseAOT", // AOT explicitly set klass shift to 3.
+            "-Xlog:gc+metaspace=trace",
+            "-Xshare:off",
+            "-Xlog:cds=trace",
+            "-XX:+VerifyBeforeGC", "-version");
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        output.shouldContain("Narrow klass base: 0x0000000000000000");
+        output.shouldContain("Narrow klass shift: 0");
+        output.shouldHaveExitValue(0);
+    }
+
+    public static void largePagesTestNoCoop() throws Exception {
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+            "-XX:-UseCompressedOops",
+            "-XX:+UseCompressedClassPointers",
+            "-XX:+UnlockDiagnosticVMOptions",
+            "-Xmx128m",
+            "-XX:+UseLargePages",
+            "-Xlog:gc+metaspace=trace",
+            "-XX:+VerifyBeforeGC", "-version");
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        output.shouldContain("Narrow klass base:");
+        output.shouldHaveExitValue(0);
+    }
+
+    public static void heapBaseMinAddressTestNoCoop() throws Exception {
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+            "-XX:-UseCompressedOops",
+            "-XX:+UseCompressedClassPointers",
+            "-XX:HeapBaseMinAddress=1m",
+            "-Xlog:gc+heap+coops=debug",
+            "-version");
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        output.shouldContain("HeapBaseMinAddress must be at least");
+        output.shouldHaveExitValue(0);
+    }
+
+    public static void sharingTestNoCoop() throws Exception {
+        // Test small heaps
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+            "-XX:-UseCompressedOops",
+            "-XX:+UseCompressedClassPointers",
+            "-XX:+UnlockDiagnosticVMOptions",
+            "-XX:SharedArchiveFile=./CompressedClassPointers.jsa",
+            "-Xmx128m",
+            "-XX:SharedBaseAddress=8g",
+            "-XX:+PrintCompressedOopsMode",
+            "-XX:+VerifyBeforeGC",
+            "-Xshare:dump", "-Xlog:cds");
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        if (output.firstMatch("Shared spaces are not supported in this VM") != null) {
+            return;
+        }
+        try {
+          output.shouldContain("Loading classes to share");
+          output.shouldHaveExitValue(0);
+
+          pb = ProcessTools.createJavaProcessBuilder(
+            "-XX:-UseCompressedOops",
+            "-XX:+UseCompressedClassPointers",
+            "-XX:+UnlockDiagnosticVMOptions",
+            "-XX:SharedArchiveFile=./CompressedClassPointers.jsa",
+            "-Xmx128m",
+            "-XX:SharedBaseAddress=8g",
+            "-XX:+PrintCompressedOopsMode",
+            "-Xshare:on",
+            "-version");
+          output = new OutputAnalyzer(pb.start());
+          output.shouldContain("sharing");
+          output.shouldHaveExitValue(0);
+
+        } catch (RuntimeException e) {
+          output.shouldContain("Unable to use shared archive");
+          output.shouldHaveExitValue(1);
+        }
+    }
+
     public static void main(String[] args) throws Exception {
         if (Platform.isSolaris()) {
              String name = System.getProperty("os.version");
@@ -154,5 +271,22 @@ public class CompressedClassPointers {
         largePagesTest();
         heapBaseMinAddressTest();
         sharingTest();
+
+        boolean ccpRequiresCoop = Platform.isAArch64() || Platform.isSparc();
+
+        if (!ccpRequiresCoop && !Platform.isOSX()) {
+            // Testing compressed class pointers without compressed oops.
+            // This is only possible if the platform supports it. Notably,
+            // on macOS, when compressed oops is disabled and the heap is
+            // given an arbitrary address, that address occasionally collides
+            // with where we would ideally have placed the compressed class
+            // space. Therefore, macOS is omitted for now.
+            smallHeapTestNoCoop();
+            smallHeapTestWith1GNoCoop();
+            largeHeapTestNoCoop();
+            largePagesTestNoCoop();
+            heapBaseMinAddressTestNoCoop();
+            sharingTestNoCoop();
+        }
     }
 }
diff --git a/test/hotspot/jtreg/runtime/CompressedOops/CompressedClassSpaceSize.java b/test/hotspot/jtreg/runtime/CompressedOops/CompressedClassSpaceSize.java
index 0e12a067f15..6e596b01b52 100644
--- a/test/hotspot/jtreg/runtime/CompressedOops/CompressedClassSpaceSize.java
+++ b/test/hotspot/jtreg/runtime/CompressedOops/CompressedClassSpaceSize.java
@@ -83,14 +83,6 @@ public class CompressedClassSpaceSize {
               .shouldHaveExitValue(0);
 
 
-        pb = ProcessTools.createJavaProcessBuilder("-XX:-UseCompressedOops",
-                                                   "-XX:CompressedClassSpaceSize=1m",
-                                                   "-version");
-        output = new OutputAnalyzer(pb.start());
-        output.shouldContain("Setting CompressedClassSpaceSize has no effect when compressed class pointers are not used")
-              .shouldHaveExitValue(0);
-
-
         pb = ProcessTools.createJavaProcessBuilder("-XX:-UseCompressedClassPointers",
                                                    "-XX:CompressedClassSpaceSize=1m",
                                                    "-version");
diff --git a/test/hotspot/jtreg/runtime/cds/appcds/TestCombinedCompressedFlags.java b/test/hotspot/jtreg/runtime/cds/appcds/TestCombinedCompressedFlags.java
index 244a5b738df..4ae8b0da339 100644
--- a/test/hotspot/jtreg/runtime/cds/appcds/TestCombinedCompressedFlags.java
+++ b/test/hotspot/jtreg/runtime/cds/appcds/TestCombinedCompressedFlags.java
@@ -65,7 +65,7 @@ public class TestCombinedCompressedFlags {
             initExecArgs();
         }
         private void initExecArgs() {
-           /* The combinations have four cases. Note COOP off, CCPTR must be off
+           /* The combinations have four cases.
             *          UseCompressedOops   UseCompressedClassPointers  Result
             *    1.
             *    dump: on                  on
@@ -82,13 +82,11 @@ public class TestCombinedCompressedFlags {
             *    3.
             *    dump: off                 on
             *    test: off                 on                          Pass
-            *          off                 off                         Pass
             *          on                  on                          Fail
             *          on                  off                         Fail
             *    4.
             *    dump: off                 off
             *    test: off                 off                         Pass
-            *          off                 on                          Pass
             *          on                  on                          Fail
             *          on                  off                         Fail
             **/
@@ -114,8 +112,6 @@ public class TestCombinedCompressedFlags {
                     .add(new ConfArg(false, false, EXEC_ABNORMAL_MSG, FAIL));
 
             } else if (!dumpArg.useCompressedOops && dumpArg.useCompressedClassPointers) {
-                execArgs
-                    .add(new ConfArg(false, false, HELLO_STRING, PASS));
                 execArgs
                     .add(new ConfArg(false, true, HELLO_STRING, PASS));
                 execArgs
@@ -125,8 +121,6 @@ public class TestCombinedCompressedFlags {
             } else if (!dumpArg.useCompressedOops && !dumpArg.useCompressedClassPointers) {
                 execArgs
                     .add(new ConfArg(false, false, HELLO_STRING, PASS));
-                execArgs
-                    .add(new ConfArg(false, true, HELLO_STRING, PASS));
                 execArgs
                     .add(new ConfArg(true, true, EXEC_ABNORMAL_MSG, FAIL));
                 execArgs
diff --git a/test/hotspot/jtreg/runtime/cds/appcds/TestZGCWithCDS.java b/test/hotspot/jtreg/runtime/cds/appcds/TestZGCWithCDS.java
index 5d378e090c0..96c58cd2cdc 100644
--- a/test/hotspot/jtreg/runtime/cds/appcds/TestZGCWithCDS.java
+++ b/test/hotspot/jtreg/runtime/cds/appcds/TestZGCWithCDS.java
@@ -62,7 +62,19 @@ public class TestZGCWithCDS {
          out.shouldContain(HELLO);
          out.shouldHaveExitValue(0);
 
-         System.out.println("2. Run with -UseCompressedOops -UseCompressedClassPointers");
+         System.out.println("2. Run with +UseCompressedOops +UseCompressedClassPointers");
+         out = TestCommon
+                   .exec(helloJar,
+                         "-XX:-UseZGC",
+                         "-XX:+UseCompressedOops",           // in case turned off by vmoptions
+                         "-XX:+UseCompressedClassPointers",  // by jtreg
+                         "-Xlog:cds",
+                         "Hello");
+         out.shouldContain(UNABLE_TO_USE_ARCHIVE);
+         out.shouldContain(ERR_MSG);
+         out.shouldHaveExitValue(1);
+
+         System.out.println("3. Run with -UseCompressedOops -UseCompressedClassPointers");
          out = TestCommon
                    .exec(helloJar,
                          "-XX:+UseSerialGC",
@@ -70,10 +82,22 @@ public class TestZGCWithCDS {
                          "-XX:-UseCompressedClassPointers",
                          "-Xlog:cds",
                          "Hello");
+         out.shouldContain(UNABLE_TO_USE_ARCHIVE);
+         out.shouldContain(ERR_MSG);
+         out.shouldHaveExitValue(1);
+
+         System.out.println("4. Run with -UseCompressedOops +UseCompressedClassPointers");
+         out = TestCommon
+                   .exec(helloJar,
+                         "-XX:+UseSerialGC",
+                         "-XX:-UseCompressedOops",
+                         "-XX:+UseCompressedClassPointers",
+                         "-Xlog:cds",
+                         "Hello");
          out.shouldContain(HELLO);
          out.shouldHaveExitValue(0);
 
-         System.out.println("3. Run with +UseCompressedOops -UseCompressedClassPointers");
+         System.out.println("5. Run with +UseCompressedOops -UseCompressedClassPointers");
          out = TestCommon
                    .exec(helloJar,
                          "-XX:+UseSerialGC",
@@ -85,7 +109,7 @@ public class TestZGCWithCDS {
          out.shouldContain(ERR_MSG);
          out.shouldHaveExitValue(1);
 
-         System.out.println("4. Run with +UseCompressedOops +UseCompressedClassPointers");
+         System.out.println("6. Run with +UseCompressedOops +UseCompressedClassPointers");
          out = TestCommon
                    .exec(helloJar,
                          "-XX:+UseSerialGC",
@@ -97,18 +121,18 @@ public class TestZGCWithCDS {
          out.shouldContain(ERR_MSG);
          out.shouldHaveExitValue(1);
 
-         System.out.println("5. Dump with -UseCompressedOops -UseCompressedClassPointers");
+         System.out.println("7. Dump with -UseCompressedOops -UseCompressedClassPointers");
          out = TestCommon
                    .dump(helloJar,
                          new String[] {"Hello"},
                          "-XX:+UseSerialGC",
                          "-XX:-UseCompressedOops",
-                         "-XX:-UseCompressedClassPointers",
+                         "-XX:+UseCompressedClassPointers",
                          "-Xlog:cds");
          out.shouldContain("Dumping shared data to file:");
          out.shouldHaveExitValue(0);
 
-         System.out.println("6. Run with ZGC");
+         System.out.println("8. Run with ZGC");
          out = TestCommon
                    .exec(helloJar,
                          "-XX:+UseZGC",
diff --git a/test/jdk/jdk/jfr/event/gc/objectcount/TestObjectCountAfterGCEventWithG1ConcurrentMark.java b/test/jdk/jdk/jfr/event/gc/objectcount/TestObjectCountAfterGCEventWithG1ConcurrentMark.java
index ab2a37ee5b6..a120b52e740 100644
--- a/test/jdk/jdk/jfr/event/gc/objectcount/TestObjectCountAfterGCEventWithG1ConcurrentMark.java
+++ b/test/jdk/jdk/jfr/event/gc/objectcount/TestObjectCountAfterGCEventWithG1ConcurrentMark.java
@@ -33,7 +33,7 @@ import jdk.test.lib.jfr.GCHelper;
  * @requires (vm.gc == "G1" | vm.gc == null)
  *           & vm.opt.ExplicitGCInvokesConcurrent != false
  * @library /test/lib /test/jdk
- * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseG1GC -XX:+ExplicitGCInvokesConcurrent -XX:MarkSweepDeadRatio=0 -XX:-UseCompressedOops -XX:+IgnoreUnrecognizedVMOptions jdk.jfr.event.gc.objectcount.TestObjectCountAfterGCEventWithG1ConcurrentMark
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseG1GC -XX:+ExplicitGCInvokesConcurrent -XX:MarkSweepDeadRatio=0 -XX:-UseCompressedOops -XX:-UseCompressedClassPointers -XX:+IgnoreUnrecognizedVMOptions jdk.jfr.event.gc.objectcount.TestObjectCountAfterGCEventWithG1ConcurrentMark
  */
 public class TestObjectCountAfterGCEventWithG1ConcurrentMark {
     public static void main(String[] args) throws Exception {
diff --git a/test/jdk/jdk/jfr/event/gc/objectcount/TestObjectCountAfterGCEventWithG1FullCollection.java b/test/jdk/jdk/jfr/event/gc/objectcount/TestObjectCountAfterGCEventWithG1FullCollection.java
index 3169b3eefcf..73991d13bbd 100644
--- a/test/jdk/jdk/jfr/event/gc/objectcount/TestObjectCountAfterGCEventWithG1FullCollection.java
+++ b/test/jdk/jdk/jfr/event/gc/objectcount/TestObjectCountAfterGCEventWithG1FullCollection.java
@@ -33,7 +33,7 @@ import jdk.test.lib.jfr.GCHelper;
  * @requires (vm.gc == "G1" | vm.gc == null)
  *           & vm.opt.ExplicitGCInvokesConcurrent != true
  * @library /test/lib /test/jdk
- * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:-UseFastUnorderedTimeStamps -XX:+UseG1GC -XX:MarkSweepDeadRatio=0 -XX:-UseCompressedOops -XX:+IgnoreUnrecognizedVMOptions jdk.jfr.event.gc.objectcount.TestObjectCountAfterGCEventWithG1FullCollection
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:-UseFastUnorderedTimeStamps -XX:+UseG1GC -XX:MarkSweepDeadRatio=0 -XX:-UseCompressedOops -XX:-UseCompressedClassPointers -XX:+IgnoreUnrecognizedVMOptions jdk.jfr.event.gc.objectcount.TestObjectCountAfterGCEventWithG1FullCollection
  */
 public class TestObjectCountAfterGCEventWithG1FullCollection {
     public static void main(String[] args) throws Exception {
diff --git a/test/jdk/jdk/jfr/event/gc/objectcount/TestObjectCountAfterGCEventWithParallelOld.java b/test/jdk/jdk/jfr/event/gc/objectcount/TestObjectCountAfterGCEventWithParallelOld.java
index d450715e15f..25c3d1ba04b 100644
--- a/test/jdk/jdk/jfr/event/gc/objectcount/TestObjectCountAfterGCEventWithParallelOld.java
+++ b/test/jdk/jdk/jfr/event/gc/objectcount/TestObjectCountAfterGCEventWithParallelOld.java
@@ -32,7 +32,7 @@ import jdk.test.lib.jfr.GCHelper;
  * @requires vm.hasJFR
  * @requires vm.gc == "Parallel" | vm.gc == null
  * @library /test/lib /test/jdk
- * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:-UseFastUnorderedTimeStamps -XX:+UseParallelGC -XX:MarkSweepDeadRatio=0 -XX:-UseCompressedOops -XX:+IgnoreUnrecognizedVMOptions jdk.jfr.event.gc.objectcount.TestObjectCountAfterGCEventWithParallelOld
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:-UseFastUnorderedTimeStamps -XX:+UseParallelGC -XX:MarkSweepDeadRatio=0 -XX:-UseCompressedOops -XX:-UseCompressedClassPointers -XX:+IgnoreUnrecognizedVMOptions jdk.jfr.event.gc.objectcount.TestObjectCountAfterGCEventWithParallelOld
  */
 public class TestObjectCountAfterGCEventWithParallelOld {
     public static void main(String[] args) throws Exception {
diff --git a/test/jdk/jdk/jfr/event/gc/objectcount/TestObjectCountAfterGCEventWithSerial.java b/test/jdk/jdk/jfr/event/gc/objectcount/TestObjectCountAfterGCEventWithSerial.java
index 1416a625c8c..c0ca6ff23c6 100644
--- a/test/jdk/jdk/jfr/event/gc/objectcount/TestObjectCountAfterGCEventWithSerial.java
+++ b/test/jdk/jdk/jfr/event/gc/objectcount/TestObjectCountAfterGCEventWithSerial.java
@@ -32,7 +32,7 @@ import jdk.test.lib.jfr.GCHelper;
  * @requires vm.hasJFR
  * @requires vm.gc == "Serial" | vm.gc == null
  * @library /test/lib /test/jdk
- * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:-UseFastUnorderedTimeStamps -XX:+UseSerialGC -XX:MarkSweepDeadRatio=0 -XX:-UseCompressedOops -XX:+IgnoreUnrecognizedVMOptions jdk.jfr.event.gc.objectcount.TestObjectCountAfterGCEventWithSerial
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:-UseFastUnorderedTimeStamps -XX:+UseSerialGC -XX:MarkSweepDeadRatio=0 -XX:-UseCompressedOops -XX:-UseCompressedClassPointers -XX:+IgnoreUnrecognizedVMOptions jdk.jfr.event.gc.objectcount.TestObjectCountAfterGCEventWithSerial
  */
 public class TestObjectCountAfterGCEventWithSerial {
     public static void main(String[] args) throws Exception {
diff --git a/test/jdk/jdk/jfr/event/gc/objectcount/TestObjectCountEvent.java b/test/jdk/jdk/jfr/event/gc/objectcount/TestObjectCountEvent.java
index 42a670a0e64..659050722bf 100644
--- a/test/jdk/jdk/jfr/event/gc/objectcount/TestObjectCountEvent.java
+++ b/test/jdk/jdk/jfr/event/gc/objectcount/TestObjectCountEvent.java
@@ -41,7 +41,7 @@ import jdk.test.lib.jfr.Events;
  * @requires vm.hasJFR
  * @requires vm.gc == "Serial" | vm.gc == null
  * @library /test/lib /test/jdk
- * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:-UseFastUnorderedTimeStamps -XX:+UseSerialGC -XX:-UseCompressedOops -XX:MarkSweepDeadRatio=0 -XX:+IgnoreUnrecognizedVMOptions jdk.jfr.event.gc.objectcount.TestObjectCountEvent
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:-UseFastUnorderedTimeStamps -XX:+UseSerialGC -XX:-UseCompressedOops -XX:-UseCompressedClassPointers -XX:MarkSweepDeadRatio=0 -XX:+IgnoreUnrecognizedVMOptions jdk.jfr.event.gc.objectcount.TestObjectCountEvent
  */
 public class TestObjectCountEvent {
     private static final String objectCountEventPath = EventNames.ObjectCount;

From fe46f44bd1be02470b74841389e0a7380410b434 Mon Sep 17 00:00:00 2001
From: Andy Herrick 
Date: Tue, 12 May 2020 19:20:28 -0400
Subject: [PATCH 038/143] 8244758: DMG bundler ignores --install-dir option

Reviewed-by: asemenyuk, almatvee
---
 .../jpackage/internal/MacBaseInstallerBundler.java    | 11 +++++++++++
 .../incubator/jpackage/internal/MacDmgBundler.java    |  5 +++--
 .../incubator/jpackage/internal/MacPkgBundler.java    | 11 -----------
 .../jpackage/internal/resources/DMGsetup.scpt         |  4 ++--
 4 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacBaseInstallerBundler.java b/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacBaseInstallerBundler.java
index 6423ea12268..d55c1da9a58 100644
--- a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacBaseInstallerBundler.java
+++ b/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacBaseInstallerBundler.java
@@ -83,6 +83,17 @@ public abstract class MacBaseInstallerBundler extends AbstractBundler {
             params -> "",
             null);
 
+    public static final BundlerParamInfo MAC_INSTALL_DIR =
+            new StandardBundlerParam<>(
+            "mac-install-dir",
+            String.class,
+             params -> {
+                 String dir = INSTALL_DIR.fetchFrom(params);
+                 return (dir != null) ? dir : "/Applications";
+             },
+            (s, p) -> s
+    );
+
     public static final BundlerParamInfo INSTALLER_NAME =
             new StandardBundlerParam<> (
             "mac.installerName",
diff --git a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacDmgBundler.java b/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacDmgBundler.java
index fd0ca2f604a..81de7f34743 100644
--- a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacDmgBundler.java
+++ b/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacDmgBundler.java
@@ -31,6 +31,7 @@ import java.nio.file.Path;
 import java.text.MessageFormat;
 import java.util.*;
 import static jdk.incubator.jpackage.internal.MacAppImageBuilder.ICON_ICNS;
+import static jdk.incubator.jpackage.internal.MacAppImageBuilder.MAC_CF_BUNDLE_IDENTIFIER;
 import static jdk.incubator.jpackage.internal.OverridableResource.createResource;
 
 import static jdk.incubator.jpackage.internal.StandardBundlerParam.*;
@@ -116,8 +117,8 @@ public class MacDmgBundler extends MacBaseInstallerBundler {
         data.put("DEPLOY_VOLUME_PATH", volumePath.toString());
         data.put("DEPLOY_APPLICATION_NAME", APP_NAME.fetchFrom(params));
 
-        data.put("DEPLOY_INSTALL_LOCATION", "(path to applications folder)");
-        data.put("DEPLOY_INSTALL_NAME", "Applications");
+        data.put("DEPLOY_INSTALL_LOCATION", MAC_INSTALL_DIR.fetchFrom(params));
+        data.put("DEPLOY_INSTALL_NAME", MAC_INSTALL_DIR.fetchFrom(params));
 
         createResource(DEFAULT_DMG_SETUP_SCRIPT, params)
                 .setCategory(I18N.getString("resource.dmg-setup-script"))
diff --git a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacPkgBundler.java b/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacPkgBundler.java
index 8bf6e96b119..dae6c96ef15 100644
--- a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacPkgBundler.java
+++ b/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacPkgBundler.java
@@ -101,17 +101,6 @@ public class MacPkgBundler extends MacBaseInstallerBundler {
                 },
             (s, p) -> s);
 
-    public static final BundlerParamInfo MAC_INSTALL_DIR =
-            new StandardBundlerParam<>(
-            "mac-install-dir",
-            String.class,
-             params -> {
-                 String dir = INSTALL_DIR.fetchFrom(params);
-                 return (dir != null) ? dir : "/Applications";
-             },
-            (s, p) -> s
-    );
-
     public static final BundlerParamInfo INSTALLER_SUFFIX =
             new StandardBundlerParam<> (
             "mac.pkg.installerName.suffix",
diff --git a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/DMGsetup.scpt b/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/DMGsetup.scpt
index eac9c6daf76..4f0b23857c2 100644
--- a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/DMGsetup.scpt
+++ b/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/DMGsetup.scpt
@@ -17,7 +17,7 @@ tell application "Finder"
   set background picture of theViewOptions to POSIX file "DEPLOY_BG_FILE"
 
   -- Create alias for install location
-  make new alias file at POSIX file "DEPLOY_VOLUME_PATH" to DEPLOY_INSTALL_LOCATION with properties {name:"DEPLOY_INSTALL_NAME"}
+  make new alias file at POSIX file "DEPLOY_VOLUME_PATH" to POSIX file "DEPLOY_INSTALL_LOCATION" with properties {name:"DEPLOY_INSTALL_NAME"}
 
   set allTheFiles to the name of every item of theWindow
   repeat with theFile in allTheFiles
@@ -25,7 +25,7 @@ tell application "Finder"
     if theFilePath is "/DEPLOY_APPLICATION_NAME.app" then
       -- Position application location
       set position of item theFile of theWindow to {120, 130}
-    else if theFilePath is "/DEPLOY_INSTALL_NAME" then
+    else if theFilePath is "DEPLOY_INSTALL_NAME" then
       -- Position install location
       set position of item theFile of theWindow to {390, 130}
     else

From 707462edc263a11fae9f5620c30a1b4823112739 Mon Sep 17 00:00:00 2001
From: Magnus Ihse Bursie 
Date: Wed, 13 May 2020 15:03:24 +0200
Subject: [PATCH 039/143] 8244930: Building without test failure handler broken
 after JDK-8244844

Reviewed-by: erikj
---
 make/Main.gmk | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/make/Main.gmk b/make/Main.gmk
index 65a5911c3a7..81843478de5 100644
--- a/make/Main.gmk
+++ b/make/Main.gmk
@@ -1109,10 +1109,13 @@ ifeq ($(INCLUDE_GRAAL), true)
 endif
 
 # This target builds the test image
-test-image: prepare-test-image \
-    test-image-jdk-jtreg-native test-image-failure-handler \
+test-image: prepare-test-image test-image-jdk-jtreg-native \
     test-image-demos-jdk $(JVM_TEST_IMAGE_TARGETS)
 
+ifeq ($(BUILD_FAILURE_HANDLER), true)
+  test-image: test-image-failure-handler
+endif
+
 ifneq ($(JMH_CORE_JAR), )
   test-image: build-microbenchmark
 endif

From ca53ee259314c94202a76efe9a8b65a8baf40f3b Mon Sep 17 00:00:00 2001
From: Erik Gahlin 
Date: Wed, 13 May 2020 16:18:16 +0200
Subject: [PATCH 040/143] 8242934: test/jdk/jdk/jfr/tool/TestPrintJSON.java
 uses nashorn script engine

Reviewed-by: mgronlun
---
 test/jdk/ProblemList.txt                 |   5 -
 test/jdk/jdk/jfr/tool/JSONValue.java     | 551 +++++++++++++++++++++++
 test/jdk/jdk/jfr/tool/TestPrintJSON.java |  42 +-
 3 files changed, 567 insertions(+), 31 deletions(-)
 create mode 100644 test/jdk/jdk/jfr/tool/JSONValue.java

diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt
index 7f330931974..8e7cb07d032 100644
--- a/test/jdk/ProblemList.txt
+++ b/test/jdk/ProblemList.txt
@@ -948,11 +948,6 @@ javax/script/Test7.java                                         8239361 generic-
 jdk/jfr/event/runtime/TestNetworkUtilizationEvent.java          8228990,8229370    generic-all
 jdk/jfr/event/compiler/TestCodeSweeper.java                     8225209    generic-all
 
-jdk/jfr/api/consumer/TestHiddenMethod.java                  8242933    generic-all
-jdk/jfr/tool/TestPrintJSON.java                             8242934    generic-all
-
-
-
 ############################################################################
 
 # jdk_internal
diff --git a/test/jdk/jdk/jfr/tool/JSONValue.java b/test/jdk/jdk/jfr/tool/JSONValue.java
new file mode 100644
index 00000000000..27c63116c88
--- /dev/null
+++ b/test/jdk/jdk/jfr/tool/JSONValue.java
@@ -0,0 +1,551 @@
+/*
+ * 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.jfr.tool;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+public interface JSONValue {
+
+    public final class JSONObject implements JSONValue {
+        private final Map value;
+
+        public JSONObject(Map value) {
+            this.value = value;
+        }
+
+        @Override
+        public JSONObject asObject() {
+            return this;
+        }
+
+        public JSONValue get(String k) {
+            return value.get(k);
+        }
+
+        @Override
+        public int size() {
+            return value.size();
+        }
+
+        @Override
+        public String toString() {
+            var builder = new StringBuilder();
+            builder.append("{");
+            for (var key : value.keySet()) {
+                builder.append("\"");
+                builder.append(key);
+                builder.append("\":");
+                builder.append(value.get(key).toString());
+                builder.append(",");
+            }
+
+            var end = builder.length() - 1;
+            if (builder.charAt(end) == ',') {
+                builder.deleteCharAt(end);
+            }
+
+            builder.append("}");
+            return builder.toString();
+        }
+    }
+
+    public final class JSONString implements JSONValue {
+        private final String value;
+
+        public JSONString(String value) {
+            this.value = value;
+        }
+
+        @Override
+        public String asString() {
+            return value;
+        }
+
+        @Override
+        public String toString() {
+            if (value == null) {
+                return "null";
+            }
+            var builder = new StringBuilder();
+            builder.append("\"");
+
+            for (var i = 0; i < value.length(); i++) {
+                var c = value.charAt(i);
+
+                switch (c) {
+                    case '"':
+                        builder.append("\\\"");
+                        break;
+                    case '\\':
+                        builder.append("\\\\");
+                        break;
+                    case '/':
+                        builder.append("\\/");
+                        break;
+                    case '\b':
+                        builder.append("\\b");
+                        break;
+                    case '\f':
+                        builder.append("\\f");
+                        break;
+                    case '\n':
+                        builder.append("\\n");
+                        break;
+                    case '\r':
+                        builder.append("\\r");
+                        break;
+                    case '\t':
+                        builder.append("\\t");
+                        break;
+                    default:
+                        builder.append(c);
+                        break;
+                }
+            }
+
+            builder.append("\"");
+            return builder.toString();
+        }
+    }
+
+    public final class JSONArray implements JSONValue, Iterable {
+        private final List values;
+
+        public JSONArray(List array) {
+            this.values = array;
+        }
+
+        @Override
+        public JSONArray asArray() {
+            return this;
+        }
+
+        public JSONValue get(int i) {
+            return values.get(i);
+        }
+
+        public int size() {
+            return values.size();
+        }
+
+        @Override
+        public String toString() {
+            var builder = new StringBuilder();
+
+            builder.append("[");
+            for (var i = 0; i < size(); i++) {
+                builder.append(get(i).toString());
+                if (i != (size() - 1)) {
+                    builder.append(",");
+                }
+            }
+            builder.append("]");
+            return builder.toString();
+        }
+
+        @Override
+        public Iterator iterator() {
+            return values.iterator();
+        }
+    }
+
+    class JSONParser {
+        private int pos = 0;
+        private String input;
+
+        JSONParser() {
+        }
+
+        private IllegalStateException failure(String message) {
+            return new IllegalStateException(String.format("[%d]: %s : %s", pos, message, input));
+        }
+
+        private char current() {
+            return input.charAt(pos);
+        }
+
+        private void advance() {
+            pos++;
+        }
+
+        private boolean hasInput() {
+            return pos < input.length();
+        }
+
+        private void expectMoreInput(String message) {
+            if (!hasInput()) {
+                throw failure(message);
+            }
+        }
+
+        private char next(String message) {
+            advance();
+            if (!hasInput()) {
+                throw failure(message);
+            }
+            return current();
+        }
+
+        private void expect(char c) {
+            var msg = String.format("Expected character %c", c);
+
+            var n = next(msg);
+            if (n != c) {
+                throw failure(msg);
+            }
+        }
+
+        private JSONString parseBoolean() {
+            if (current() == 't') {
+                expect('r');
+                expect('u');
+                expect('e');
+                advance();
+                return new JSONString("true");
+            }
+
+            if (current() == 'f') {
+                expect('a');
+                expect('l');
+                expect('s');
+                expect('e');
+                advance();
+                return new JSONString("false");
+            }
+            throw failure("a boolean can only be 'true' or 'false'");
+        }
+
+        private JSONValue parseNumber() {
+            var isInteger = true;
+            var builder = new StringBuilder();
+
+            if (current() == '-') {
+                builder.append(current());
+                advance();
+                expectMoreInput("a number cannot consist of only '-'");
+            }
+
+            if (current() == '0') {
+                builder.append(current());
+                advance();
+
+                if (hasInput() && current() == '.') {
+                    isInteger = false;
+                    builder.append(current());
+                    advance();
+
+                    expectMoreInput("a number cannot end with '.'");
+
+                    if (!isDigit(current())) {
+                        throw failure("must be at least one digit after '.'");
+                    }
+
+                    while (hasInput() && isDigit(current())) {
+                        builder.append(current());
+                        advance();
+                    }
+                }
+            } else {
+                while (hasInput() && isDigit(current())) {
+                    builder.append(current());
+                    advance();
+                }
+
+                if (hasInput() && current() == '.') {
+                    isInteger = false;
+                    builder.append(current());
+                    advance();
+
+                    expectMoreInput("a number cannot end with '.'");
+
+                    if (!isDigit(current())) {
+                        throw failure("must be at least one digit after '.'");
+                    }
+
+                    while (hasInput() && isDigit(current())) {
+                        builder.append(current());
+                        advance();
+                    }
+                }
+            }
+
+            if (hasInput() && (current() == 'e' || current() == 'E')) {
+                isInteger = false;
+
+                builder.append(current());
+                advance();
+                expectMoreInput("a number cannot end with 'e' or 'E'");
+
+                if (current() == '+' || current() == '-') {
+                    builder.append(current());
+                    advance();
+                }
+
+                if (!isDigit(current())) {
+                    throw failure("a digit must follow {'e','E'}{'+','-'}");
+                }
+
+                while (hasInput() && isDigit(current())) {
+                    builder.append(current());
+                    advance();
+                }
+            }
+
+            var value = builder.toString();
+            if (isInteger) {
+                Long.parseLong(value);
+                return new JSONString(value);
+            } else {
+                Double.parseDouble(value);
+                return new JSONString(value);
+            }
+        }
+
+        private JSONString parseString() {
+            var missingEndChar = "string is not terminated with '\"'";
+            var builder = new StringBuilder();
+            for (var c = next(missingEndChar); c != '"'; c = next(missingEndChar)) {
+                if (c == '\\') {
+                    var n = next(missingEndChar);
+                    switch (n) {
+                        case '"':
+                            builder.append("\"");
+                            break;
+                        case '\\':
+                            builder.append("\\");
+                            break;
+                        case '/':
+                            builder.append("/");
+                            break;
+                        case 'b':
+                            builder.append("\b");
+                            break;
+                        case 'f':
+                            builder.append("\f");
+                            break;
+                        case 'n':
+                            builder.append("\n");
+                            break;
+                        case 'r':
+                            builder.append("\r");
+                            break;
+                        case 't':
+                            builder.append("\t");
+                            break;
+                        case 'u':
+                            var u1 = next(missingEndChar);
+                            var u2 = next(missingEndChar);
+                            var u3 = next(missingEndChar);
+                            var u4 = next(missingEndChar);
+                            var cp = Integer.parseInt(String.format("%c%c%c%c", u1, u2, u3, u4), 16);
+                            builder.append(new String(new int[]{cp}, 0, 1));
+                            break;
+                        default:
+                            throw failure(String.format("Unexpected escaped character '%c'", n));
+                    }
+                } else {
+                    builder.append(c);
+                }
+            }
+
+            advance(); // step beyond closing "
+            return new JSONString(builder.toString());
+        }
+
+        private JSONArray parseArray() {
+            var error = "array is not terminated with ']'";
+            var list = new ArrayList();
+
+            advance(); // step beyond opening '['
+            consumeWhitespace();
+            expectMoreInput(error);
+
+            while (current() != ']') {
+                var val = parseValue();
+                list.add(val);
+
+                expectMoreInput(error);
+                if (current() == ',') {
+                    advance();
+                }
+                expectMoreInput(error);
+            }
+
+            advance(); // step beyond closing ']'
+            return new JSONArray(list);
+        }
+
+        public JSONString parseNull() {
+            expect('u');
+            expect('l');
+            expect('l');
+            advance();
+            return new JSONString(null);
+        }
+
+        public JSONObject parseObject() {
+            var error = "object is not terminated with '}'";
+            var map = new HashMap();
+
+            advance(); // step beyond opening '{'
+            consumeWhitespace();
+            expectMoreInput(error);
+
+            while (current() != '}') {
+                var key = parseValue();
+                if (!(key instanceof JSONString)) {
+                    throw failure("a field must of type string");
+                }
+
+                if (!hasInput() || current() != ':') {
+                    throw failure("a field must be followed by ':'");
+                }
+                advance(); // skip ':'
+
+                var val = parseValue();
+                map.put(key.asString(), val);
+
+                expectMoreInput(error);
+                if (current() == ',') {
+                    advance();
+                }
+                expectMoreInput(error);
+            }
+
+            advance(); // step beyond '}'
+            return new JSONObject(map);
+        }
+
+        private boolean isDigit(char c) {
+            return c >= '0' && c <= '9';
+        }
+
+        private boolean isStartOfNumber(char c) {
+            return isDigit(c) || c == '-';
+        }
+
+        private boolean isStartOfString(char c) {
+            return c == '"';
+        }
+
+        private boolean isStartOfBoolean(char c) {
+            return c == 't' || c == 'f';
+        }
+
+        private boolean isStartOfArray(char c) {
+            return c == '[';
+        }
+
+        private boolean isStartOfNull(char c) {
+            return c == 'n';
+        }
+
+        private boolean isWhitespace(char c) {
+            return c == '\r' ||
+                   c == '\n' ||
+                   c == '\t' ||
+                   c == ' ';
+        }
+
+        private boolean isStartOfObject(char c) {
+            return c == '{';
+        }
+
+        private void consumeWhitespace() {
+            while (hasInput() && isWhitespace(current())) {
+                advance();
+            }
+        }
+
+        public JSONValue parseValue() {
+            JSONValue ret = null;
+
+            consumeWhitespace();
+            if (hasInput()) {
+                var c = current();
+
+                if (isStartOfNumber(c)) {
+                    ret = parseNumber();
+                } else if (isStartOfString(c)) {
+                    ret = parseString();
+                } else if (isStartOfBoolean(c)) {
+                    ret = parseBoolean();
+                } else if (isStartOfArray(c)) {
+                    ret = parseArray();
+                } else if (isStartOfNull(c)) {
+                    ret = parseNull();
+                } else if (isStartOfObject(c)) {
+                    ret = parseObject();
+                } else {
+                    throw failure("not a valid start of a JSON value");
+                }
+            }
+            consumeWhitespace();
+
+            return ret;
+        }
+
+        public JSONValue parse(String s) {
+            if (s == null || s.equals("")) {
+                return null;
+            }
+
+            pos = 0;
+            input = s;
+
+            var result = parseValue();
+            if (hasInput()) {
+                throw failure("can only have one top-level JSON value");
+            }
+            return result;
+        }
+    }
+
+    public static JSONValue parse(String s) {
+        return new JSONParser().parse(s);
+    }
+
+    default int size() {
+        throw new IllegalStateException("Size operation unsupported");
+    }
+
+    default String asString() {
+        throw new IllegalStateException("Unsupported conversion to String");
+    }
+
+    default JSONArray asArray() {
+        throw new IllegalStateException("Unsupported conversion to array");
+    }
+
+    default JSONObject asObject() {
+        throw new IllegalStateException("Unsupported conversion to object");
+    }
+
+    default JSONValue get(String field) {
+        return asObject().get(field);
+    }
+}
diff --git a/test/jdk/jdk/jfr/tool/TestPrintJSON.java b/test/jdk/jdk/jfr/tool/TestPrintJSON.java
index 71337904c98..2e63a99d327 100644
--- a/test/jdk/jdk/jfr/tool/TestPrintJSON.java
+++ b/test/jdk/jdk/jfr/tool/TestPrintJSON.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
@@ -31,16 +31,13 @@ import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 
-import javax.script.ScriptEngine;
-import javax.script.ScriptEngineManager;
-
 import jdk.jfr.Timespan;
 import jdk.jfr.Timestamp;
 import jdk.jfr.ValueDescriptor;
 import jdk.jfr.consumer.RecordedEvent;
 import jdk.jfr.consumer.RecordedObject;
 import jdk.jfr.consumer.RecordingFile;
-import jdk.nashorn.api.scripting.JSObject;
+import jdk.jfr.tool.JSONValue.JSONArray;
 import jdk.test.lib.Asserts;
 import jdk.test.lib.process.OutputAnalyzer;
 
@@ -51,8 +48,7 @@ import jdk.test.lib.process.OutputAnalyzer;
  * @requires vm.hasJFR
  *
  * @library /test/lib /test/jdk
- * @modules jdk.scripting.nashorn
- *          jdk.jfr
+ * @modules jdk.jfr
  *
  * @run main/othervm jdk.jfr.tool.TestPrintJSON
  */
@@ -65,42 +61,36 @@ public class TestPrintJSON {
         OutputAnalyzer output = ExecuteHelper.jfr("print", "--json", "--stack-depth", "999", recordingFile.toString());
         String json = output.getStdout();
 
-        // Parse JSON using Nashorn
-        String statement = "var jsonObject = " + json;
-        ScriptEngineManager factory = new ScriptEngineManager();
-        ScriptEngine engine = factory.getEngineByName("nashorn");
-        engine.eval(statement);
-        JSObject o = (JSObject) engine.get("jsonObject");
-        JSObject recording = (JSObject) o.getMember("recording");
-        JSObject jsonEvents = (JSObject) recording.getMember("events");
-
+        JSONValue o = JSONValue.parse(json);
+        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()));
         // Verify events are equal
         Iterator it = events.iterator();
-
-        for (Object jsonEvent : jsonEvents.values()) {
+        for (JSONValue jsonEvent : jsonEvents) {
             RecordedEvent recordedEvent = it.next();
             String typeName = recordedEvent.getEventType().getName();
-            Asserts.assertEquals(typeName, ((JSObject) jsonEvent).getMember("type").toString());
+            Asserts.assertEquals(typeName,  jsonEvent.get("type").asString());
             assertEquals(jsonEvent, recordedEvent);
         }
-        Asserts.assertFalse(events.size() != jsonEvents.values().size(), "Incorrect number of events");
+        Asserts.assertFalse(events.size() != jsonEvents.size(), "Incorrect number of events");
     }
 
     private static void assertEquals(Object jsonObject, Object jfrObject) throws Exception {
         // Check object
         if (jfrObject instanceof RecordedObject) {
-            JSObject values = (JSObject) ((JSObject) jsonObject).getMember("values");
+            JSONValue values = ((JSONValue)jsonObject).get("values");
             RecordedObject recObject = (RecordedObject) jfrObject;
-            Asserts.assertEquals(values.values().size(), recObject.getFields().size());
+            Asserts.assertEquals(values.size(), recObject.getFields().size());
             for (ValueDescriptor v : recObject.getFields()) {
                 String name = v.getName();
-                Object jsonValue = values.getMember(name);
+                Object jsonValue = values.get(name);
                 Object expectedValue = recObject.getValue(name);
                 if (v.getAnnotation(Timestamp.class) != null) {
                     // Make instant of OffsetDateTime
-                    jsonValue = OffsetDateTime.parse("" + jsonValue).toInstant().toString();
+                    String text = ((JSONValue)jsonValue).asString();
+                    jsonValue = OffsetDateTime.parse(text).toInstant().toString();
                     expectedValue = recObject.getInstant(name);
                 }
                 if (v.getAnnotation(Timespan.class) != null) {
@@ -113,9 +103,9 @@ public class TestPrintJSON {
         // Check array
         if (jfrObject != null && jfrObject.getClass().isArray()) {
             Object[] jfrArray = (Object[]) jfrObject;
-            JSObject jsArray = (JSObject) jsonObject;
+            JSONArray jsArray = ((JSONArray)jsonObject);
             for (int i = 0; i < jfrArray.length; i++) {
-                assertEquals(jsArray.getSlot(i), jfrArray[i]);
+                assertEquals(jsArray.get(i), jfrArray[i]);
             }
             return;
         }

From 398a2b3c37236c0cd1b5258b517adf9edaf0b044 Mon Sep 17 00:00:00 2001
From: Patricio Chilano Mateo 
Date: Wed, 13 May 2020 15:47:10 +0000
Subject: [PATCH 041/143] 8231264: Implementation of JEP 374: Disable
 biased-locking and deprecate all flags related to biased-locking

Changed default value of UseBiasedLocking to false and deprecated related flags.

Reviewed-by: dholmes, dcubed
---
 src/hotspot/share/opto/c2_globals.hpp         |  5 +--
 src/hotspot/share/runtime/arguments.cpp       |  8 +++++
 src/hotspot/share/runtime/globals.hpp         | 22 +++++++------
 test/hotspot/gtest/oops/test_markWord.cpp     | 32 +++++++++----------
 .../CommandLine/VMDeprecatedOptions.java      |  6 ++++
 5 files changed, 44 insertions(+), 29 deletions(-)

diff --git a/src/hotspot/share/opto/c2_globals.hpp b/src/hotspot/share/opto/c2_globals.hpp
index 03fdae2b8ad..26173716ad4 100644
--- a/src/hotspot/share/opto/c2_globals.hpp
+++ b/src/hotspot/share/opto/c2_globals.hpp
@@ -497,7 +497,8 @@
           "Print precise statistics on the dynamic lock usage")             \
                                                                             \
   diagnostic(bool, PrintPreciseBiasedLockingStatistics, false,              \
-          "Print per-lock-site statistics of biased locking in JVM")        \
+          "(Deprecated) Print per-lock-site statistics of biased locking "  \
+          "in JVM")                                                         \
                                                                             \
   diagnostic(bool, PrintPreciseRTMLockingStatistics, false,                 \
           "Print per-lock-site statistics of rtm locking in JVM")           \
@@ -551,7 +552,7 @@
           "Verify Connection Graph construction in Escape Analysis")        \
                                                                             \
   product(bool, UseOptoBiasInlining, true,                                  \
-          "Generate biased locking code in C2 ideal graph")                 \
+          "(Deprecated) Generate biased locking code in C2 ideal graph")    \
                                                                             \
   product(bool, OptimizeStringConcat, true,                                 \
           "Optimize the construction of Strings by StringBuilder")          \
diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp
index fd8f9b3388a..a14276119dd 100644
--- a/src/hotspot/share/runtime/arguments.cpp
+++ b/src/hotspot/share/runtime/arguments.cpp
@@ -525,6 +525,14 @@ static SpecialFlag const special_jvm_flags[] = {
   { "PrintVMQWaitTime",             JDK_Version::jdk(15), JDK_Version::jdk(16), JDK_Version::jdk(17) },
   { "UseNewFieldLayout",            JDK_Version::jdk(15), JDK_Version::jdk(16), JDK_Version::jdk(17) },
   { "ForceNUMA",                    JDK_Version::jdk(15), JDK_Version::jdk(16), JDK_Version::jdk(17) },
+  { "UseBiasedLocking",             JDK_Version::jdk(15), JDK_Version::jdk(16), JDK_Version::jdk(17) },
+  { "BiasedLockingStartupDelay",    JDK_Version::jdk(15), JDK_Version::jdk(16), JDK_Version::jdk(17) },
+  { "PrintBiasedLockingStatistics", JDK_Version::jdk(15), JDK_Version::jdk(16), JDK_Version::jdk(17) },
+  { "BiasedLockingBulkRebiasThreshold",    JDK_Version::jdk(15), JDK_Version::jdk(16), JDK_Version::jdk(17) },
+  { "BiasedLockingBulkRevokeThreshold",    JDK_Version::jdk(15), JDK_Version::jdk(16), JDK_Version::jdk(17) },
+  { "BiasedLockingDecayTime",              JDK_Version::jdk(15), JDK_Version::jdk(16), JDK_Version::jdk(17) },
+  { "UseOptoBiasInlining",                 JDK_Version::jdk(15), JDK_Version::jdk(16), JDK_Version::jdk(17) },
+  { "PrintPreciseBiasedLockingStatistics", JDK_Version::jdk(15), JDK_Version::jdk(16), JDK_Version::jdk(17) },
 
   // --- Deprecated alias flags (see also aliased_jvm_flags) - sorted by obsolete_in then expired_in:
   { "DefaultMaxRAMFraction",        JDK_Version::jdk(8),  JDK_Version::undefined(), JDK_Version::undefined() },
diff --git a/src/hotspot/share/runtime/globals.hpp b/src/hotspot/share/runtime/globals.hpp
index aa9b2dc830c..c18368bd9c4 100644
--- a/src/hotspot/share/runtime/globals.hpp
+++ b/src/hotspot/share/runtime/globals.hpp
@@ -777,32 +777,34 @@ const size_t minimumSymbolTableSize = 1024;
   product(bool, RestrictContended, true,                                    \
           "Restrict @Contended to trusted classes")                         \
                                                                             \
-  product(bool, UseBiasedLocking, true,                                     \
-          "Enable biased locking in JVM")                                   \
+  product(bool, UseBiasedLocking, false,                                    \
+          "(Deprecated) Enable biased locking in JVM")                      \
                                                                             \
   product(intx, BiasedLockingStartupDelay, 0,                               \
-          "Number of milliseconds to wait before enabling biased locking")  \
+          "(Deprecated) Number of milliseconds to wait before enabling "    \
+          "biased locking")                                                 \
           range(0, (intx)(max_jint-(max_jint%PeriodicTask::interval_gran))) \
           constraint(BiasedLockingStartupDelayFunc,AfterErgo)               \
                                                                             \
   diagnostic(bool, PrintBiasedLockingStatistics, false,                     \
-          "Print statistics of biased locking in JVM")                      \
+          "(Deprecated) Print statistics of biased locking in JVM")         \
                                                                             \
   product(intx, BiasedLockingBulkRebiasThreshold, 20,                       \
-          "Threshold of number of revocations per type to try to "          \
-          "rebias all objects in the heap of that type")                    \
+          "(Deprecated) Threshold of number of revocations per type to "    \
+          "try to rebias all objects in the heap of that type")             \
           range(0, max_intx)                                                \
           constraint(BiasedLockingBulkRebiasThresholdFunc,AfterErgo)        \
                                                                             \
   product(intx, BiasedLockingBulkRevokeThreshold, 40,                       \
-          "Threshold of number of revocations per type to permanently "     \
-          "revoke biases of all objects in the heap of that type")          \
+          "(Deprecated) Threshold of number of revocations per type to "    \
+          "permanently revoke biases of all objects in the heap of that "   \
+          "type")                                                           \
           range(0, max_intx)                                                \
           constraint(BiasedLockingBulkRevokeThresholdFunc,AfterErgo)        \
                                                                             \
   product(intx, BiasedLockingDecayTime, 25000,                              \
-          "Decay time (in milliseconds) to re-enable bulk rebiasing of a "  \
-          "type after previous bulk rebias")                                \
+          "(Deprecated) Decay time (in milliseconds) to re-enable bulk "    \
+          "rebiasing of a type after previous bulk rebias")                 \
           range(500, max_intx)                                              \
           constraint(BiasedLockingDecayTimeFunc,AfterErgo)                  \
                                                                             \
diff --git a/test/hotspot/gtest/oops/test_markWord.cpp b/test/hotspot/gtest/oops/test_markWord.cpp
index 7b5b1f919d6..95a150af0fd 100644
--- a/test/hotspot/gtest/oops/test_markWord.cpp
+++ b/test/hotspot/gtest/oops/test_markWord.cpp
@@ -85,11 +85,6 @@ TEST_VM(markWord, printing) {
   ThreadInVMfromNative invm(THREAD);
   ResourceMark rm(THREAD);
 
-  if (!UseBiasedLocking || !BiasedLocking::enabled()) {
-    // Can't test this with biased locking disabled.
-    return;
-  }
-
   oop obj = SystemDictionary::Byte_klass()->allocate_instance(THREAD);
 
   FlagSetting fs(WizardMode, true);
@@ -97,22 +92,25 @@ TEST_VM(markWord, printing) {
   HandleMark hm(THREAD);
   Handle h_obj(THREAD, obj);
 
-  // Biased locking is initially enabled for this java.lang.Byte object.
-  assert_test_pattern(h_obj, "is_biased");
+  if (UseBiasedLocking && BiasedLocking::enabled()) {
+    // Can't test this with biased locking disabled.
+    // Biased locking is initially enabled for this java.lang.Byte object.
+    assert_test_pattern(h_obj, "is_biased");
 
-  // Lock using biased locking.
-  BasicObjectLock lock;
-  lock.set_obj(obj);
-  markWord prototype_header = obj->klass()->prototype_header();
-  markWord mark = obj->mark();
-  markWord biased_mark = markWord::encode((JavaThread*) THREAD, mark.age(), prototype_header.bias_epoch());
-  obj->set_mark(biased_mark);
-  // Look for the biased_locker in markWord, not prototype_header.
+    // Lock using biased locking.
+    BasicObjectLock lock;
+    lock.set_obj(obj);
+    markWord prototype_header = obj->klass()->prototype_header();
+    markWord mark = obj->mark();
+    markWord biased_mark = markWord::encode((JavaThread*) THREAD, mark.age(), prototype_header.bias_epoch());
+    obj->set_mark(biased_mark);
+    // Look for the biased_locker in markWord, not prototype_header.
 #ifdef _LP64
-  assert_not_test_pattern(h_obj, "mark(is_biased biased_locker=0x0000000000000000");
+    assert_not_test_pattern(h_obj, "mark(is_biased biased_locker=0x0000000000000000");
 #else
-  assert_not_test_pattern(h_obj, "mark(is_biased biased_locker=0x00000000");
+    assert_not_test_pattern(h_obj, "mark(is_biased biased_locker=0x00000000");
 #endif
+  }
 
   // Same thread tries to lock it again.
   {
diff --git a/test/hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java b/test/hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java
index d6fb588b042..1cba9d545f4 100644
--- a/test/hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java
+++ b/test/hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java
@@ -49,6 +49,12 @@ public class VMDeprecatedOptions {
         {"AllowRedefinitionToAddDeleteMethods", "true"},
         {"PrintVMQWaitTime",          "true"},
         {"UseNewFieldLayout",         "true"},
+        {"UseBiasedLocking",                    "false"},
+        {"BiasedLockingStartupDelay",           "0"},
+        {"BiasedLockingBulkRebiasThreshold",    "20"},
+        {"BiasedLockingBulkRevokeThreshold",    "40"},
+        {"BiasedLockingDecayTime",              "25000"},
+        {"UseOptoBiasInlining",                 "true"},
 
         // deprecated alias flags (see also aliased_jvm_flags):
         {"DefaultMaxRAMFraction", "4"},

From 658fb7ac3e0670ecf6d394cc37ed372e122624f2 Mon Sep 17 00:00:00 2001
From: Bob Vandette 
Date: Wed, 13 May 2020 11:33:52 -0400
Subject: [PATCH 042/143] 8244852: GraalVM native-image fails after JDK-8238048
 change

Reviewed-by: dholmes
---
 .../src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java    | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java
index e9ab1d780c5..3191918d48b 100644
--- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java
+++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java
@@ -818,7 +818,7 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem
     @Override
     public String getSourceFileName() {
         if (isArray()) {
-            throw new JVMCIError("Cannot call getSourceFileName() on an array klass type: %s", this);
+            return null;
         }
         return getConstantPool().getSourceFileName();
     }

From 3d50f242c2172c05b74e533962195bc8d9ea2997 Mon Sep 17 00:00:00 2001
From: Bob Vandette 
Date: Wed, 13 May 2020 11:35:48 -0400
Subject: [PATCH 043/143] 8244853: The static build of libextnet is missing the
 JNI_OnLoad_extnet function

Reviewed-by: alanb
---
 src/jdk.net/linux/native/libextnet/LinuxSocketOptions.c     | 5 +++++
 src/jdk.net/macosx/native/libextnet/MacOSXSocketOptions.c   | 5 +++++
 src/jdk.net/solaris/native/libextnet/SolarisSocketOptions.c | 5 +++++
 3 files changed, 15 insertions(+)

diff --git a/src/jdk.net/linux/native/libextnet/LinuxSocketOptions.c b/src/jdk.net/linux/native/libextnet/LinuxSocketOptions.c
index 241133c813f..2b4126e1a95 100644
--- a/src/jdk.net/linux/native/libextnet/LinuxSocketOptions.c
+++ b/src/jdk.net/linux/native/libextnet/LinuxSocketOptions.c
@@ -33,6 +33,11 @@
 #include "jni_util.h"
 #include "jdk_net_LinuxSocketOptions.h"
 
+/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
 /*
  * Class:     jdk_net_LinuxSocketOptions
  * Method:    setQuickAck
diff --git a/src/jdk.net/macosx/native/libextnet/MacOSXSocketOptions.c b/src/jdk.net/macosx/native/libextnet/MacOSXSocketOptions.c
index 4844f8dd2e2..c16dab1a1c7 100644
--- a/src/jdk.net/macosx/native/libextnet/MacOSXSocketOptions.c
+++ b/src/jdk.net/macosx/native/libextnet/MacOSXSocketOptions.c
@@ -32,6 +32,11 @@
 #include 
 #include "jni_util.h"
 
+/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
 static jint socketOptionSupported(jint sockopt) {
     jint one = 1;
     jint rv, s;
diff --git a/src/jdk.net/solaris/native/libextnet/SolarisSocketOptions.c b/src/jdk.net/solaris/native/libextnet/SolarisSocketOptions.c
index 96d6ed96088..51f07a5629c 100644
--- a/src/jdk.net/solaris/native/libextnet/SolarisSocketOptions.c
+++ b/src/jdk.net/solaris/native/libextnet/SolarisSocketOptions.c
@@ -31,6 +31,11 @@ static jfieldID sf_bandwidth;
 
 static int initialized = 0;
 
+/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
 /*
  * Class:     jdk_net_SolarisSocketOptions
  * Method:    init

From 49bfbd3bc719e8988127420d36785e80c724e4f2 Mon Sep 17 00:00:00 2001
From: Jonathan Gibbons 
Date: Wed, 13 May 2020 10:39:35 -0700
Subject: [PATCH 044/143] 8243417: Clean up
 com.sun.tools.javac.main.CommandLine

Reviewed-by: prappo
---
 .../com/sun/tools/javac/main/Arguments.java   |  4 +--
 .../com/sun/tools/javac/main/CommandLine.java | 27 +++----------------
 .../com/sun/tools/javac/main/Main.java        |  5 ++--
 .../tools/sjavac/options/OptionHelper.java    |  5 ++--
 .../jdk/javadoc/internal/tool/Start.java      |  5 ++--
 .../tools/javac/main/EnvVariableTest.java     | 11 +++++---
 6 files changed, 21 insertions(+), 36 deletions(-)

diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Arguments.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Arguments.java
index 3802cb909f7..dbd82e34ab4 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Arguments.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Arguments.java
@@ -183,14 +183,14 @@ public class Arguments {
      * @param ownName the name of this tool; used to prefix messages
      * @param args the args to be processed
      */
-    public void init(String ownName, String... args) {
+    public void init(String ownName, Iterable args) {
         this.ownName = ownName;
         errorMode = ErrorMode.LOG;
         files = new LinkedHashSet<>();
         deferredFileManagerOptions = new LinkedHashMap<>();
         fileObjects = null;
         classNames = new LinkedHashSet<>();
-        processArgs(List.from(args), Option.getJavaCompilerOptions(), cmdLineHelper, true, false);
+        processArgs(args, Option.getJavaCompilerOptions(), cmdLineHelper, true, false);
         if (errors) {
             log.printLines(PrefixKind.JAVAC, "msg.usage", ownName);
         }
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/CommandLine.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/CommandLine.java
index de8d0376106..ec6f711f9bc 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/CommandLine.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/CommandLine.java
@@ -56,10 +56,10 @@ public class CommandLine {
      * @return the arguments, with @files expanded
      * @throws IOException if there is a problem reading any of the @files
      */
-    public static String[] parse(String[] args) throws IOException {
+    public static List parse(List args) throws IOException {
         List newArgs = new ArrayList<>();
-        appendParsedCommandArgs(newArgs, Arrays.asList(args));
-        return newArgs.toArray(new String[newArgs.size()]);
+        appendParsedCommandArgs(newArgs, args);
+        return newArgs;
     }
 
     private static void appendParsedCommandArgs(List newArgs, List args) throws IOException {
@@ -104,27 +104,6 @@ public class CommandLine {
         return newArgs;
     }
 
-    /**
-     * Process the given environment variable and appends any Win32-style
-     * command files for the specified command line arguments and return
-     * the resulting arguments. A command file argument
-     * is of the form '@file' where 'file' is the name of the file whose
-     * contents are to be parsed for additional arguments. The contents of
-     * the command file are parsed using StreamTokenizer and the original
-     * '@file' argument replaced with the resulting tokens. Recursive command
-     * files are not supported. The '@' character itself can be quoted with
-     * the sequence '@@'.
-     * @param envVariable the env variable to process
-     * @param args the arguments that may contain @files
-     * @return the arguments, with environment variable's content and expansion of @files
-     * @throws IOException if there is a problem reading any of the @files
-     * @throws com.sun.tools.javac.main.CommandLine.UnmatchedQuote
-     */
-    public static String[] parse(String envVariable, String[] args) throws IOException, UnmatchedQuote {
-        List out = parse(envVariable, Arrays.asList(args));
-        return out.toArray(new String[out.size()]);
-    }
-
     private static void loadCmdFile(String name, List args) throws IOException {
         try (Reader r = Files.newBufferedReader(Paths.get(name), Charset.defaultCharset())) {
             Tokenizer t = new Tokenizer(r);
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java
index 4f5a2a4f113..d437678eeb5 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java
@@ -217,8 +217,9 @@ public class Main {
         }
 
         // prefix argv with contents of environment variable and expand @-files
+        Iterable allArgs;
         try {
-            argv = CommandLine.parse(ENV_OPT_NAME, argv);
+            allArgs = CommandLine.parse(ENV_OPT_NAME, List.from(argv));
         } catch (UnmatchedQuote ex) {
             reportDiag(Errors.UnmatchedQuote(ex.variableName));
             return Result.CMDERR;
@@ -232,7 +233,7 @@ public class Main {
         }
 
         Arguments args = Arguments.instance(context);
-        args.init(ownName, argv);
+        args.init(ownName, allArgs);
 
         if (log.nerrors > 0)
             return Result.CMDERR;
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/OptionHelper.java b/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/OptionHelper.java
index 709bf835a5b..2d0e8790b15 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/OptionHelper.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/OptionHelper.java
@@ -117,12 +117,13 @@ public abstract class OptionHelper {
      * @param args the arguments to traverse.
      */
     void traverse(String[] args) {
+        Iterable allArgs;
         try {
-            args = CommandLine.parse(args); // Detect @file and load it as a command line.
+            allArgs = CommandLine.parse(List.of(args)); // Detect @file and load it as a command line.
         } catch (java.io.IOException e) {
             throw new IllegalArgumentException("Problem reading @"+e.getMessage());
         }
-        ArgumentIterator argIter = new ArgumentIterator(Arrays.asList(args));
+        ArgumentIterator argIter = new ArgumentIterator(allArgs);
 
         nextArg:
         while (argIter.hasNext()) {
diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java
index bb213615f1b..a23da6c6c0e 100644
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java
@@ -341,13 +341,14 @@ public class Start {
     @SuppressWarnings("deprecation")
     Result begin(String... argv) {
         // Preprocess @file arguments
+        List allArgs;
         try {
-            argv = CommandLine.parse(argv);
+            allArgs = CommandLine.parse(List.of(argv));
         } catch (IOException e) {
             error("main.cant.read", e.getMessage());
             return ERROR;
         }
-        return begin(Arrays.asList(argv), Collections.emptySet());
+        return begin(allArgs, Collections.emptySet());
     }
 
     // Called by the JSR 199 API
diff --git a/test/langtools/tools/javac/main/EnvVariableTest.java b/test/langtools/tools/javac/main/EnvVariableTest.java
index 0d44edcb72c..cba7f7f02be 100644
--- a/test/langtools/tools/javac/main/EnvVariableTest.java
+++ b/test/langtools/tools/javac/main/EnvVariableTest.java
@@ -35,6 +35,9 @@ import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.PrintStream;
 import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.stream.Collectors;
+import java.util.List;
 
 import toolbox.*;
 
@@ -135,14 +138,14 @@ public class EnvVariableTest extends TestRunner {
      * print the result.
      */
     public static class Tester {
-        private static final String[] EMPTY_ARRAY = new String[0];
+        private static final List EMPTY_LIST = List.of();
         static String arrayToString(String... args) {
-            return String.join(", ", args);
+            return List.of(args).stream().collect(Collectors.joining(", "));
         }
         public static void main(String... args) throws IOException {
             try {
-                String[] argv = CommandLine.parse("JDK_JAVAC_OPTIONS", EMPTY_ARRAY);
-                System.out.print(arrayToString(argv));
+                List argv = CommandLine.parse("JDK_JAVAC_OPTIONS", EMPTY_LIST);
+                System.out.print(argv.stream().collect(Collectors.joining(", ")));
             } catch (CommandLine.UnmatchedQuote ex) {
                 System.out.print("Exception: " + ex.variableName);
             }

From 92d1c4a61a03e918a32468592e9dadadecf6d9bb Mon Sep 17 00:00:00 2001
From: Ioi Lam 
Date: Wed, 13 May 2020 10:56:51 -0700
Subject: [PATCH 045/143] 8244775: Remove unnecessary dependency to
 jfrEvents.hpp

Reviewed-by: kbarrett, kvn
---
 src/hotspot/share/c1/c1_GraphBuilder.cpp      |  1 +
 src/hotspot/share/ci/ciEnv.cpp                |  1 +
 src/hotspot/share/compiler/compileBroker.cpp  |  1 +
 src/hotspot/share/compiler/compilerEvent.cpp  |  1 +
 src/hotspot/share/compiler/compilerEvent.hpp  |  6 +-
 src/hotspot/share/gc/g1/g1CollectedHeap.cpp   |  1 +
 .../share/gc/g1/g1GCParPhaseTimesTracker.hpp  | 56 +++++++++++++++++++
 src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp    |  1 +
 src/hotspot/share/gc/g1/g1GCPhaseTimes.hpp    | 25 ---------
 src/hotspot/share/gc/g1/g1RemSet.cpp          |  1 +
 src/hotspot/share/gc/g1/g1RootProcessor.cpp   |  3 +-
 src/hotspot/share/gc/g1/heapRegionManager.cpp |  1 +
 src/hotspot/share/jvmci/jvmciCompilerToVM.cpp |  1 +
 src/hotspot/share/opto/bytecodeInfo.cpp       |  1 +
 src/hotspot/share/opto/compile.cpp            | 36 +++++++++++-
 src/hotspot/share/opto/compile.hpp            | 33 +----------
 16 files changed, 110 insertions(+), 59 deletions(-)
 create mode 100644 src/hotspot/share/gc/g1/g1GCParPhaseTimesTracker.hpp

diff --git a/src/hotspot/share/c1/c1_GraphBuilder.cpp b/src/hotspot/share/c1/c1_GraphBuilder.cpp
index fad5a1fe856..b9bcf7dc4fe 100644
--- a/src/hotspot/share/c1/c1_GraphBuilder.cpp
+++ b/src/hotspot/share/c1/c1_GraphBuilder.cpp
@@ -37,6 +37,7 @@
 #include "compiler/compileBroker.hpp"
 #include "compiler/compilerEvent.hpp"
 #include "interpreter/bytecode.hpp"
+#include "jfr/jfrEvents.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/sharedRuntime.hpp"
diff --git a/src/hotspot/share/ci/ciEnv.cpp b/src/hotspot/share/ci/ciEnv.cpp
index 12e60fd4a65..ab15882e2d6 100644
--- a/src/hotspot/share/ci/ciEnv.cpp
+++ b/src/hotspot/share/ci/ciEnv.cpp
@@ -44,6 +44,7 @@
 #include "compiler/disassembler.hpp"
 #include "gc/shared/collectedHeap.inline.hpp"
 #include "interpreter/linkResolver.hpp"
+#include "jfr/jfrEvents.hpp"
 #include "logging/log.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/oopFactory.hpp"
diff --git a/src/hotspot/share/compiler/compileBroker.cpp b/src/hotspot/share/compiler/compileBroker.cpp
index 77cf75c59fc..bb6ee664942 100644
--- a/src/hotspot/share/compiler/compileBroker.cpp
+++ b/src/hotspot/share/compiler/compileBroker.cpp
@@ -37,6 +37,7 @@
 #include "compiler/compilerOracle.hpp"
 #include "compiler/directivesParser.hpp"
 #include "interpreter/linkResolver.hpp"
+#include "jfr/jfrEvents.hpp"
 #include "logging/log.hpp"
 #include "logging/logStream.hpp"
 #include "memory/allocation.inline.hpp"
diff --git a/src/hotspot/share/compiler/compilerEvent.cpp b/src/hotspot/share/compiler/compilerEvent.cpp
index b76d70c6da0..062eceba72a 100644
--- a/src/hotspot/share/compiler/compilerEvent.cpp
+++ b/src/hotspot/share/compiler/compilerEvent.cpp
@@ -25,6 +25,7 @@
 #include "ci/ciMethod.hpp"
 #include "compiler/compilerEvent.hpp"
 #include "jfr/jfr.hpp"
+#include "jfr/jfrEvents.hpp"
 #include "jfr/metadata/jfrSerializer.hpp"
 #include "runtime/semaphore.inline.hpp"
 #include "utilities/growableArray.hpp"
diff --git a/src/hotspot/share/compiler/compilerEvent.hpp b/src/hotspot/share/compiler/compilerEvent.hpp
index a9f5ede03c5..ae94d4cf185 100644
--- a/src/hotspot/share/compiler/compilerEvent.hpp
+++ b/src/hotspot/share/compiler/compilerEvent.hpp
@@ -26,7 +26,6 @@
 
 #include "jni.h"
 #include "compiler/compilerDefinitions.hpp"
-#include "jfr/jfrEvents.hpp"
 #include "memory/allocation.hpp"
 #include "utilities/macros.hpp"
 #include "utilities/ticks.hpp"
@@ -39,6 +38,11 @@ class ciMethod;
 template 
 class GrowableArray;
 class Method;
+class EventCompilation;
+class EventCompilationFailure;
+class EventCompilerInlining;
+class EventCompilerPhase;
+struct JfrStructCalleeMethod;
 
 class CompilerEvent : AllStatic {
  public:
diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp
index 45fc8ae046b..aac26cd340a 100644
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp
@@ -41,6 +41,7 @@
 #include "gc/g1/g1DirtyCardQueue.hpp"
 #include "gc/g1/g1EvacStats.inline.hpp"
 #include "gc/g1/g1FullCollector.hpp"
+#include "gc/g1/g1GCParPhaseTimesTracker.hpp"
 #include "gc/g1/g1GCPhaseTimes.hpp"
 #include "gc/g1/g1HeapSizingPolicy.hpp"
 #include "gc/g1/g1HeapTransition.hpp"
diff --git a/src/hotspot/share/gc/g1/g1GCParPhaseTimesTracker.hpp b/src/hotspot/share/gc/g1/g1GCParPhaseTimesTracker.hpp
new file mode 100644
index 00000000000..11a62b03825
--- /dev/null
+++ b/src/hotspot/share/gc/g1/g1GCParPhaseTimesTracker.hpp
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ *
+ */
+
+#ifndef SHARE_GC_G1_G1GCPARPHASETIMESTRACKER_HPP
+#define SHARE_GC_G1_G1GCPARPHASETIMESTRACKER_HPP
+
+#include "gc/g1/g1GCPhaseTimes.hpp"
+#include "jfr/jfrEvents.hpp"
+#include "utilities/ticks.hpp"
+
+class G1GCParPhaseTimesTracker : public CHeapObj {
+protected:
+  Ticks _start_time;
+  G1GCPhaseTimes::GCParPhases _phase;
+  G1GCPhaseTimes* _phase_times;
+  uint _worker_id;
+  EventGCPhaseParallel _event;
+  bool _must_record;
+
+public:
+  G1GCParPhaseTimesTracker(G1GCPhaseTimes* phase_times, G1GCPhaseTimes::GCParPhases phase, uint worker_id, bool must_record = true);
+  virtual ~G1GCParPhaseTimesTracker();
+};
+
+class G1EvacPhaseTimesTracker : public G1GCParPhaseTimesTracker {
+  Tickspan _total_time;
+  Tickspan _trim_time;
+
+  G1EvacPhaseWithTrimTimeTracker _trim_tracker;
+public:
+  G1EvacPhaseTimesTracker(G1GCPhaseTimes* phase_times, G1ParScanThreadState* pss, G1GCPhaseTimes::GCParPhases phase, uint worker_id);
+  virtual ~G1EvacPhaseTimesTracker();
+};
+
+#endif
diff --git a/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp b/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp
index feb9c033ca5..e8bda9c26fb 100644
--- a/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp
+++ b/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "gc/g1/g1CollectedHeap.inline.hpp"
+#include "gc/g1/g1GCParPhaseTimesTracker.hpp"
 #include "gc/g1/g1GCPhaseTimes.hpp"
 #include "gc/g1/g1HotCardCache.hpp"
 #include "gc/g1/g1ParScanThreadState.inline.hpp"
diff --git a/src/hotspot/share/gc/g1/g1GCPhaseTimes.hpp b/src/hotspot/share/gc/g1/g1GCPhaseTimes.hpp
index 98680d396f6..a83538a1071 100644
--- a/src/hotspot/share/gc/g1/g1GCPhaseTimes.hpp
+++ b/src/hotspot/share/gc/g1/g1GCPhaseTimes.hpp
@@ -27,7 +27,6 @@
 
 #include "gc/shared/referenceProcessorPhaseTimes.hpp"
 #include "gc/shared/weakProcessorPhaseTimes.hpp"
-#include "jfr/jfrEvents.hpp"
 #include "logging/logLevel.hpp"
 #include "memory/allocation.hpp"
 #include "utilities/macros.hpp"
@@ -457,28 +456,4 @@ public:
   void stop();
 };
 
-class G1GCParPhaseTimesTracker : public CHeapObj {
-protected:
-  Ticks _start_time;
-  G1GCPhaseTimes::GCParPhases _phase;
-  G1GCPhaseTimes* _phase_times;
-  uint _worker_id;
-  EventGCPhaseParallel _event;
-  bool _must_record;
-
-public:
-  G1GCParPhaseTimesTracker(G1GCPhaseTimes* phase_times, G1GCPhaseTimes::GCParPhases phase, uint worker_id, bool must_record = true);
-  virtual ~G1GCParPhaseTimesTracker();
-};
-
-class G1EvacPhaseTimesTracker : public G1GCParPhaseTimesTracker {
-  Tickspan _total_time;
-  Tickspan _trim_time;
-
-  G1EvacPhaseWithTrimTimeTracker _trim_tracker;
-public:
-  G1EvacPhaseTimesTracker(G1GCPhaseTimes* phase_times, G1ParScanThreadState* pss, G1GCPhaseTimes::GCParPhases phase, uint worker_id);
-  virtual ~G1EvacPhaseTimesTracker();
-};
-
 #endif // SHARE_GC_G1_G1GCPHASETIMES_HPP
diff --git a/src/hotspot/share/gc/g1/g1RemSet.cpp b/src/hotspot/share/gc/g1/g1RemSet.cpp
index cc2fbbe7295..5ad62d1d47a 100644
--- a/src/hotspot/share/gc/g1/g1RemSet.cpp
+++ b/src/hotspot/share/gc/g1/g1RemSet.cpp
@@ -31,6 +31,7 @@
 #include "gc/g1/g1ConcurrentRefine.hpp"
 #include "gc/g1/g1DirtyCardQueue.hpp"
 #include "gc/g1/g1FromCardCache.hpp"
+#include "gc/g1/g1GCParPhaseTimesTracker.hpp"
 #include "gc/g1/g1GCPhaseTimes.hpp"
 #include "gc/g1/g1HotCardCache.hpp"
 #include "gc/g1/g1OopClosures.inline.hpp"
diff --git a/src/hotspot/share/gc/g1/g1RootProcessor.cpp b/src/hotspot/share/gc/g1/g1RootProcessor.cpp
index b45c31871c9..05e79be3978 100644
--- a/src/hotspot/share/gc/g1/g1RootProcessor.cpp
+++ b/src/hotspot/share/gc/g1/g1RootProcessor.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
@@ -32,6 +32,7 @@
 #include "gc/g1/g1CodeBlobClosure.hpp"
 #include "gc/g1/g1CollectedHeap.inline.hpp"
 #include "gc/g1/g1CollectorState.hpp"
+#include "gc/g1/g1GCParPhaseTimesTracker.hpp"
 #include "gc/g1/g1GCPhaseTimes.hpp"
 #include "gc/g1/g1ParScanThreadState.inline.hpp"
 #include "gc/g1/g1Policy.hpp"
diff --git a/src/hotspot/share/gc/g1/heapRegionManager.cpp b/src/hotspot/share/gc/g1/heapRegionManager.cpp
index f37a51f2f18..fb71fee0507 100644
--- a/src/hotspot/share/gc/g1/heapRegionManager.cpp
+++ b/src/hotspot/share/gc/g1/heapRegionManager.cpp
@@ -31,6 +31,7 @@
 #include "gc/g1/heapRegionManager.inline.hpp"
 #include "gc/g1/heapRegionSet.inline.hpp"
 #include "gc/g1/heterogeneousHeapRegionManager.hpp"
+#include "jfr/jfrEvents.hpp"
 #include "logging/logStream.hpp"
 #include "memory/allocation.hpp"
 #include "runtime/atomic.hpp"
diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp
index 1f334a24914..01b09819999 100644
--- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp
+++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp
@@ -32,6 +32,7 @@
 #include "compiler/disassembler.hpp"
 #include "interpreter/linkResolver.hpp"
 #include "interpreter/bytecodeStream.hpp"
+#include "jfr/jfrEvents.hpp"
 #include "jvmci/jvmciCompilerToVM.hpp"
 #include "jvmci/jvmciCodeInstaller.hpp"
 #include "jvmci/jvmciRuntime.hpp"
diff --git a/src/hotspot/share/opto/bytecodeInfo.cpp b/src/hotspot/share/opto/bytecodeInfo.cpp
index a6d77a341d4..ea32a469d06 100644
--- a/src/hotspot/share/opto/bytecodeInfo.cpp
+++ b/src/hotspot/share/opto/bytecodeInfo.cpp
@@ -30,6 +30,7 @@
 #include "compiler/compilerEvent.hpp"
 #include "compiler/compileLog.hpp"
 #include "interpreter/linkResolver.hpp"
+#include "jfr/jfrEvents.hpp"
 #include "oops/objArrayKlass.hpp"
 #include "opto/callGenerator.hpp"
 #include "opto/parse.hpp"
diff --git a/src/hotspot/share/opto/compile.cpp b/src/hotspot/share/opto/compile.cpp
index b26a4d2b600..e5154270be5 100644
--- a/src/hotspot/share/opto/compile.cpp
+++ b/src/hotspot/share/opto/compile.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
@@ -35,6 +35,7 @@
 #include "compiler/oopMap.hpp"
 #include "gc/shared/barrierSet.hpp"
 #include "gc/shared/c2/barrierSetC2.hpp"
+#include "jfr/jfrEvents.hpp"
 #include "memory/resourceArea.hpp"
 #include "opto/addnode.hpp"
 #include "opto/block.hpp"
@@ -4562,6 +4563,39 @@ void Compile::sort_macro_nodes() {
   }
 }
 
+void Compile::print_method(CompilerPhaseType cpt, int level, int idx) {
+  EventCompilerPhase event;
+  if (event.should_commit()) {
+    CompilerEvent::PhaseEvent::post(event, C->_latest_stage_start_counter, cpt, C->_compile_id, level);
+  }
+
+#ifndef PRODUCT
+  if (should_print(level)) {
+    char output[1024];
+    if (idx != 0) {
+      jio_snprintf(output, sizeof(output), "%s:%d", CompilerPhaseTypeHelper::to_string(cpt), idx);
+    } else {
+      jio_snprintf(output, sizeof(output), "%s", CompilerPhaseTypeHelper::to_string(cpt));
+    }
+    _printer->print_method(output, level);
+  }
+#endif
+  C->_latest_stage_start_counter.stamp();
+}
+
+void Compile::end_method(int level) {
+  EventCompilerPhase event;
+  if (event.should_commit()) {
+    CompilerEvent::PhaseEvent::post(event, C->_latest_stage_start_counter, PHASE_END, C->_compile_id, level);
+  }
+
+#ifndef PRODUCT
+  if (_printer && _printer->should_print(level)) {
+    _printer->end_method();
+  }
+#endif
+}
+
 
 #ifndef PRODUCT
 IdealGraphPrinter* Compile::_debug_file_printer = NULL;
diff --git a/src/hotspot/share/opto/compile.hpp b/src/hotspot/share/opto/compile.hpp
index 5bdf9bb9a69..a922a905707 100644
--- a/src/hotspot/share/opto/compile.hpp
+++ b/src/hotspot/share/opto/compile.hpp
@@ -631,25 +631,7 @@ class Compile : public Phase {
 #endif
   }
 
-  void print_method(CompilerPhaseType cpt, int level = 1, int idx = 0) {
-    EventCompilerPhase event;
-    if (event.should_commit()) {
-      CompilerEvent::PhaseEvent::post(event, C->_latest_stage_start_counter, cpt, C->_compile_id, level);
-    }
-
-#ifndef PRODUCT
-    if (should_print(level)) {
-      char output[1024];
-      if (idx != 0) {
-        jio_snprintf(output, sizeof(output), "%s:%d", CompilerPhaseTypeHelper::to_string(cpt), idx);
-      } else {
-        jio_snprintf(output, sizeof(output), "%s", CompilerPhaseTypeHelper::to_string(cpt));
-      }
-      _printer->print_method(output, level);
-    }
-#endif
-    C->_latest_stage_start_counter.stamp();
-  }
+  void print_method(CompilerPhaseType cpt, int level = 1, int idx = 0);
 
 #ifndef PRODUCT
   void igv_print_method_to_file(const char* phase_name = "Debug", bool append = false);
@@ -658,18 +640,7 @@ class Compile : public Phase {
   static IdealGraphPrinter* debug_network_printer() { return _debug_network_printer; }
 #endif
 
-  void end_method(int level = 1) {
-    EventCompilerPhase event;
-    if (event.should_commit()) {
-      CompilerEvent::PhaseEvent::post(event, C->_latest_stage_start_counter, PHASE_END, C->_compile_id, level);
-    }
-
-#ifndef PRODUCT
-    if (_printer && _printer->should_print(level)) {
-      _printer->end_method();
-    }
-#endif
-  }
+  void end_method(int level = 1);
 
   int           macro_count()             const { return _macro_nodes->length(); }
   int           predicate_count()         const { return _predicate_opaqs->length();}

From ad2afe0bf41d7f78cf5d7ddea7a14ddba6ec2da7 Mon Sep 17 00:00:00 2001
From: Kelvin Nilsen 
Date: Wed, 13 May 2020 20:19:09 +0200
Subject: [PATCH 046/143] 8241062: Shenandoah: rich asserts trigger "empty
 statement" inspection

Reviewed-by: shade
---
 .../share/gc/shenandoah/shenandoahAsserts.hpp | 54 +++++++++----------
 1 file changed, 27 insertions(+), 27 deletions(-)

diff --git a/src/hotspot/share/gc/shenandoah/shenandoahAsserts.hpp b/src/hotspot/share/gc/shenandoah/shenandoahAsserts.hpp
index 14b50a07ddb..42d0e60bba3 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoahAsserts.hpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahAsserts.hpp
@@ -75,69 +75,69 @@ public:
 
 #ifdef ASSERT
 #define shenandoah_assert_in_heap(interior_loc, obj) \
-                    ShenandoahAsserts::assert_in_heap(interior_loc, obj, __FILE__, __LINE__);
+                    ShenandoahAsserts::assert_in_heap(interior_loc, obj, __FILE__, __LINE__)
 #define shenandoah_assert_in_correct_region(interior_loc, obj) \
-                    ShenandoahAsserts::assert_in_correct_region(interior_loc, obj, __FILE__, __LINE__);
+                    ShenandoahAsserts::assert_in_correct_region(interior_loc, obj, __FILE__, __LINE__)
 
 #define shenandoah_assert_correct_if(interior_loc, obj, condition) \
-  if (condition)    ShenandoahAsserts::assert_correct(interior_loc, obj, __FILE__, __LINE__);
+  if (condition)    ShenandoahAsserts::assert_correct(interior_loc, obj, __FILE__, __LINE__)
 #define shenandoah_assert_correct_except(interior_loc, obj, exception) \
-  if (!(exception)) ShenandoahAsserts::assert_correct(interior_loc, obj, __FILE__, __LINE__);
+  if (!(exception)) ShenandoahAsserts::assert_correct(interior_loc, obj, __FILE__, __LINE__)
 #define shenandoah_assert_correct(interior_loc, obj) \
-                    ShenandoahAsserts::assert_correct(interior_loc, obj, __FILE__, __LINE__);
+                    ShenandoahAsserts::assert_correct(interior_loc, obj, __FILE__, __LINE__)
 
 #define shenandoah_assert_forwarded_if(interior_loc, obj, condition) \
-  if (condition)    ShenandoahAsserts::assert_forwarded(interior_loc, obj, __FILE__, __LINE__);
+  if (condition)    ShenandoahAsserts::assert_forwarded(interior_loc, obj, __FILE__, __LINE__)
 #define shenandoah_assert_forwarded_except(interior_loc, obj, exception) \
-  if (!(exception)) ShenandoahAsserts::assert_forwarded(interior_loc, obj, __FILE__, __LINE__);
+  if (!(exception)) ShenandoahAsserts::assert_forwarded(interior_loc, obj, __FILE__, __LINE__)
 #define shenandoah_assert_forwarded(interior_loc, obj) \
-                    ShenandoahAsserts::assert_forwarded(interior_loc, obj, __FILE__, __LINE__);
+                    ShenandoahAsserts::assert_forwarded(interior_loc, obj, __FILE__, __LINE__)
 
 #define shenandoah_assert_not_forwarded_if(interior_loc, obj, condition) \
-  if (condition)    ShenandoahAsserts::assert_not_forwarded(interior_loc, obj, __FILE__, __LINE__);
+  if (condition)    ShenandoahAsserts::assert_not_forwarded(interior_loc, obj, __FILE__, __LINE__)
 #define shenandoah_assert_not_forwarded_except(interior_loc, obj, exception) \
-  if (!(exception)) ShenandoahAsserts::assert_not_forwarded(interior_loc, obj, __FILE__, __LINE__);
+  if (!(exception)) ShenandoahAsserts::assert_not_forwarded(interior_loc, obj, __FILE__, __LINE__)
 #define shenandoah_assert_not_forwarded(interior_loc, obj) \
-                    ShenandoahAsserts::assert_not_forwarded(interior_loc, obj, __FILE__, __LINE__);
+                    ShenandoahAsserts::assert_not_forwarded(interior_loc, obj, __FILE__, __LINE__)
 
 #define shenandoah_assert_marked_if(interior_loc, obj, condition) \
-  if (condition)    ShenandoahAsserts::assert_marked(interior_loc, obj, __FILE__, __LINE__);
+  if (condition)    ShenandoahAsserts::assert_marked(interior_loc, obj, __FILE__, __LINE__)
 #define shenandoah_assert_marked_except(interior_loc, obj, exception) \
-  if (!(exception)) ShenandoahAsserts::assert_marked(interior_loc, obj, __FILE__, __LINE__);
+  if (!(exception)) ShenandoahAsserts::assert_marked(interior_loc, obj, __FILE__, __LINE__)
 #define shenandoah_assert_marked(interior_loc, obj) \
-                    ShenandoahAsserts::assert_marked(interior_loc, obj, __FILE__, __LINE__);
+                    ShenandoahAsserts::assert_marked(interior_loc, obj, __FILE__, __LINE__)
 
 #define shenandoah_assert_in_cset_if(interior_loc, obj, condition) \
-  if (condition)    ShenandoahAsserts::assert_in_cset(interior_loc, obj, __FILE__, __LINE__);
+  if (condition)    ShenandoahAsserts::assert_in_cset(interior_loc, obj, __FILE__, __LINE__)
 #define shenandoah_assert_in_cset_except(interior_loc, obj, exception) \
-  if (!(exception)) ShenandoahAsserts::assert_in_cset(interior_loc, obj, __FILE__, __LINE__);
+  if (!(exception)) ShenandoahAsserts::assert_in_cset(interior_loc, obj, __FILE__, __LINE__)
 #define shenandoah_assert_in_cset(interior_loc, obj) \
-                    ShenandoahAsserts::assert_in_cset(interior_loc, obj, __FILE__, __LINE__);
+                    ShenandoahAsserts::assert_in_cset(interior_loc, obj, __FILE__, __LINE__)
 
 #define shenandoah_assert_not_in_cset_if(interior_loc, obj, condition) \
-  if (condition)    ShenandoahAsserts::assert_not_in_cset(interior_loc, obj, __FILE__, __LINE__);
+  if (condition)    ShenandoahAsserts::assert_not_in_cset(interior_loc, obj, __FILE__, __LINE__)
 #define shenandoah_assert_not_in_cset_except(interior_loc, obj, exception) \
-  if (!(exception)) ShenandoahAsserts::assert_not_in_cset(interior_loc, obj, __FILE__, __LINE__);
+  if (!(exception)) ShenandoahAsserts::assert_not_in_cset(interior_loc, obj, __FILE__, __LINE__)
 #define shenandoah_assert_not_in_cset(interior_loc, obj) \
-                    ShenandoahAsserts::assert_not_in_cset(interior_loc, obj, __FILE__, __LINE__);
+                    ShenandoahAsserts::assert_not_in_cset(interior_loc, obj, __FILE__, __LINE__)
 
 #define shenandoah_assert_not_in_cset_loc_if(interior_loc, condition) \
-  if (condition)    ShenandoahAsserts::assert_not_in_cset_loc(interior_loc, __FILE__, __LINE__);
+  if (condition)    ShenandoahAsserts::assert_not_in_cset_loc(interior_loc, __FILE__, __LINE__)
 #define shenandoah_assert_not_in_cset_loc_except(interior_loc, exception) \
-  if (!(exception)) ShenandoahAsserts::assert_not_in_cset_loc(interior_loc, __FILE__, __LINE__);
+  if (!(exception)) ShenandoahAsserts::assert_not_in_cset_loc(interior_loc, __FILE__, __LINE__)
 #define shenandoah_assert_not_in_cset_loc(interior_loc) \
-                    ShenandoahAsserts::assert_not_in_cset_loc(interior_loc, __FILE__, __LINE__);
+                    ShenandoahAsserts::assert_not_in_cset_loc(interior_loc, __FILE__, __LINE__)
 
 #define shenandoah_assert_rp_isalive_installed() \
-                    ShenandoahAsserts::assert_rp_isalive_installed(__FILE__, __LINE__);
+                    ShenandoahAsserts::assert_rp_isalive_installed(__FILE__, __LINE__)
 #define shenandoah_assert_rp_isalive_not_installed() \
-                    ShenandoahAsserts::assert_rp_isalive_not_installed(__FILE__, __LINE__);
+                    ShenandoahAsserts::assert_rp_isalive_not_installed(__FILE__, __LINE__)
 
 #define shenandoah_assert_safepoint() \
-                    assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Should be at Shenandoah Safepoints");
+                    assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Should be at Shenandoah Safepoints")
 
 #define shenandoah_assert_locked_or_safepoint(lock) \
-                    ShenandoahAsserts::assert_locked_or_shenandoah_safepoint(lock, __FILE__, __LINE__);
+                    ShenandoahAsserts::assert_locked_or_shenandoah_safepoint(lock, __FILE__, __LINE__)
 
 #define shenandoah_assert_heaplocked() \
                     ShenandoahAsserts::assert_heaplocked(__FILE__, __LINE__)

From 168cdcf65d8ef56779cb1d925de34271362943ce Mon Sep 17 00:00:00 2001
From: Claes Redestad 
Date: Wed, 13 May 2020 22:25:14 +0200
Subject: [PATCH 047/143] 8244936: Reduce JNI overhead of accessing
 FileDescriptor

Reviewed-by: rriggs, alanb
---
 .../share/native/libjava/FileInputStream.c    |  6 ++---
 .../share/native/libjava/RandomAccessFile.c   | 10 ++++-----
 src/java.base/share/native/libjava/io_util.c  | 10 ++++-----
 .../unix/native/libjava/io_util_md.c          | 14 +++++++++---
 .../unix/native/libjava/io_util_md.h          | 18 +++++----------
 .../windows/native/libjava/io_util_md.c       | 14 +++++++++---
 .../windows/native/libjava/io_util_md.h       | 17 +++++---------
 .../bench/java/io/RandomAccessRead.java       | 22 +++++++++++++++++--
 8 files changed, 66 insertions(+), 45 deletions(-)

diff --git a/src/java.base/share/native/libjava/FileInputStream.c b/src/java.base/share/native/libjava/FileInputStream.c
index 44122a87b27..548ec9d379a 100644
--- a/src/java.base/share/native/libjava/FileInputStream.c
+++ b/src/java.base/share/native/libjava/FileInputStream.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, 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
@@ -76,7 +76,7 @@ JNIEXPORT jlong JNICALL
 Java_java_io_FileInputStream_skip0(JNIEnv *env, jobject this, jlong toSkip) {
     jlong cur = jlong_zero;
     jlong end = jlong_zero;
-    FD fd = GET_FD(this, fis_fd);
+    FD fd = getFD(env, this, fis_fd);
     if (fd == -1) {
         JNU_ThrowIOException (env, "Stream Closed");
         return 0;
@@ -92,7 +92,7 @@ Java_java_io_FileInputStream_skip0(JNIEnv *env, jobject this, jlong toSkip) {
 JNIEXPORT jint JNICALL
 Java_java_io_FileInputStream_available0(JNIEnv *env, jobject this) {
     jlong ret;
-    FD fd = GET_FD(this, fis_fd);
+    FD fd = getFD(env, this, fis_fd);
     if (fd == -1) {
         JNU_ThrowIOException (env, "Stream Closed");
         return 0;
diff --git a/src/java.base/share/native/libjava/RandomAccessFile.c b/src/java.base/share/native/libjava/RandomAccessFile.c
index d20dfe869a7..22c93b97233 100644
--- a/src/java.base/share/native/libjava/RandomAccessFile.c
+++ b/src/java.base/share/native/libjava/RandomAccessFile.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, 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
@@ -94,7 +94,7 @@ Java_java_io_RandomAccessFile_getFilePointer(JNIEnv *env, jobject this) {
     FD fd;
     jlong ret;
 
-    fd = GET_FD(this, raf_fd);
+    fd = getFD(env, this, raf_fd);
     if (fd == -1) {
         JNU_ThrowIOException(env, "Stream Closed");
         return -1;
@@ -111,7 +111,7 @@ Java_java_io_RandomAccessFile_length(JNIEnv *env, jobject this) {
     FD fd;
     jlong length = jlong_zero;
 
-    fd = GET_FD(this, raf_fd);
+    fd = getFD(env, this, raf_fd);
     if (fd == -1) {
         JNU_ThrowIOException(env, "Stream Closed");
         return -1;
@@ -128,7 +128,7 @@ Java_java_io_RandomAccessFile_seek0(JNIEnv *env,
 
     FD fd;
 
-    fd = GET_FD(this, raf_fd);
+    fd = getFD(env, this, raf_fd);
     if (fd == -1) {
         JNU_ThrowIOException(env, "Stream Closed");
         return;
@@ -147,7 +147,7 @@ Java_java_io_RandomAccessFile_setLength(JNIEnv *env, jobject this,
     FD fd;
     jlong cur;
 
-    fd = GET_FD(this, raf_fd);
+    fd = getFD(env, this, raf_fd);
     if (fd == -1) {
         JNU_ThrowIOException(env, "Stream Closed");
         return;
diff --git a/src/java.base/share/native/libjava/io_util.c b/src/java.base/share/native/libjava/io_util.c
index 812a13549b7..70b20157f6e 100644
--- a/src/java.base/share/native/libjava/io_util.c
+++ b/src/java.base/share/native/libjava/io_util.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 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
@@ -39,7 +39,7 @@ jint
 readSingle(JNIEnv *env, jobject this, jfieldID fid) {
     jint nread;
     char ret;
-    FD fd = GET_FD(this, fid);
+    FD fd = getFD(env, this, fid);
     if (fd == -1) {
         JNU_ThrowIOException(env, "Stream Closed");
         return -1;
@@ -101,7 +101,7 @@ readBytes(JNIEnv *env, jobject this, jbyteArray bytes,
         buf = stackBuf;
     }
 
-    fd = GET_FD(this, fid);
+    fd = getFD(env, this, fid);
     if (fd == -1) {
         JNU_ThrowIOException(env, "Stream Closed");
         nread = -1;
@@ -127,7 +127,7 @@ writeSingle(JNIEnv *env, jobject this, jint byte, jboolean append, jfieldID fid)
     // Discard the 24 high-order bits of byte. See OutputStream#write(int)
     char c = (char) byte;
     jint n;
-    FD fd = GET_FD(this, fid);
+    FD fd = getFD(env, this, fid);
     if (fd == -1) {
         JNU_ThrowIOException(env, "Stream Closed");
         return;
@@ -178,7 +178,7 @@ writeBytes(JNIEnv *env, jobject this, jbyteArray bytes,
     if (!(*env)->ExceptionOccurred(env)) {
         off = 0;
         while (len > 0) {
-            fd = GET_FD(this, fid);
+            fd = getFD(env, this, fid);
             if (fd == -1) {
                 JNU_ThrowIOException(env, "Stream Closed");
                 break;
diff --git a/src/java.base/unix/native/libjava/io_util_md.c b/src/java.base/unix/native/libjava/io_util_md.c
index 15f38f849c0..77bf44f9eeb 100644
--- a/src/java.base/unix/native/libjava/io_util_md.c
+++ b/src/java.base/unix/native/libjava/io_util_md.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2018, 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
@@ -92,6 +92,14 @@ handleOpen(const char *path, int oflag, int mode) {
     return fd;
 }
 
+FD getFD(JNIEnv *env, jobject obj, jfieldID fid) {
+  jobject fdo = (*env)->GetObjectField(env, obj, fid);
+  if (fdo == NULL) {
+    return -1;
+  }
+  return (*env)->GetIntField(env, fdo, IO_fd_fdID);
+}
+
 void
 fileOpen(JNIEnv *env, jobject this, jstring path, jfieldID fid, int flags)
 {
@@ -108,10 +116,10 @@ fileOpen(JNIEnv *env, jobject this, jstring path, jfieldID fid, int flags)
         if (fd != -1) {
             jobject fdobj;
             jboolean append;
-            SET_FD(this, fd, fid);
-
             fdobj = (*env)->GetObjectField(env, this, fid);
             if (fdobj != NULL) {
+                // Set FD
+                (*env)->SetIntField(env, fdobj, IO_fd_fdID, fd);
                 append = (flags & O_APPEND) == 0 ? JNI_FALSE : JNI_TRUE;
                 (*env)->SetBooleanField(env, fdobj, IO_append_fdID, append);
             }
diff --git a/src/java.base/unix/native/libjava/io_util_md.h b/src/java.base/unix/native/libjava/io_util_md.h
index 2e8cffe6f71..3dccf64f41f 100644
--- a/src/java.base/unix/native/libjava/io_util_md.h
+++ b/src/java.base/unix/native/libjava/io_util_md.h
@@ -43,20 +43,12 @@ jlong handleGetLength(FD fd);
 FD handleOpen(const char *path, int oflag, int mode);
 
 /*
- * Macros to set/get fd from the java.io.FileDescriptor.  These
- * macros rely on having an appropriately defined 'this' object
- * within the scope in which they're used.
- * If GetObjectField returns null, SET_FD will stop and GET_FD
- * will simply return -1 to avoid crashing VM.
+ * Functions to get fd from the java.io.FileDescriptor field
+ * of an object.  These functions rely on having an appropriately
+ * defined object with a FileDescriptor object at the fid offset.
+ * If the FD object is null, return -1 to avoid crashing VM.
  */
-
-#define SET_FD(this, fd, fid) \
-    if ((*env)->GetObjectField(env, (this), (fid)) != NULL) \
-        (*env)->SetIntField(env, (*env)->GetObjectField(env, (this), (fid)),IO_fd_fdID, (fd))
-
-#define GET_FD(this, fid) \
-    (*env)->GetObjectField(env, (this), (fid)) == NULL ? \
-        -1 : (*env)->GetIntField(env, (*env)->GetObjectField(env, (this), (fid)), IO_fd_fdID)
+FD getFD(JNIEnv *env, jobject cur, jfieldID fid);
 
 /*
  * Macros to set/get fd when inside java.io.FileDescriptor
diff --git a/src/java.base/windows/native/libjava/io_util_md.c b/src/java.base/windows/native/libjava/io_util_md.c
index eda0b4a9377..fee837b6c0a 100644
--- a/src/java.base/windows/native/libjava/io_util_md.c
+++ b/src/java.base/windows/native/libjava/io_util_md.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2018, 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
@@ -259,6 +259,14 @@ FD winFileHandleOpen(JNIEnv *env, jstring path, int flags)
     return (jlong) h;
 }
 
+FD getFD(JNIEnv *env, jobject obj, jfieldID fid) {
+  jobject fdo = (*env)->GetObjectField(env, obj, fid);
+  if (fdo == NULL) {
+    return -1;
+  }
+  return (*env)->GetLongField(env, fdo, IO_handle_fdID);
+}
+
 void
 fileOpen(JNIEnv *env, jobject this, jstring path, jfieldID fid, int flags)
 {
@@ -266,10 +274,10 @@ fileOpen(JNIEnv *env, jobject this, jstring path, jfieldID fid, int flags)
     if (h >= 0) {
         jobject fdobj;
         jboolean append;
-        SET_FD(this, h, fid);
-
         fdobj = (*env)->GetObjectField(env, this, fid);
         if (fdobj != NULL) {
+            // Set FD
+            (*env)->SetLongField(env, fdobj, IO_handle_fdID, h);
             append = (flags & O_APPEND) == 0 ? JNI_FALSE : JNI_TRUE;
             (*env)->SetBooleanField(env, fdobj, IO_append_fdID, append);
         }
diff --git a/src/java.base/windows/native/libjava/io_util_md.h b/src/java.base/windows/native/libjava/io_util_md.h
index b03d8d66f89..d9f239a25c5 100644
--- a/src/java.base/windows/native/libjava/io_util_md.h
+++ b/src/java.base/windows/native/libjava/io_util_md.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2019, 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
@@ -59,17 +59,12 @@ handleLseek(FD fd, jlong offset, jint whence);
 FD winFileHandleOpen(JNIEnv *env, jstring path, int flags);
 
 /*
- * Macros to set/get fd from the java.io.FileDescriptor.
- * If GetObjectField returns null, SET_FD will stop and GET_FD
- * will simply return -1 to avoid crashing VM.
+ * Function to get fd from the java.io.FileDescriptor field of an
+ * object.  These functions rely on having an appropriately
+ * defined object with a FileDescriptor object at the fid offset.
+ * If the FD object is null, return -1 to avoid crashing VM.
  */
-#define SET_FD(this, fd, fid) \
-    if ((*env)->GetObjectField(env, (this), (fid)) != NULL) \
-        (*env)->SetLongField(env, (*env)->GetObjectField(env, (this), (fid)), IO_handle_fdID, (fd))
-
-#define GET_FD(this, fid) \
-    ((*env)->GetObjectField(env, (this), (fid)) == NULL) ? \
-      -1 : (*env)->GetLongField(env, (*env)->GetObjectField(env, (this), (fid)), IO_handle_fdID)
+FD getFD(JNIEnv *env, jobject cur, jfieldID fid);
 
 /*
  * Macros to set/get fd when inside java.io.FileDescriptor
diff --git a/test/micro/org/openjdk/bench/java/io/RandomAccessRead.java b/test/micro/org/openjdk/bench/java/io/RandomAccessRead.java
index 7053718f860..689a95117d9 100644
--- a/test/micro/org/openjdk/bench/java/io/RandomAccessRead.java
+++ b/test/micro/org/openjdk/bench/java/io/RandomAccessRead.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 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
@@ -51,11 +51,15 @@ public class RandomAccessRead {
     @Param("1000000")
     private int fileSize;
 
+    @Param("8192")
+    private int buffer;
+
     private RandomAccessFile raf;
     private long offset;
     private int deltaIndex;
     private int[] deltas;
     private File f;
+    private byte[] buf;
 
     @Setup(Level.Trial)
     public void beforeRun() throws IOException {
@@ -66,6 +70,7 @@ public class RandomAccessRead {
             }
         }
         deltas = new int[]{1, 2, 3, 5, 7, 11, 13, 17, 19, 23};
+        buf = new byte[buffer];
     }
 
     @TearDown(Level.Trial)
@@ -85,6 +90,20 @@ public class RandomAccessRead {
         raf.close();
     }
 
+    @Benchmark
+    public int testBuffer() throws IOException {
+        offset = offset + deltas[deltaIndex];
+        if (offset >= fileSize) {
+            offset = 0;
+        }
+        deltaIndex++;
+        if (deltaIndex >= deltas.length) {
+            deltaIndex = 0;
+        }
+        raf.seek(offset);
+        return raf.read(buf);
+    }
+
     @Benchmark
     public int test() throws IOException {
         offset = offset + deltas[deltaIndex];
@@ -98,5 +117,4 @@ public class RandomAccessRead {
         raf.seek(offset);
         return raf.read();
     }
-
 }

From 659aa08fbca8c672313d9f07d3d8b321628fb294 Mon Sep 17 00:00:00 2001
From: Kim Barrett 
Date: Wed, 13 May 2020 17:01:10 -0400
Subject: [PATCH 048/143] 8242901: Duplicate PSYoung/OldGen max size functions

Use (nonvirtual) min/max_gen_size consistently, and remove duplicates.

Reviewed-by: stefank, sjohanss
---
 .../gc/parallel/parallelScavengeHeap.cpp      |  6 +--
 .../share/gc/parallel/psMemoryPool.cpp        |  8 ++--
 .../share/gc/parallel/psMemoryPool.hpp        |  6 ++-
 src/hotspot/share/gc/parallel/psOldGen.cpp    | 38 +++++++++----------
 src/hotspot/share/gc/parallel/psOldGen.hpp    | 16 +++-----
 .../share/gc/parallel/psParallelCompact.cpp   |  4 +-
 src/hotspot/share/gc/parallel/psScavenge.cpp  | 15 ++++----
 src/hotspot/share/gc/parallel/psYoungGen.cpp  | 37 +++++++++---------
 src/hotspot/share/gc/parallel/psYoungGen.hpp  | 15 ++------
 .../gc/parallel/vmStructs_parallelgc.hpp      |  2 -
 10 files changed, 68 insertions(+), 79 deletions(-)

diff --git a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp
index f814842b3e8..0ea793acb44 100644
--- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp
+++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp
@@ -100,8 +100,8 @@ jint ParallelScavengeHeap::initialize() {
       MaxOldSize,
       "old", 1);
 
-  assert(young_gen()->gen_size_limit() == young_rs.size(),"Consistency check");
-  assert(old_gen()->gen_size_limit() == old_rs.size(), "Consistency check");
+  assert(young_gen()->max_gen_size() == young_rs.size(),"Consistency check");
+  assert(old_gen()->max_gen_size() == old_rs.size(), "Consistency check");
 
   double max_gc_pause_sec = ((double) MaxGCPauseMillis)/1000.0;
   double max_gc_minor_pause_sec = ((double) MaxGCMinorPauseMillis)/1000.0;
@@ -207,7 +207,7 @@ bool ParallelScavengeHeap::is_maximal_no_gc() const {
 size_t ParallelScavengeHeap::max_capacity() const {
   size_t estimated = reserved_region().byte_size();
   if (UseAdaptiveSizePolicy) {
-    estimated -= _size_policy->max_survivor_size(young_gen()->max_size());
+    estimated -= _size_policy->max_survivor_size(young_gen()->max_gen_size());
   } else {
     estimated -= young_gen()->to_space()->capacity_in_bytes();
   }
diff --git a/src/hotspot/share/gc/parallel/psMemoryPool.cpp b/src/hotspot/share/gc/parallel/psMemoryPool.cpp
index 92e94efdfa2..cd92e86c98b 100644
--- a/src/hotspot/share/gc/parallel/psMemoryPool.cpp
+++ b/src/hotspot/share/gc/parallel/psMemoryPool.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2017, 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
@@ -51,8 +51,10 @@ EdenMutableSpacePool::EdenMutableSpacePool(PSYoungGen* young_gen,
                                            const char* name,
                                            bool support_usage_threshold) :
   CollectedMemoryPool(name, space->capacity_in_bytes(),
-                      (young_gen->max_size() - young_gen->from_space()->capacity_in_bytes() - young_gen->to_space()->capacity_in_bytes()),
-                       support_usage_threshold),
+                      (young_gen->max_gen_size() -
+                       young_gen->from_space()->capacity_in_bytes() -
+                       young_gen->to_space()->capacity_in_bytes()),
+                      support_usage_threshold),
   _young_gen(young_gen),
   _space(space) {
 }
diff --git a/src/hotspot/share/gc/parallel/psMemoryPool.hpp b/src/hotspot/share/gc/parallel/psMemoryPool.hpp
index 53731249797..58f39cdc79f 100644
--- a/src/hotspot/share/gc/parallel/psMemoryPool.hpp
+++ b/src/hotspot/share/gc/parallel/psMemoryPool.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2019, 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
@@ -59,7 +59,9 @@ public:
   size_t used_in_bytes()                    { return space()->used_in_bytes(); }
   size_t max_size() const {
     // Eden's max_size = max_size of Young Gen - the current committed size of survivor spaces
-    return _young_gen->max_size() - _young_gen->from_space()->capacity_in_bytes() - _young_gen->to_space()->capacity_in_bytes();
+    return _young_gen->max_gen_size() -
+           _young_gen->from_space()->capacity_in_bytes() -
+           _young_gen->to_space()->capacity_in_bytes();
   }
 };
 
diff --git a/src/hotspot/share/gc/parallel/psOldGen.cpp b/src/hotspot/share/gc/parallel/psOldGen.cpp
index 7b40ae25895..fe4480294ca 100644
--- a/src/hotspot/share/gc/parallel/psOldGen.cpp
+++ b/src/hotspot/share/gc/parallel/psOldGen.cpp
@@ -40,25 +40,27 @@
 
 PSOldGen::PSOldGen(ReservedSpace rs, size_t initial_size, size_t min_size,
                    size_t max_size, const char* perf_data_name, int level):
-  _init_gen_size(initial_size), _min_gen_size(min_size),
+  _min_gen_size(min_size),
   _max_gen_size(max_size)
 {
-  initialize(rs, GenAlignment, perf_data_name, level);
+  initialize(rs, initial_size, GenAlignment, perf_data_name, level);
 }
 
-void PSOldGen::initialize(ReservedSpace rs, size_t alignment,
+void PSOldGen::initialize(ReservedSpace rs, size_t initial_size, size_t alignment,
                           const char* perf_data_name, int level) {
-  initialize_virtual_space(rs, alignment);
+  initialize_virtual_space(rs, initial_size, alignment);
   initialize_work(perf_data_name, level);
 
-  // The old gen can grow to gen_size_limit().  _reserve reflects only
+  // The old gen can grow to max_gen_size().  _reserve reflects only
   // the current maximum that can be committed.
-  assert(_reserved.byte_size() <= gen_size_limit(), "Consistency check");
+  assert(_reserved.byte_size() <= max_gen_size(), "Consistency check");
 
   initialize_performance_counters(perf_data_name, level);
 }
 
-void PSOldGen::initialize_virtual_space(ReservedSpace rs, size_t alignment) {
+void PSOldGen::initialize_virtual_space(ReservedSpace rs,
+                                        size_t initial_size,
+                                        size_t alignment) {
 
   if(ParallelArguments::is_heterogeneous_heap()) {
     _virtual_space = new PSFileBackedVirtualSpace(rs, alignment, AllocateOldGenAt);
@@ -68,7 +70,7 @@ void PSOldGen::initialize_virtual_space(ReservedSpace rs, size_t alignment) {
   } else {
     _virtual_space = new PSVirtualSpace(rs, alignment);
   }
-  if (!_virtual_space->expand_by(_init_gen_size)) {
+  if (!_virtual_space->expand_by(initial_size)) {
     vm_exit_during_initialization("Could not reserve enough space for "
                                   "object heap");
   }
@@ -80,8 +82,8 @@ void PSOldGen::initialize_work(const char* perf_data_name, int level) {
   //
 
   MemRegion limit_reserved((HeapWord*)virtual_space()->low_boundary(),
-    heap_word_size(_max_gen_size));
-  assert(limit_reserved.byte_size() == _max_gen_size,
+                           heap_word_size(max_gen_size()));
+  assert(limit_reserved.byte_size() == max_gen_size(),
     "word vs bytes confusion");
   //
   // Object start stuff
@@ -137,8 +139,8 @@ void PSOldGen::initialize_work(const char* perf_data_name, int level) {
 
 void PSOldGen::initialize_performance_counters(const char* perf_data_name, int level) {
   // Generation Counters, generation 'level', 1 subspace
-  _gen_counters = new PSGenerationCounters(perf_data_name, level, 1, _min_gen_size,
-                                           _max_gen_size, virtual_space());
+  _gen_counters = new PSGenerationCounters(perf_data_name, level, 1, min_gen_size(),
+                                           max_gen_size(), virtual_space());
   _space_counters = new SpaceCounters(perf_data_name, 0,
                                       virtual_space()->reserved_size(),
                                       _object_space, _gen_counters);
@@ -299,12 +301,12 @@ void PSOldGen::resize(size_t desired_free_space) {
   size_t new_size = used_in_bytes() + desired_free_space;
   if (new_size < used_in_bytes()) {
     // Overflowed the addition.
-    new_size = gen_size_limit();
+    new_size = max_gen_size();
   }
   // Adjust according to our min and max
-  new_size = clamp(new_size, min_gen_size(), gen_size_limit());
+  new_size = clamp(new_size, min_gen_size(), max_gen_size());
 
-  assert(gen_size_limit() >= reserved().byte_size(), "max new size problem?");
+  assert(max_gen_size() >= reserved().byte_size(), "max new size problem?");
   new_size = align_up(new_size, alignment);
 
   const size_t current_size = capacity_in_bytes();
@@ -314,7 +316,7 @@ void PSOldGen::resize(size_t desired_free_space) {
     " new size: " SIZE_FORMAT " current size " SIZE_FORMAT
     " gen limits: " SIZE_FORMAT " / " SIZE_FORMAT,
     desired_free_space, used_in_bytes(), new_size, current_size,
-    gen_size_limit(), min_gen_size());
+    max_gen_size(), min_gen_size());
 
   if (new_size == current_size) {
     // No change requested
@@ -358,10 +360,6 @@ void PSOldGen::post_resize() {
     "Sanity");
 }
 
-size_t PSOldGen::gen_size_limit() {
-  return _max_gen_size;
-}
-
 void PSOldGen::print() const { print_on(tty);}
 void PSOldGen::print_on(outputStream* st) const {
   st->print(" %-15s", name());
diff --git a/src/hotspot/share/gc/parallel/psOldGen.hpp b/src/hotspot/share/gc/parallel/psOldGen.hpp
index 61a2f32f1f6..f7e43af064f 100644
--- a/src/hotspot/share/gc/parallel/psOldGen.hpp
+++ b/src/hotspot/share/gc/parallel/psOldGen.hpp
@@ -49,7 +49,6 @@ class PSOldGen : public CHeapObj {
   SpaceCounters*           _space_counters;
 
   // Sizing information, in bytes, set in constructor
-  const size_t _init_gen_size;
   const size_t _min_gen_size;
   const size_t _max_gen_size;
 
@@ -110,9 +109,9 @@ class PSOldGen : public CHeapObj {
 
   void post_resize();
 
-  void initialize(ReservedSpace rs, size_t alignment,
+  void initialize(ReservedSpace rs, size_t initial_size, size_t alignment,
                   const char* perf_data_name, int level);
-  void initialize_virtual_space(ReservedSpace rs, size_t alignment);
+  void initialize_virtual_space(ReservedSpace rs, size_t initial_size, size_t alignment);
   void initialize_work(const char* perf_data_name, int level);
   void initialize_performance_counters(const char* perf_data_name, int level);
 
@@ -121,14 +120,9 @@ class PSOldGen : public CHeapObj {
   PSOldGen(ReservedSpace rs, size_t initial_size, size_t min_size,
            size_t max_size, const char* perf_data_name, int level);
 
-  MemRegion reserved() const    { return _reserved; }
-  virtual size_t max_gen_size() { return _max_gen_size; }
-  size_t min_gen_size()         { return _min_gen_size; }
-
-  // Returns limit on the maximum size of the generation.  This
-  // is the same as _max_gen_size for PSOldGen but need not be
-  // for a derived class.
-  virtual size_t gen_size_limit();
+  MemRegion reserved() const { return _reserved; }
+  size_t max_gen_size() const { return _max_gen_size; }
+  size_t min_gen_size() const { return _min_gen_size; }
 
   bool is_in(const void* p) const           {
     return _virtual_space->contains((void *)p);
diff --git a/src/hotspot/share/gc/parallel/psParallelCompact.cpp b/src/hotspot/share/gc/parallel/psParallelCompact.cpp
index ce652ffb2a3..ca3d663eab1 100644
--- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp
+++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp
@@ -1864,7 +1864,7 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) {
         }
 
         // Calculate optimal free space amounts
-        assert(young_gen->max_size() >
+        assert(young_gen->max_gen_size() >
           young_gen->from_space()->capacity_in_bytes() +
           young_gen->to_space()->capacity_in_bytes(),
           "Sizes of space in young gen are out-of-bounds");
@@ -1874,7 +1874,7 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) {
         size_t old_live = old_gen->used_in_bytes();
         size_t cur_eden = young_gen->eden_space()->capacity_in_bytes();
         size_t max_old_gen_size = old_gen->max_gen_size();
-        size_t max_eden_size = young_gen->max_size() -
+        size_t max_eden_size = young_gen->max_gen_size() -
           young_gen->from_space()->capacity_in_bytes() -
           young_gen->to_space()->capacity_in_bytes();
 
diff --git a/src/hotspot/share/gc/parallel/psScavenge.cpp b/src/hotspot/share/gc/parallel/psScavenge.cpp
index bd42e3b3c11..86575a33b04 100644
--- a/src/hotspot/share/gc/parallel/psScavenge.cpp
+++ b/src/hotspot/share/gc/parallel/psScavenge.cpp
@@ -592,7 +592,7 @@ bool PSScavenge::invoke_no_policy() {
           counters->update_survivor_overflowed(_survivor_overflow);
         }
 
-        size_t max_young_size = young_gen->max_size();
+        size_t max_young_size = young_gen->max_gen_size();
 
         // Deciding a free ratio in the young generation is tricky, so if
         // MinHeapFreeRatio or MaxHeapFreeRatio are in use (implicating
@@ -600,7 +600,8 @@ bool PSScavenge::invoke_no_policy() {
         // should then limit our young generation size using NewRatio to have it
         // follow the old generation size.
         if (MinHeapFreeRatio != 0 || MaxHeapFreeRatio != 100) {
-          max_young_size = MIN2(old_gen->capacity_in_bytes() / NewRatio, young_gen->max_size());
+          max_young_size = MIN2(old_gen->capacity_in_bytes() / NewRatio,
+                                young_gen->max_gen_size());
         }
 
         size_t survivor_limit =
@@ -625,12 +626,12 @@ bool PSScavenge::invoke_no_policy() {
         // Don't check if the size_policy is ready at this
         // level.  Let the size_policy check that internally.
         if (UseAdaptiveGenerationSizePolicyAtMinorCollection &&
-            (AdaptiveSizePolicy::should_update_eden_stats(gc_cause))) {
+            AdaptiveSizePolicy::should_update_eden_stats(gc_cause)) {
           // Calculate optimal free space amounts
-          assert(young_gen->max_size() >
-            young_gen->from_space()->capacity_in_bytes() +
-            young_gen->to_space()->capacity_in_bytes(),
-            "Sizes of space in young gen are out-of-bounds");
+          assert(young_gen->max_gen_size() >
+                 young_gen->from_space()->capacity_in_bytes() +
+                 young_gen->to_space()->capacity_in_bytes(),
+                 "Sizes of space in young gen are out-of-bounds");
 
           size_t young_live = young_gen->used_in_bytes();
           size_t eden_live = young_gen->eden_space()->used_in_bytes();
diff --git a/src/hotspot/share/gc/parallel/psYoungGen.cpp b/src/hotspot/share/gc/parallel/psYoungGen.cpp
index 23f5319a1d5..97362dfe615 100644
--- a/src/hotspot/share/gc/parallel/psYoungGen.cpp
+++ b/src/hotspot/share/gc/parallel/psYoungGen.cpp
@@ -41,7 +41,6 @@ PSYoungGen::PSYoungGen(ReservedSpace rs, size_t initial_size, size_t min_size, s
   _eden_space(NULL),
   _from_space(NULL),
   _to_space(NULL),
-  _init_gen_size(initial_size),
   _min_gen_size(min_size),
   _max_gen_size(max_size),
   _gen_counters(NULL),
@@ -49,20 +48,21 @@ PSYoungGen::PSYoungGen(ReservedSpace rs, size_t initial_size, size_t min_size, s
   _from_counters(NULL),
   _to_counters(NULL)
 {
-  initialize(rs, GenAlignment);
+  initialize(rs, initial_size, GenAlignment);
 }
 
-void PSYoungGen::initialize_virtual_space(ReservedSpace rs, size_t alignment) {
-  assert(_init_gen_size != 0, "Should have a finite size");
+void PSYoungGen::initialize_virtual_space(ReservedSpace rs,
+                                          size_t initial_size,
+                                          size_t alignment) {
+  assert(initial_size != 0, "Should have a finite size");
   _virtual_space = new PSVirtualSpace(rs, alignment);
-  if (!virtual_space()->expand_by(_init_gen_size)) {
-    vm_exit_during_initialization("Could not reserve enough space for "
-                                  "object heap");
+  if (!virtual_space()->expand_by(initial_size)) {
+    vm_exit_during_initialization("Could not reserve enough space for object heap");
   }
 }
 
-void PSYoungGen::initialize(ReservedSpace rs, size_t alignment) {
-  initialize_virtual_space(rs, alignment);
+void PSYoungGen::initialize(ReservedSpace rs, size_t initial_size, size_t alignment) {
+  initialize_virtual_space(rs, initial_size, alignment);
   initialize_work();
 }
 
@@ -70,6 +70,7 @@ void PSYoungGen::initialize_work() {
 
   _reserved = MemRegion((HeapWord*)virtual_space()->low_boundary(),
                         (HeapWord*)virtual_space()->high_boundary());
+  assert(_reserved.byte_size() == max_gen_size(), "invariant");
 
   MemRegion cmr((HeapWord*)virtual_space()->low(),
                 (HeapWord*)virtual_space()->high());
@@ -91,8 +92,8 @@ void PSYoungGen::initialize_work() {
   _to_space   = new MutableSpace(virtual_space()->alignment());
 
   // Generation Counters - generation 0, 3 subspaces
-  _gen_counters = new PSGenerationCounters("new", 0, 3, _min_gen_size,
-                                           _max_gen_size, _virtual_space);
+  _gen_counters = new PSGenerationCounters("new", 0, 3, min_gen_size(),
+                                           max_gen_size(), virtual_space());
 
   // Compute maximum space sizes for performance counters
   size_t alignment = SpaceAlignment;
@@ -258,7 +259,7 @@ void PSYoungGen::resize(size_t eden_size, size_t survivor_size) {
                         " used: " SIZE_FORMAT " capacity: " SIZE_FORMAT
                         " gen limits: " SIZE_FORMAT " / " SIZE_FORMAT,
                         eden_size, survivor_size, used_in_bytes(), capacity_in_bytes(),
-                        _max_gen_size, min_gen_size());
+                        max_gen_size(), min_gen_size());
   }
 }
 
@@ -269,18 +270,18 @@ bool PSYoungGen::resize_generation(size_t eden_size, size_t survivor_size) {
   bool size_changed = false;
 
   // There used to be this guarantee there.
-  // guarantee ((eden_size + 2*survivor_size)  <= _max_gen_size, "incorrect input arguments");
+  // guarantee ((eden_size + 2*survivor_size)  <= max_gen_size(), "incorrect input arguments");
   // Code below forces this requirement.  In addition the desired eden
   // size and desired survivor sizes are desired goals and may
   // exceed the total generation size.
 
-  assert(min_gen_size() <= orig_size && orig_size <= max_size(), "just checking");
+  assert(min_gen_size() <= orig_size && orig_size <= max_gen_size(), "just checking");
 
   // Adjust new generation size
   const size_t eden_plus_survivors =
           align_up(eden_size + 2 * survivor_size, alignment);
-  size_t desired_size = clamp(eden_plus_survivors, min_gen_size(), max_size());
-  assert(desired_size <= max_size(), "just checking");
+  size_t desired_size = clamp(eden_plus_survivors, min_gen_size(), max_gen_size());
+  assert(desired_size <= max_gen_size(), "just checking");
 
   if (desired_size > orig_size) {
     // Grow the generation
@@ -312,7 +313,7 @@ bool PSYoungGen::resize_generation(size_t eden_size, size_t survivor_size) {
       size_changed = true;
     }
   } else {
-    if (orig_size == gen_size_limit()) {
+    if (orig_size == max_gen_size()) {
       log_trace(gc)("PSYoung generation size at maximum: " SIZE_FORMAT "K", orig_size/K);
     } else if (orig_size == min_gen_size()) {
       log_trace(gc)("PSYoung generation size at minium: " SIZE_FORMAT "K", orig_size/K);
@@ -326,7 +327,7 @@ bool PSYoungGen::resize_generation(size_t eden_size, size_t survivor_size) {
   }
 
   guarantee(eden_plus_survivors <= virtual_space()->committed_size() ||
-            virtual_space()->committed_size() == max_size(), "Sanity");
+            virtual_space()->committed_size() == max_gen_size(), "Sanity");
 
   return true;
 }
diff --git a/src/hotspot/share/gc/parallel/psYoungGen.hpp b/src/hotspot/share/gc/parallel/psYoungGen.hpp
index efddb8f6a59..9bab7e1c4a1 100644
--- a/src/hotspot/share/gc/parallel/psYoungGen.hpp
+++ b/src/hotspot/share/gc/parallel/psYoungGen.hpp
@@ -46,7 +46,6 @@ class PSYoungGen : public CHeapObj {
   MutableSpace* _to_space;
 
   // Sizing information, in bytes, set in constructor
-  const size_t _init_gen_size;
   const size_t _min_gen_size;
   const size_t _max_gen_size;
 
@@ -78,9 +77,9 @@ class PSYoungGen : public CHeapObj {
   // the location the live data in the generation.
   size_t available_to_live();
 
-  void initialize(ReservedSpace rs, size_t alignment);
+  void initialize(ReservedSpace rs, size_t inital_size, size_t alignment);
   void initialize_work();
-  void initialize_virtual_space(ReservedSpace rs, size_t alignment);
+  void initialize_virtual_space(ReservedSpace rs, size_t initial_size, size_t alignment);
 
  public:
   // Initialize the generation.
@@ -104,9 +103,6 @@ class PSYoungGen : public CHeapObj {
   MutableSpace*   to_space() const      { return _to_space; }
   PSVirtualSpace* virtual_space() const { return _virtual_space; }
 
-  // For Adaptive size policy
-  size_t min_gen_size() { return _min_gen_size; }
-
   // Called during/after GC
   void swap_spaces();
 
@@ -125,11 +121,8 @@ class PSYoungGen : public CHeapObj {
   size_t used_in_words() const;
   size_t free_in_words() const;
 
-  // The max this generation can grow to
-  size_t max_size() const { return _reserved.byte_size(); }
-
-  // The max this generation can grow to
-  size_t gen_size_limit() const { return _max_gen_size; }
+  size_t min_gen_size() const { return _min_gen_size; }
+  size_t max_gen_size() const { return _max_gen_size; }
 
   bool is_maximal_no_gc() const {
     return true;  // Never expands except at a GC
diff --git a/src/hotspot/share/gc/parallel/vmStructs_parallelgc.hpp b/src/hotspot/share/gc/parallel/vmStructs_parallelgc.hpp
index d07eadfb514..658546ac529 100644
--- a/src/hotspot/share/gc/parallel/vmStructs_parallelgc.hpp
+++ b/src/hotspot/share/gc/parallel/vmStructs_parallelgc.hpp
@@ -56,14 +56,12 @@
   nonstatic_field(PSYoungGen,                  _eden_space,                                   MutableSpace*)                         \
   nonstatic_field(PSYoungGen,                  _from_space,                                   MutableSpace*)                         \
   nonstatic_field(PSYoungGen,                  _to_space,                                     MutableSpace*)                         \
-  nonstatic_field(PSYoungGen,                  _init_gen_size,                                const size_t)                          \
   nonstatic_field(PSYoungGen,                  _min_gen_size,                                 const size_t)                          \
   nonstatic_field(PSYoungGen,                  _max_gen_size,                                 const size_t)                          \
                                                                                                                                      \
   nonstatic_field(PSOldGen,                    _reserved,                                     MemRegion)                             \
   nonstatic_field(PSOldGen,                    _virtual_space,                                PSVirtualSpace*)                       \
   nonstatic_field(PSOldGen,                    _object_space,                                 MutableSpace*)                         \
-  nonstatic_field(PSOldGen,                    _init_gen_size,                                const size_t)                          \
   nonstatic_field(PSOldGen,                    _min_gen_size,                                 const size_t)                          \
   nonstatic_field(PSOldGen,                    _max_gen_size,                                 const size_t)                          \
                                                                                                                                      \

From 073e095e6053550b17b1daf33df2be4f4c4b40ad Mon Sep 17 00:00:00 2001
From: Alex Menkov 
Date: Wed, 13 May 2020 15:25:59 -0700
Subject: [PATCH 049/143] 8235211:
 serviceability/attach/RemovingUnixDomainSocketTest.java fails with
 AttachNotSupportedException: Unable to open socket file

Reviewed-by: sspitsyn, ysuenaga
---
 src/hotspot/os/aix/attachListener_aix.cpp     | 27 ++++++++++-------
 src/hotspot/os/bsd/attachListener_bsd.cpp     | 18 ++++++-----
 src/hotspot/os/linux/attachListener_linux.cpp | 16 ++++++----
 .../attach/RemovingUnixDomainSocketTest.java  | 30 ++++++++++++++-----
 test/lib/jdk/test/lib/apps/LingeredApp.java   |  9 ++++--
 5 files changed, 66 insertions(+), 34 deletions(-)

diff --git a/src/hotspot/os/aix/attachListener_aix.cpp b/src/hotspot/os/aix/attachListener_aix.cpp
index 982c94a7a1d..ab81becae7c 100644
--- a/src/hotspot/os/aix/attachListener_aix.cpp
+++ b/src/hotspot/os/aix/attachListener_aix.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2012, 2018 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -66,10 +66,10 @@ class AixAttachListener: AllStatic {
   static char _path[UNIX_PATH_MAX];
   static bool _has_path;
   // Shutdown marker to prevent accept blocking during clean-up.
-  static bool _shutdown;
+  static volatile bool _shutdown;
 
   // the file descriptor for the listening socket
-  static int _listener;
+  static volatile int _listener;
 
   static bool _atexit_registered;
 
@@ -132,10 +132,10 @@ class AixAttachOperation: public AttachOperation {
 // statics
 char AixAttachListener::_path[UNIX_PATH_MAX];
 bool AixAttachListener::_has_path;
-int AixAttachListener::_listener = -1;
+volatile int AixAttachListener::_listener = -1;
 bool AixAttachListener::_atexit_registered = false;
 // Shutdown marker to prevent accept blocking during clean-up
-bool AixAttachListener::_shutdown = false;
+volatile bool AixAttachListener::_shutdown = false;
 
 // Supporting class to help split a buffer into individual components
 class ArgumentIterator : public StackObj {
@@ -184,7 +184,6 @@ extern "C" {
     AixAttachListener::set_shutdown(true);
     int s = AixAttachListener::listener();
     if (s != -1) {
-      AixAttachListener::set_listener(-1);
       ::shutdown(s, 2);
     }
     if (AixAttachListener::has_path()) {
@@ -376,10 +375,14 @@ AixAttachOperation* AixAttachListener::dequeue() {
     // We must prevent accept blocking on the socket if it has been shut down.
     // Therefore we allow interrupts and check whether we have been shut down already.
     if (AixAttachListener::is_shutdown()) {
+      ::close(listener());
+      set_listener(-1);
       return NULL;
     }
-    s=::accept(listener(), &addr, &len);
+    s = ::accept(listener(), &addr, &len);
     if (s == -1) {
+      ::close(listener());
+      set_listener(-1);
       return NULL;      // log a warning?
     }
 
@@ -531,9 +534,13 @@ bool AttachListener::check_socket_file() {
     listener_cleanup();
 
     // wait to terminate current attach listener instance...
-    while (AttachListener::transit_state(AL_INITIALIZING,
-                                         AL_NOT_INITIALIZED) != AL_NOT_INITIALIZED) {
-      os::naked_yield();
+    {
+      // avoid deadlock if AttachListener thread is blocked at safepoint
+      ThreadBlockInVM tbivm(JavaThread::current());
+      while (AttachListener::transit_state(AL_INITIALIZING,
+                                           AL_NOT_INITIALIZED) != AL_NOT_INITIALIZED) {
+        os::naked_yield();
+      }
     }
     return is_init_trigger();
   }
diff --git a/src/hotspot/os/bsd/attachListener_bsd.cpp b/src/hotspot/os/bsd/attachListener_bsd.cpp
index ba3bd605d4d..c951aee42c4 100644
--- a/src/hotspot/os/bsd/attachListener_bsd.cpp
+++ b/src/hotspot/os/bsd/attachListener_bsd.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2019, 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
@@ -66,7 +66,7 @@ class BsdAttachListener: AllStatic {
   static bool _has_path;
 
   // the file descriptor for the listening socket
-  static int _listener;
+  static volatile int _listener;
 
   static bool _atexit_registered;
 
@@ -126,7 +126,7 @@ class BsdAttachOperation: public AttachOperation {
 // statics
 char BsdAttachListener::_path[UNIX_PATH_MAX];
 bool BsdAttachListener::_has_path;
-int BsdAttachListener::_listener = -1;
+volatile int BsdAttachListener::_listener = -1;
 bool BsdAttachListener::_atexit_registered = false;
 
 // Supporting class to help split a buffer into individual components
@@ -502,11 +502,13 @@ bool AttachListener::check_socket_file() {
     listener_cleanup();
 
     // wait to terminate current attach listener instance...
-
-    while (AttachListener::transit_state(AL_INITIALIZING,
-
-                                         AL_NOT_INITIALIZED) != AL_NOT_INITIALIZED) {
-      os::naked_yield();
+    {
+      // avoid deadlock if AttachListener thread is blocked at safepoint
+      ThreadBlockInVM tbivm(JavaThread::current());
+      while (AttachListener::transit_state(AL_INITIALIZING,
+                                           AL_NOT_INITIALIZED) != AL_NOT_INITIALIZED) {
+        os::naked_yield();
+      }
     }
     return is_init_trigger();
   }
diff --git a/src/hotspot/os/linux/attachListener_linux.cpp b/src/hotspot/os/linux/attachListener_linux.cpp
index a96ee42d77f..aa114d91232 100644
--- a/src/hotspot/os/linux/attachListener_linux.cpp
+++ b/src/hotspot/os/linux/attachListener_linux.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2019, 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
@@ -67,7 +67,7 @@ class LinuxAttachListener: AllStatic {
   static bool _has_path;
 
   // the file descriptor for the listening socket
-  static int _listener;
+  static volatile int _listener;
 
   static bool _atexit_registered;
 
@@ -127,7 +127,7 @@ class LinuxAttachOperation: public AttachOperation {
 // statics
 char LinuxAttachListener::_path[UNIX_PATH_MAX];
 bool LinuxAttachListener::_has_path;
-int LinuxAttachListener::_listener = -1;
+volatile int LinuxAttachListener::_listener = -1;
 bool LinuxAttachListener::_atexit_registered = false;
 
 // Supporting class to help split a buffer into individual components
@@ -502,9 +502,13 @@ bool AttachListener::check_socket_file() {
     listener_cleanup();
 
     // wait to terminate current attach listener instance...
-    while (AttachListener::transit_state(AL_INITIALIZING,
-                                         AL_NOT_INITIALIZED) != AL_NOT_INITIALIZED) {
-      os::naked_yield();
+    {
+      // avoid deadlock if AttachListener thread is blocked at safepoint
+      ThreadBlockInVM tbivm(JavaThread::current());
+      while (AttachListener::transit_state(AL_INITIALIZING,
+                                           AL_NOT_INITIALIZED) != AL_NOT_INITIALIZED) {
+        os::naked_yield();
+      }
     }
     return is_init_trigger();
   }
diff --git a/test/hotspot/jtreg/serviceability/attach/RemovingUnixDomainSocketTest.java b/test/hotspot/jtreg/serviceability/attach/RemovingUnixDomainSocketTest.java
index 2fd36be8840..6ab5cc0149e 100644
--- a/test/hotspot/jtreg/serviceability/attach/RemovingUnixDomainSocketTest.java
+++ b/test/hotspot/jtreg/serviceability/attach/RemovingUnixDomainSocketTest.java
@@ -29,33 +29,44 @@
  * @run main RemovingUnixDomainSocketTest
  */
 
+import java.io.File;
 import java.io.IOException;
 import java.nio.file.Path;
+import java.util.concurrent.TimeUnit;
 
 import jdk.test.lib.Utils;
 import jdk.test.lib.apps.LingeredApp;
 import jdk.test.lib.JDKToolLauncher;
 import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
 
 public class RemovingUnixDomainSocketTest {
 
+    // timeout (in seconds)
+    private static final long timeout = Utils.adjustTimeout(60);
+
     private static void runJCmd(long pid) throws InterruptedException, IOException {
         JDKToolLauncher jcmd = JDKToolLauncher.createUsingTestJDK("jcmd");
         jcmd.addVMArgs(Utils.getTestJavaOpts());
         jcmd.addToolArg(Long.toString(pid));
         jcmd.addToolArg("VM.version");
 
-        ProcessBuilder pb = new ProcessBuilder(jcmd.getCommand());
-        Process jcmdProc = pb.start();
+        Process jcmdProc = ProcessTools.startProcess("jcmd", new ProcessBuilder(jcmd.getCommand()));
 
         OutputAnalyzer out = new OutputAnalyzer(jcmdProc);
 
-        jcmdProc.waitFor();
+        if (!jcmdProc.waitFor(timeout, TimeUnit.SECONDS)) {
+            log("jcmd is still running after " + timeout + " seconds, terminating...");
+            jcmdProc.destroy();
+            jcmdProc.waitFor();
+        }
 
-        System.out.println(out.getStdout());
-        System.err.println(out.getStderr());
+        log("jcmd stdout: [" + out.getStdout() + "];\n" +
+            "jcmd  stderr: [" + out.getStderr() + "]\n" +
+            "jcmd  exitValue = " + out.getExitValue());
 
-        out.stderrShouldBeEmptyIgnoreVMWarnings();
+        out.stderrShouldBeEmptyIgnoreVMWarnings()
+                .stderrShouldBeEmpty();
     }
 
     public static void main(String... args) throws Exception {
@@ -67,10 +78,10 @@ public class RemovingUnixDomainSocketTest {
             runJCmd(app.getPid());
 
             // Remove unix domain socket file
-            var sockFile = Path.of(System.getProperty("java.io.tmpdir"),
+            File sockFile = Path.of(System.getProperty("java.io.tmpdir"),
                                    ".java_pid" + app.getPid())
                                .toFile();
-            System.out.println("Remove " + sockFile.toString());
+            log("Remove " + sockFile.toString());
             sockFile.delete();
 
             // Access to Attach Listener again
@@ -80,4 +91,7 @@ public class RemovingUnixDomainSocketTest {
         }
     }
 
+    static void log(Object s) {
+        System.out.println(String.valueOf(s));
+    }
 }
diff --git a/test/lib/jdk/test/lib/apps/LingeredApp.java b/test/lib/jdk/test/lib/apps/LingeredApp.java
index 3b75b061007..18b61187af1 100644
--- a/test/lib/jdk/test/lib/apps/LingeredApp.java
+++ b/test/lib/jdk/test/lib/apps/LingeredApp.java
@@ -36,6 +36,7 @@ import java.util.Collections;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 import java.util.UUID;
 
@@ -224,7 +225,11 @@ public class LingeredApp {
     public void waitAppTerminate() {
         // This code is modeled after tail end of ProcessTools.getOutput().
         try {
-            appProcess.waitFor();
+            // If the app hangs, we don't want to wait for the to test timeout.
+            if (!appProcess.waitFor(Utils.adjustTimeout(appWaitTime), TimeUnit.SECONDS)) {
+                appProcess.destroy();
+                appProcess.waitFor();
+            }
             outPumperThread.join();
             errPumperThread.join();
         } catch (InterruptedException e) {
@@ -270,7 +275,7 @@ public class LingeredApp {
     }
 
     /**
-     * Waits the application to start with the default timeout.
+     * Waits for the application to start with the default timeout.
      */
     public void waitAppReady() throws IOException {
         waitAppReady(appWaitTime);

From 80c75c9fa92b5c16056b5ef459730479b9994925 Mon Sep 17 00:00:00 2001
From: Naoto Sato 
Date: Wed, 13 May 2020 15:46:08 -0700
Subject: [PATCH 050/143] 8239383: Support for Unicode 13.0

Reviewed-by: rriggs, joehw
---
 .../CharacterData01.java.template             |    9 +-
 .../CharacterData02.java.template             |    8 +-
 .../CharacterData03.java.template             |  259 ++++
 .../CharacterData0E.java.template             |    8 +-
 .../CharacterDataLatin1.java.template         |    8 +-
 make/data/unicodedata/Blocks.txt              |   12 +-
 .../unicodedata/DerivedCoreProperties.txt     |  421 ++++--
 make/data/unicodedata/NormalizationTest.txt   |  265 ++--
 make/data/unicodedata/PropList.txt            |   75 +-
 .../data/unicodedata/PropertyValueAliases.txt |   57 +-
 make/data/unicodedata/Scripts.txt             |  156 +-
 make/data/unicodedata/SpecialCasing.txt       |    4 +-
 make/data/unicodedata/UnicodeData.txt         |  962 ++++++++++++-
 make/data/unicodedata/VERSION                 |    2 +-
 .../auxiliary/GraphemeBreakProperty.txt       |   31 +-
 .../auxiliary/GraphemeBreakTest.txt           |    4 +-
 make/data/unicodedata/emoji-data.txt          |  769 ----------
 make/data/unicodedata/emoji/emoji-data.txt    | 1261 +++++++++++++++++
 .../generateemojidata/GenerateEmojiData.java  |    4 +-
 .../java.base/gensrc/GensrcCharacterData.gmk  |    3 +-
 .../java.base/gensrc/GensrcEmojiData.gmk      |    4 +-
 .../share/classes/java/lang/Character.java    |  518 ++++---
 .../classes/java/lang/CharacterData.java      |    4 +-
 .../classes/java/util/regex/Grapheme.java     |    2 +
 .../internal/icu/impl/UCharacterProperty.java |   29 +-
 .../internal/icu/impl/data/icudt64b/nfkc.nrm  |  Bin 53856 -> 0 bytes
 .../icu/impl/data/icudt64b/uprops.icu         |  Bin 133040 -> 0 bytes
 .../impl/data/{icudt64b => icudt67b}/nfc.nrm  |  Bin 34912 -> 35136 bytes
 .../internal/icu/impl/data/icudt67b/nfkc.nrm  |  Bin 0 -> 54144 bytes
 .../data/{icudt64b => icudt67b}/ubidi.icu     |  Bin 26208 -> 26640 bytes
 .../icu/impl/data/icudt67b/uprops.icu         |  Bin 0 -> 135664 bytes
 .../jdk/internal/icu/util/CodePointMap.java   |   78 +-
 .../jdk/internal/icu/util/CodePointTrie.java  |  138 +-
 .../jdk/internal/icu/util/VersionInfo.java    |    2 +-
 src/java.base/share/legal/icu.md              |  351 +----
 src/java.base/share/legal/unicode.md          |    4 +-
 .../UnicodeBlock/OptimalMapSize.java          |    9 +-
 .../java/text/Normalizer/ConformanceTest.java |    4 +-
 test/jdk/java/util/regex/GraphemeTest.java    |  176 +--
 .../lib/testlibrary/java/lang/UCDFiles.java   |    4 +-
 40 files changed, 3807 insertions(+), 1834 deletions(-)
 create mode 100644 make/data/characterdata/CharacterData03.java.template
 delete mode 100644 make/data/unicodedata/emoji-data.txt
 create mode 100644 make/data/unicodedata/emoji/emoji-data.txt
 delete mode 100644 src/java.base/share/classes/jdk/internal/icu/impl/data/icudt64b/nfkc.nrm
 delete mode 100644 src/java.base/share/classes/jdk/internal/icu/impl/data/icudt64b/uprops.icu
 rename src/java.base/share/classes/jdk/internal/icu/impl/data/{icudt64b => icudt67b}/nfc.nrm (50%)
 create mode 100644 src/java.base/share/classes/jdk/internal/icu/impl/data/icudt67b/nfkc.nrm
 rename src/java.base/share/classes/jdk/internal/icu/impl/data/{icudt64b => icudt67b}/ubidi.icu (73%)
 create mode 100644 src/java.base/share/classes/jdk/internal/icu/impl/data/icudt67b/uprops.icu

diff --git a/make/data/characterdata/CharacterData01.java.template b/make/data/characterdata/CharacterData01.java.template
index bc2ccc1fda1..430fde0ae96 100644
--- a/make/data/characterdata/CharacterData01.java.template
+++ b/make/data/characterdata/CharacterData01.java.template
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2019, 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
@@ -114,14 +114,12 @@ class CharacterData01 extends CharacterData {
     }
 
     boolean isUnicodeIdentifierStart(int ch) {
-        return (getPropertiesEx(ch) & $$maskIDStart) != 0 ||
-               ch == 0x2E2F;
+        return (getPropertiesEx(ch) & $$maskIDStart) != 0;
     }
 
     boolean isUnicodeIdentifierPart(int ch) {
         return (getPropertiesEx(ch) & $$maskIDContinue) != 0 ||
-               isIdentifierIgnorable(ch) ||
-               ch == 0x2E2F;
+               isIdentifierIgnorable(ch);
     }
 
     boolean isIdentifierIgnorable(int ch) {
@@ -367,6 +365,7 @@ class CharacterData01 extends CharacterData {
             case 0x10E7A: retval = 900; break;     // RUMI NUMBER NINE HUNDRED
             case 0x10F25: retval = 100; break;     // OLD SOGDIAN NUMBER ONE HUNDRED
             case 0x10F54: retval = 100; break;     // SOGDIAN NUMBER ONE HUNDRED
+            case 0x10FCB: retval = 100; break;     // CHORASMIAN NUMBER ONE HUNDRED
             case 0x1105E: retval = 40; break;      // BRAHMI NUMBER FORTY
             case 0x1105F: retval = 50; break;      // BRAHMI NUMBER FIFTY
             case 0x11060: retval = 60; break;      // BRAHMI NUMBER SIXTY
diff --git a/make/data/characterdata/CharacterData02.java.template b/make/data/characterdata/CharacterData02.java.template
index b47ebb4096f..57289ed36a5 100644
--- a/make/data/characterdata/CharacterData02.java.template
+++ b/make/data/characterdata/CharacterData02.java.template
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2019, 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
@@ -113,14 +113,12 @@ class CharacterData02 extends CharacterData {
     }
 
     boolean isUnicodeIdentifierStart(int ch) {
-        return (getPropertiesEx(ch) & $$maskIDStart) != 0 ||
-               ch == 0x2E2F;
+        return (getPropertiesEx(ch) & $$maskIDStart) != 0;
     }
 
     boolean isUnicodeIdentifierPart(int ch) {
         return (getPropertiesEx(ch) & $$maskIDContinue) != 0 ||
-               isIdentifierIgnorable(ch) ||
-               ch == 0x2E2F;
+               isIdentifierIgnorable(ch);
     }
 
     boolean isIdentifierIgnorable(int ch) {
diff --git a/make/data/characterdata/CharacterData03.java.template b/make/data/characterdata/CharacterData03.java.template
new file mode 100644
index 00000000000..730169b0290
--- /dev/null
+++ b/make/data/characterdata/CharacterData03.java.template
@@ -0,0 +1,259 @@
+/*
+ * 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 java.lang;
+
+/** The CharacterData class encapsulates the large tables found in
+    Java.lang.Character. */
+
+class CharacterData03 extends CharacterData {
+    /* The character properties are currently encoded into 32 bits in the following manner:
+        1 bit   mirrored property
+        4 bits  directionality property
+        9 bits  signed offset used for converting case
+        1 bit   if 1, adding the signed offset converts the character to lowercase
+        1 bit   if 1, subtracting the signed offset converts the character to uppercase
+        1 bit   if 1, this character has a titlecase equivalent (possibly itself)
+        3 bits  0  may not be part of an identifier
+                1  ignorable control; may continue a Unicode identifier or Java identifier
+                2  may continue a Java identifier but not a Unicode identifier (unused)
+                3  may continue a Unicode identifier or Java identifier
+                4  is a Java whitespace character
+                5  may start or continue a Java identifier;
+                   may continue but not start a Unicode identifier (underscores)
+                6  may start or continue a Java identifier but not a Unicode identifier ($)
+                7  may start or continue a Unicode identifier or Java identifier
+                Thus:
+                   5, 6, 7 may start a Java identifier
+                   1, 2, 3, 5, 6, 7 may continue a Java identifier
+                   7 may start a Unicode identifier
+                   1, 3, 5, 7 may continue a Unicode identifier
+                   1 is ignorable within an identifier
+                   4 is Java whitespace
+        2 bits  0  this character has no numeric property
+                1  adding the digit offset to the character code and then
+                   masking with 0x1F will produce the desired numeric value
+                2  this character has a "strange" numeric value
+                3  a Java supradecimal digit: adding the digit offset to the
+                   character code, then masking with 0x1F, then adding 10
+                   will produce the desired numeric value
+        5 bits  digit offset
+        5 bits  character type
+
+        The encoding of character properties is subject to change at any time.
+     */
+
+    int getProperties(int ch) {
+	char offset = (char)ch;
+        int props = $$Lookup(offset);
+        return props;
+    }
+
+    int getPropertiesEx(int ch) {
+        char offset = (char)ch;
+        int props = $$LookupEx(offset);
+        return props;
+    }
+
+    boolean isOtherLowercase(int ch) {
+        int props = getPropertiesEx(ch);
+        return (props & $$maskOtherLowercase) != 0;
+    }
+
+    boolean isOtherUppercase(int ch) {
+        int props = getPropertiesEx(ch);
+        return (props & $$maskOtherUppercase) != 0;
+    }
+
+    boolean isOtherAlphabetic(int ch) {
+        int props = getPropertiesEx(ch);
+        return (props & $$maskOtherAlphabetic) != 0;
+    }
+
+    boolean isIdeographic(int ch) {
+        int props = getPropertiesEx(ch);
+        return (props & $$maskIdeographic) != 0;
+    }
+
+    int getType(int ch) {
+        int props = getProperties(ch);
+        return (props & $$maskType);
+    }
+
+    boolean isJavaIdentifierStart(int ch) {
+        int props = getProperties(ch);
+        return ((props & $$maskIdentifierInfo) >= $$lowJavaStart);
+    }
+
+    boolean isJavaIdentifierPart(int ch) {
+        int props = getProperties(ch);
+        return ((props & $$nonzeroJavaPart) != 0);
+    }
+
+    boolean isUnicodeIdentifierStart(int ch) {
+        return (getPropertiesEx(ch) & $$maskIDStart) != 0;
+    }
+
+    boolean isUnicodeIdentifierPart(int ch) {
+        return (getPropertiesEx(ch) & $$maskIDContinue) != 0 ||
+               isIdentifierIgnorable(ch);
+    }
+
+    boolean isIdentifierIgnorable(int ch) {
+        int props = getProperties(ch);
+        return ((props & $$maskIdentifierInfo) == $$valueIgnorable);
+    }
+
+    int toLowerCase(int ch) {
+        int mapChar = ch;
+        int val = getProperties(ch);
+
+        if ((val & $$maskLowerCase) != 0) {
+            int offset = val << $$shiftCaseOffsetSign >> ($$shiftCaseOffsetSign+$$shiftCaseOffset);
+            mapChar = ch + offset;
+        }
+        return mapChar;
+    }
+
+    int toUpperCase(int ch) {
+        int mapChar = ch;
+        int val = getProperties(ch);
+
+        if ((val & $$maskUpperCase) != 0) {
+            int offset = val  << $$shiftCaseOffsetSign >> ($$shiftCaseOffsetSign+$$shiftCaseOffset);
+            mapChar =  ch - offset;
+        }
+        return mapChar;
+    }
+
+    int toTitleCase(int ch) {
+        int mapChar = ch;
+        int val = getProperties(ch);
+
+        if ((val & $$maskTitleCase) != 0) {
+            // There is a titlecase equivalent.  Perform further checks:
+            if ((val & $$maskUpperCase) == 0) {
+                // The character does not have an uppercase equivalent, so it must
+                // already be uppercase; so add 1 to get the titlecase form.
+                mapChar = ch + 1;
+            }
+            else if ((val & $$maskLowerCase) == 0) {
+                // The character does not have a lowercase equivalent, so it must
+                // already be lowercase; so subtract 1 to get the titlecase form.
+                mapChar = ch - 1;
+            }
+            // else {
+            // The character has both an uppercase equivalent and a lowercase
+            // equivalent, so it must itself be a titlecase form; return it.
+            // return ch;
+            //}
+        }
+        else if ((val & $$maskUpperCase) != 0) {
+            // This character has no titlecase equivalent but it does have an
+            // uppercase equivalent, so use that (subtract the signed case offset).
+            mapChar = toUpperCase(ch);
+        }
+        return mapChar;
+    }
+
+    int digit(int ch, int radix) {
+        int value = -1;
+        if (radix >= Character.MIN_RADIX && radix <= Character.MAX_RADIX) {
+            int val = getProperties(ch);
+            int kind = val & $$maskType;
+            if (kind == Character.DECIMAL_DIGIT_NUMBER) {
+                value = ch + ((val & $$maskDigitOffset) >> $$shiftDigitOffset) & $$maskDigit;
+            }
+            else if ((val & $$maskNumericType) == $$valueJavaSupradecimal) {
+                // Java supradecimal digit
+                value = (ch + ((val & $$maskDigitOffset) >> $$shiftDigitOffset) & $$maskDigit) + 10;
+            }
+        }
+        return (value < radix) ? value : -1;
+    }
+
+    int getNumericValue(int ch) {
+        int val = getProperties(ch);
+        int retval = -1;
+
+        switch (val & $$maskNumericType) {
+        default: // cannot occur
+        case ($$valueNotNumeric):         // not numeric
+            retval = -1;
+            break;
+        case ($$valueDigit):              // simple numeric
+            retval = ch + ((val & $$maskDigitOffset) >> $$shiftDigitOffset) & $$maskDigit;
+            break;
+        case ($$valueStrangeNumeric)      :       // "strange" numeric
+            retval = -2;
+            break;
+        case ($$valueJavaSupradecimal):           // Java supradecimal
+            retval = (ch + ((val & $$maskDigitOffset) >> $$shiftDigitOffset) & $$maskDigit) + 10;
+            break;
+        }
+        return retval;
+    }
+
+    boolean isDigit(int ch) {
+        int props = getProperties(ch);
+        return (props & $$maskType) == Character.DECIMAL_DIGIT_NUMBER;
+    }
+
+    boolean isLowerCase(int ch) {
+        int props = getProperties(ch);
+        return (props & $$maskType) == Character.LOWERCASE_LETTER;
+    }
+
+    boolean isUpperCase(int ch) {
+        int props = getProperties(ch);
+        return (props & $$maskType) == Character.UPPERCASE_LETTER;
+    }
+
+    boolean isWhitespace(int ch) {
+        return (getProperties(ch) & $$maskIdentifierInfo) == $$valueJavaWhitespace;
+    }
+
+    byte getDirectionality(int ch) {
+        int val = getProperties(ch);
+        byte directionality = (byte)((val & $$maskBidi) >> $$shiftBidi);
+        if (directionality == 0xF ) {
+	        directionality = Character.DIRECTIONALITY_UNDEFINED;
+        }
+        return directionality;
+    }
+
+    boolean isMirrored(int ch) {
+        return (getProperties(ch) & $$maskMirrored) != 0;
+    }
+
+    static final CharacterData instance = new CharacterData03();
+    private CharacterData03() {};
+
+    $$Tables
+
+    static {
+        $$Initializers
+    }        
+}
diff --git a/make/data/characterdata/CharacterData0E.java.template b/make/data/characterdata/CharacterData0E.java.template
index de939ce11c2..d0e2b772525 100644
--- a/make/data/characterdata/CharacterData0E.java.template
+++ b/make/data/characterdata/CharacterData0E.java.template
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2019, 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
@@ -113,14 +113,12 @@ class CharacterData0E extends CharacterData {
     }
 
     boolean isUnicodeIdentifierStart(int ch) {
-        return (getPropertiesEx(ch) & $$maskIDStart) != 0 ||
-               ch == 0x2E2F;
+        return (getPropertiesEx(ch) & $$maskIDStart) != 0;
     }
 
     boolean isUnicodeIdentifierPart(int ch) {
         return (getPropertiesEx(ch) & $$maskIDContinue) != 0 ||
-               isIdentifierIgnorable(ch) ||
-               ch == 0x2E2F;
+               isIdentifierIgnorable(ch);
     }
     
     boolean isIdentifierIgnorable(int ch) {
diff --git a/make/data/characterdata/CharacterDataLatin1.java.template b/make/data/characterdata/CharacterDataLatin1.java.template
index ea2bf74aed3..2d4f2ecdf2e 100644
--- a/make/data/characterdata/CharacterDataLatin1.java.template
+++ b/make/data/characterdata/CharacterDataLatin1.java.template
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -133,14 +133,12 @@ class CharacterDataLatin1 extends CharacterData {
     }
 
     boolean isUnicodeIdentifierStart(int ch) {
-        return (getPropertiesEx(ch) & $$maskIDStart) != 0 ||
-               ch == 0x2E2F;
+        return (getPropertiesEx(ch) & $$maskIDStart) != 0;
     }
 
     boolean isUnicodeIdentifierPart(int ch) {
         return (getPropertiesEx(ch) & $$maskIDContinue) != 0 ||
-               isIdentifierIgnorable(ch) ||
-               ch == 0x2E2F;
+               isIdentifierIgnorable(ch);
     }
 
     boolean isIdentifierIgnorable(int ch) {
diff --git a/make/data/unicodedata/Blocks.txt b/make/data/unicodedata/Blocks.txt
index b7c89ec99f1..b20570e0676 100644
--- a/make/data/unicodedata/Blocks.txt
+++ b/make/data/unicodedata/Blocks.txt
@@ -1,5 +1,5 @@
-# Blocks-12.1.0.txt
-# Date: 2019-03-08, 23:59:00 GMT [KW]
+# Blocks-13.0.0.txt
+# Date: 2019-07-10, 19:06:00 GMT [KW]
 # Copyright (c) 2019 Unicode, Inc.
 # For terms of use, see http://www.unicode.org/terms_of_use.html
 #
@@ -237,8 +237,10 @@ FFF0..FFFF; Specials
 10C80..10CFF; Old Hungarian
 10D00..10D3F; Hanifi Rohingya
 10E60..10E7F; Rumi Numeral Symbols
+10E80..10EBF; Yezidi
 10F00..10F2F; Old Sogdian
 10F30..10F6F; Sogdian
+10FB0..10FDF; Chorasmian
 10FE0..10FFF; Elymaic
 11000..1107F; Brahmi
 11080..110CF; Kaithi
@@ -260,6 +262,7 @@ FFF0..FFFF; Specials
 11700..1173F; Ahom
 11800..1184F; Dogra
 118A0..118FF; Warang Citi
+11900..1195F; Dives Akuru
 119A0..119FF; Nandinagari
 11A00..11A4F; Zanabazar Square
 11A50..11AAF; Soyombo
@@ -269,6 +272,7 @@ FFF0..FFFF; Specials
 11D00..11D5F; Masaram Gondi
 11D60..11DAF; Gunjala Gondi
 11EE0..11EFF; Makasar
+11FB0..11FBF; Lisu Supplement
 11FC0..11FFF; Tamil Supplement
 12000..123FF; Cuneiform
 12400..1247F; Cuneiform Numbers and Punctuation
@@ -285,6 +289,8 @@ FFF0..FFFF; Specials
 16FE0..16FFF; Ideographic Symbols and Punctuation
 17000..187FF; Tangut
 18800..18AFF; Tangut Components
+18B00..18CFF; Khitan Small Script
+18D00..18D8F; Tangut Supplement
 1B000..1B0FF; Kana Supplement
 1B100..1B12F; Kana Extended-A
 1B130..1B16F; Small Kana Extension
@@ -322,12 +328,14 @@ FFF0..FFFF; Specials
 1F900..1F9FF; Supplemental Symbols and Pictographs
 1FA00..1FA6F; Chess Symbols
 1FA70..1FAFF; Symbols and Pictographs Extended-A
+1FB00..1FBFF; Symbols for Legacy Computing
 20000..2A6DF; CJK Unified Ideographs Extension B
 2A700..2B73F; CJK Unified Ideographs Extension C
 2B740..2B81F; CJK Unified Ideographs Extension D
 2B820..2CEAF; CJK Unified Ideographs Extension E
 2CEB0..2EBEF; CJK Unified Ideographs Extension F
 2F800..2FA1F; CJK Compatibility Ideographs Supplement
+30000..3134F; CJK Unified Ideographs Extension G
 E0000..E007F; Tags
 E0100..E01EF; Variation Selectors Supplement
 F0000..FFFFF; Supplementary Private Use Area-A
diff --git a/make/data/unicodedata/DerivedCoreProperties.txt b/make/data/unicodedata/DerivedCoreProperties.txt
index 4a92ffd1a5b..cbaa2d46ce1 100644
--- a/make/data/unicodedata/DerivedCoreProperties.txt
+++ b/make/data/unicodedata/DerivedCoreProperties.txt
@@ -1,6 +1,6 @@
-# DerivedCoreProperties-12.1.0.txt
-# Date: 2019-03-10, 10:53:06 GMT
-# © 2019 Unicode®, Inc.
+# DerivedCoreProperties-13.0.0.txt
+# Date: 2020-01-22, 00:07:19 GMT
+# Copyright (c) 2020 Unicode, Inc.
 # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
 # For terms of use, see http://www.unicode.org/terms_of_use.html
 #
@@ -342,7 +342,7 @@ FFE9..FFEC    ; Math # Sm   [4] HALFWIDTH LEFTWARDS ARROW..HALFWIDTH DOWNWARDS A
 0840..0858    ; Alphabetic # Lo  [25] MANDAIC LETTER HALQA..MANDAIC LETTER AIN
 0860..086A    ; Alphabetic # Lo  [11] SYRIAC LETTER MALAYALAM NGA..SYRIAC LETTER MALAYALAM SSA
 08A0..08B4    ; Alphabetic # Lo  [21] ARABIC LETTER BEH WITH SMALL V BELOW..ARABIC LETTER KAF WITH DOT BELOW
-08B6..08BD    ; Alphabetic # Lo   [8] ARABIC LETTER BEH WITH SMALL MEEM ABOVE..ARABIC LETTER AFRICAN NOON
+08B6..08C7    ; Alphabetic # Lo  [18] ARABIC LETTER BEH WITH SMALL MEEM ABOVE..ARABIC LETTER LAM WITH SMALL ARABIC LETTER TAH ABOVE
 08D4..08DF    ; Alphabetic # Mn  [12] ARABIC SMALL HIGH WORD AR-RUB..ARABIC SMALL HIGH WORD WAQFA
 08E3..08E9    ; Alphabetic # Mn   [7] ARABIC TURNED DAMMA BELOW..ARABIC CURLY KASRATAN
 08F0..0902    ; Alphabetic # Mn  [19] ARABIC OPEN FATHATAN..DEVANAGARI SIGN ANUSVARA
@@ -496,7 +496,7 @@ FFE9..FFEC    ; Math # Sm   [4] HALFWIDTH LEFTWARDS ARROW..HALFWIDTH DOWNWARDS A
 0CF1..0CF2    ; Alphabetic # Lo   [2] KANNADA SIGN JIHVAMULIYA..KANNADA SIGN UPADHMANIYA
 0D00..0D01    ; Alphabetic # Mn   [2] MALAYALAM SIGN COMBINING ANUSVARA ABOVE..MALAYALAM SIGN CANDRABINDU
 0D02..0D03    ; Alphabetic # Mc   [2] MALAYALAM SIGN ANUSVARA..MALAYALAM SIGN VISARGA
-0D05..0D0C    ; Alphabetic # Lo   [8] MALAYALAM LETTER A..MALAYALAM LETTER VOCALIC L
+0D04..0D0C    ; Alphabetic # Lo   [9] MALAYALAM LETTER VEDIC ANUSVARA..MALAYALAM LETTER VOCALIC L
 0D0E..0D10    ; Alphabetic # Lo   [3] MALAYALAM LETTER E..MALAYALAM LETTER AI
 0D12..0D3A    ; Alphabetic # Lo  [41] MALAYALAM LETTER O..MALAYALAM LETTER TTTA
 0D3D          ; Alphabetic # Lo       MALAYALAM SIGN AVAGRAHA
@@ -510,6 +510,7 @@ FFE9..FFEC    ; Math # Sm   [4] HALFWIDTH LEFTWARDS ARROW..HALFWIDTH DOWNWARDS A
 0D5F..0D61    ; Alphabetic # Lo   [3] MALAYALAM LETTER ARCHAIC II..MALAYALAM LETTER VOCALIC LL
 0D62..0D63    ; Alphabetic # Mn   [2] MALAYALAM VOWEL SIGN VOCALIC L..MALAYALAM VOWEL SIGN VOCALIC LL
 0D7A..0D7F    ; Alphabetic # Lo   [6] MALAYALAM LETTER CHILLU NN..MALAYALAM LETTER CHILLU K
+0D81          ; Alphabetic # Mn       SINHALA SIGN CANDRABINDU
 0D82..0D83    ; Alphabetic # Mc   [2] SINHALA SIGN ANUSVARAYA..SINHALA SIGN VISARGAYA
 0D85..0D96    ; Alphabetic # Lo  [18] SINHALA LETTER AYANNA..SINHALA LETTER AUYANNA
 0D9A..0DB1    ; Alphabetic # Lo  [24] SINHALA LETTER ALPAPRAANA KAYANNA..SINHALA LETTER DANTAJA NAYANNA
@@ -668,6 +669,7 @@ FFE9..FFEC    ; Math # Sm   [4] HALFWIDTH LEFTWARDS ARROW..HALFWIDTH DOWNWARDS A
 1A6D..1A72    ; Alphabetic # Mc   [6] TAI THAM VOWEL SIGN OY..TAI THAM VOWEL SIGN THAM AI
 1A73..1A74    ; Alphabetic # Mn   [2] TAI THAM VOWEL SIGN OA ABOVE..TAI THAM SIGN MAI KANG
 1AA7          ; Alphabetic # Lm       TAI THAM SIGN MAI YAMOK
+1ABF..1AC0    ; Alphabetic # Mn   [2] COMBINING LATIN SMALL LETTER W BELOW..COMBINING LATIN SMALL LETTER TURNED W BELOW
 1B00..1B03    ; Alphabetic # Mn   [4] BALINESE SIGN ULU RICEM..BALINESE SIGN SURANG
 1B04          ; Alphabetic # Mc       BALINESE SIGN BISAH
 1B05..1B33    ; Alphabetic # Lo  [47] BALINESE LETTER AKARA..BALINESE LETTER HA
@@ -797,10 +799,10 @@ FFE9..FFEC    ; Math # Sm   [4] HALFWIDTH LEFTWARDS ARROW..HALFWIDTH DOWNWARDS A
 30FF          ; Alphabetic # Lo       KATAKANA DIGRAPH KOTO
 3105..312F    ; Alphabetic # Lo  [43] BOPOMOFO LETTER B..BOPOMOFO LETTER NN
 3131..318E    ; Alphabetic # Lo  [94] HANGUL LETTER KIYEOK..HANGUL LETTER ARAEAE
-31A0..31BA    ; Alphabetic # Lo  [27] BOPOMOFO LETTER BU..BOPOMOFO LETTER ZY
+31A0..31BF    ; Alphabetic # Lo  [32] BOPOMOFO LETTER BU..BOPOMOFO LETTER AH
 31F0..31FF    ; Alphabetic # Lo  [16] KATAKANA LETTER SMALL KU..KATAKANA LETTER SMALL RO
-3400..4DB5    ; Alphabetic # Lo [6582] CJK UNIFIED IDEOGRAPH-3400..CJK UNIFIED IDEOGRAPH-4DB5
-4E00..9FEF    ; Alphabetic # Lo [20976] CJK UNIFIED IDEOGRAPH-4E00..CJK UNIFIED IDEOGRAPH-9FEF
+3400..4DBF    ; Alphabetic # Lo [6592] CJK UNIFIED IDEOGRAPH-3400..CJK UNIFIED IDEOGRAPH-4DBF
+4E00..9FFC    ; Alphabetic # Lo [20989] CJK UNIFIED IDEOGRAPH-4E00..CJK UNIFIED IDEOGRAPH-9FFC
 A000..A014    ; Alphabetic # Lo  [21] YI SYLLABLE IT..YI SYLLABLE E
 A015          ; Alphabetic # Lm       YI SYLLABLE WU
 A016..A48C    ; Alphabetic # Lo [1143] YI SYLLABLE BIT..YI SYLLABLE YYR
@@ -827,7 +829,8 @@ A788          ; Alphabetic # Lm       MODIFIER LETTER LOW CIRCUMFLEX ACCENT
 A78B..A78E    ; Alphabetic # L&   [4] LATIN CAPITAL LETTER SALTILLO..LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT
 A78F          ; Alphabetic # Lo       LATIN LETTER SINOLOGICAL DOT
 A790..A7BF    ; Alphabetic # L&  [48] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER GLOTTAL U
-A7C2..A7C6    ; Alphabetic # L&   [5] LATIN CAPITAL LETTER ANGLICANA W..LATIN CAPITAL LETTER Z WITH PALATAL HOOK
+A7C2..A7CA    ; Alphabetic # L&   [9] LATIN CAPITAL LETTER ANGLICANA W..LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY
+A7F5..A7F6    ; Alphabetic # L&   [2] LATIN CAPITAL LETTER REVERSED HALF H..LATIN SMALL LETTER REVERSED HALF H
 A7F7          ; Alphabetic # Lo       LATIN EPIGRAPHIC LETTER SIDEWAYS I
 A7F8..A7F9    ; Alphabetic # Lm   [2] MODIFIER LETTER CAPITAL H WITH STROKE..MODIFIER LETTER SMALL LIGATURE OE
 A7FA          ; Alphabetic # L&       LATIN LETTER SMALL CAPITAL TURNED M
@@ -913,7 +916,8 @@ AB20..AB26    ; Alphabetic # Lo   [7] ETHIOPIC SYLLABLE CCHHA..ETHIOPIC SYLLABLE
 AB28..AB2E    ; Alphabetic # Lo   [7] ETHIOPIC SYLLABLE BBA..ETHIOPIC SYLLABLE BBO
 AB30..AB5A    ; Alphabetic # L&  [43] LATIN SMALL LETTER BARRED ALPHA..LATIN SMALL LETTER Y WITH SHORT RIGHT LEG
 AB5C..AB5F    ; Alphabetic # Lm   [4] MODIFIER LETTER SMALL HENG..MODIFIER LETTER SMALL U WITH LEFT HOOK
-AB60..AB67    ; Alphabetic # L&   [8] LATIN SMALL LETTER SAKHA YAT..LATIN SMALL LETTER TS DIGRAPH WITH RETROFLEX HOOK
+AB60..AB68    ; Alphabetic # L&   [9] LATIN SMALL LETTER SAKHA YAT..LATIN SMALL LETTER TURNED R WITH MIDDLE TILDE
+AB69          ; Alphabetic # Lm       MODIFIER LETTER SMALL TURNED W
 AB70..ABBF    ; Alphabetic # L&  [80] CHEROKEE SMALL LETTER A..CHEROKEE SMALL LETTER YA
 ABC0..ABE2    ; Alphabetic # Lo  [35] MEETEI MAYEK LETTER KOK..MEETEI MAYEK LETTER I LONSUM
 ABE3..ABE4    ; Alphabetic # Mc   [2] MEETEI MAYEK VOWEL SIGN ONAP..MEETEI MAYEK VOWEL SIGN INAP
@@ -1018,9 +1022,13 @@ FFDA..FFDC    ; Alphabetic # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANG
 10CC0..10CF2  ; Alphabetic # L&  [51] OLD HUNGARIAN SMALL LETTER A..OLD HUNGARIAN SMALL LETTER US
 10D00..10D23  ; Alphabetic # Lo  [36] HANIFI ROHINGYA LETTER A..HANIFI ROHINGYA MARK NA KHONNA
 10D24..10D27  ; Alphabetic # Mn   [4] HANIFI ROHINGYA SIGN HARBAHAY..HANIFI ROHINGYA SIGN TASSI
+10E80..10EA9  ; Alphabetic # Lo  [42] YEZIDI LETTER ELIF..YEZIDI LETTER ET
+10EAB..10EAC  ; Alphabetic # Mn   [2] YEZIDI COMBINING HAMZA MARK..YEZIDI COMBINING MADDA MARK
+10EB0..10EB1  ; Alphabetic # Lo   [2] YEZIDI LETTER LAM WITH DOT ABOVE..YEZIDI LETTER YOT WITH CIRCUMFLEX ABOVE
 10F00..10F1C  ; Alphabetic # Lo  [29] OLD SOGDIAN LETTER ALEPH..OLD SOGDIAN LETTER FINAL TAW WITH VERTICAL TAIL
 10F27         ; Alphabetic # Lo       OLD SOGDIAN LIGATURE AYIN-DALETH
 10F30..10F45  ; Alphabetic # Lo  [22] SOGDIAN LETTER ALEPH..SOGDIAN INDEPENDENT SHIN
+10FB0..10FC4  ; Alphabetic # Lo  [21] CHORASMIAN LETTER ALEPH..CHORASMIAN LETTER TAW
 10FE0..10FF6  ; Alphabetic # Lo  [23] ELYMAIC LETTER ALEPH..ELYMAIC LIGATURE ZAYIN-YODH
 11000         ; Alphabetic # Mc       BRAHMI SIGN CANDRABINDU
 11001         ; Alphabetic # Mn       BRAHMI SIGN ANUSVARA
@@ -1040,6 +1048,7 @@ FFDA..FFDC    ; Alphabetic # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANG
 1112D..11132  ; Alphabetic # Mn   [6] CHAKMA VOWEL SIGN AI..CHAKMA AU MARK
 11144         ; Alphabetic # Lo       CHAKMA LETTER LHAA
 11145..11146  ; Alphabetic # Mc   [2] CHAKMA VOWEL SIGN AA..CHAKMA VOWEL SIGN EI
+11147         ; Alphabetic # Lo       CHAKMA LETTER VAA
 11150..11172  ; Alphabetic # Lo  [35] MAHAJANI LETTER A..MAHAJANI LETTER RRA
 11176         ; Alphabetic # Lo       MAHAJANI LIGATURE SHRI
 11180..11181  ; Alphabetic # Mn   [2] SHARADA SIGN CANDRABINDU..SHARADA SIGN ANUSVARA
@@ -1049,6 +1058,8 @@ FFDA..FFDC    ; Alphabetic # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANG
 111B6..111BE  ; Alphabetic # Mn   [9] SHARADA VOWEL SIGN U..SHARADA VOWEL SIGN O
 111BF         ; Alphabetic # Mc       SHARADA VOWEL SIGN AU
 111C1..111C4  ; Alphabetic # Lo   [4] SHARADA SIGN AVAGRAHA..SHARADA OM
+111CE         ; Alphabetic # Mc       SHARADA VOWEL SIGN PRISHTHAMATRA E
+111CF         ; Alphabetic # Mn       SHARADA SIGN INVERTED CANDRABINDU
 111DA         ; Alphabetic # Lo       SHARADA EKAM
 111DC         ; Alphabetic # Lo       SHARADA HEADSTROKE
 11200..11211  ; Alphabetic # Lo  [18] KHOJKI LETTER A..KHOJKI LETTER JJA
@@ -1093,7 +1104,7 @@ FFDA..FFDC    ; Alphabetic # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANG
 11443..11444  ; Alphabetic # Mn   [2] NEWA SIGN CANDRABINDU..NEWA SIGN ANUSVARA
 11445         ; Alphabetic # Mc       NEWA SIGN VISARGA
 11447..1144A  ; Alphabetic # Lo   [4] NEWA SIGN AVAGRAHA..NEWA SIDDHI
-1145F         ; Alphabetic # Lo       NEWA LETTER VEDIC ANUSVARA
+1145F..11461  ; Alphabetic # Lo   [3] NEWA LETTER VEDIC ANUSVARA..NEWA SIGN UPADHMANIYA
 11480..114AF  ; Alphabetic # Lo  [48] TIRHUTA ANJI..TIRHUTA LETTER HA
 114B0..114B2  ; Alphabetic # Mc   [3] TIRHUTA VOWEL SIGN AA..TIRHUTA VOWEL SIGN II
 114B3..114B8  ; Alphabetic # Mn   [6] TIRHUTA VOWEL SIGN U..TIRHUTA VOWEL SIGN VOCALIC LL
@@ -1138,7 +1149,18 @@ FFDA..FFDC    ; Alphabetic # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANG
 1182F..11837  ; Alphabetic # Mn   [9] DOGRA VOWEL SIGN U..DOGRA SIGN ANUSVARA
 11838         ; Alphabetic # Mc       DOGRA SIGN VISARGA
 118A0..118DF  ; Alphabetic # L&  [64] WARANG CITI CAPITAL LETTER NGAA..WARANG CITI SMALL LETTER VIYO
-118FF         ; Alphabetic # Lo       WARANG CITI OM
+118FF..11906  ; Alphabetic # Lo   [8] WARANG CITI OM..DIVES AKURU LETTER E
+11909         ; Alphabetic # Lo       DIVES AKURU LETTER O
+1190C..11913  ; Alphabetic # Lo   [8] DIVES AKURU LETTER KA..DIVES AKURU LETTER JA
+11915..11916  ; Alphabetic # Lo   [2] DIVES AKURU LETTER NYA..DIVES AKURU LETTER TTA
+11918..1192F  ; Alphabetic # Lo  [24] DIVES AKURU LETTER DDA..DIVES AKURU LETTER ZA
+11930..11935  ; Alphabetic # Mc   [6] DIVES AKURU VOWEL SIGN AA..DIVES AKURU VOWEL SIGN E
+11937..11938  ; Alphabetic # Mc   [2] DIVES AKURU VOWEL SIGN AI..DIVES AKURU VOWEL SIGN O
+1193B..1193C  ; Alphabetic # Mn   [2] DIVES AKURU SIGN ANUSVARA..DIVES AKURU SIGN CANDRABINDU
+1193F         ; Alphabetic # Lo       DIVES AKURU PREFIXED NASAL SIGN
+11940         ; Alphabetic # Mc       DIVES AKURU MEDIAL YA
+11941         ; Alphabetic # Lo       DIVES AKURU INITIAL RA
+11942         ; Alphabetic # Mc       DIVES AKURU MEDIAL RA
 119A0..119A7  ; Alphabetic # Lo   [8] NANDINAGARI LETTER A..NANDINAGARI LETTER VOCALIC RR
 119AA..119D0  ; Alphabetic # Lo  [39] NANDINAGARI LETTER E..NANDINAGARI LETTER RRA
 119D1..119D3  ; Alphabetic # Mc   [3] NANDINAGARI VOWEL SIGN AA..NANDINAGARI VOWEL SIGN II
@@ -1201,6 +1223,7 @@ FFDA..FFDC    ; Alphabetic # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANG
 11EE0..11EF2  ; Alphabetic # Lo  [19] MAKASAR LETTER KA..MAKASAR ANGKA
 11EF3..11EF4  ; Alphabetic # Mn   [2] MAKASAR VOWEL SIGN I..MAKASAR VOWEL SIGN U
 11EF5..11EF6  ; Alphabetic # Mc   [2] MAKASAR VOWEL SIGN E..MAKASAR VOWEL SIGN O
+11FB0         ; Alphabetic # Lo       LISU LETTER YHA
 12000..12399  ; Alphabetic # Lo [922] CUNEIFORM SIGN A..CUNEIFORM SIGN U U
 12400..1246E  ; Alphabetic # Nl [111] CUNEIFORM NUMERIC SIGN TWO ASH..CUNEIFORM NUMERIC SIGN NINE U VARIANT FORM
 12480..12543  ; Alphabetic # Lo [196] CUNEIFORM SIGN AB TIMES NUN TENU..CUNEIFORM SIGN ZU5 TIMES THREE DISH TENU
@@ -1222,8 +1245,10 @@ FFDA..FFDC    ; Alphabetic # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANG
 16F93..16F9F  ; Alphabetic # Lm  [13] MIAO LETTER TONE-2..MIAO LETTER REFORMED TONE-8
 16FE0..16FE1  ; Alphabetic # Lm   [2] TANGUT ITERATION MARK..NUSHU ITERATION MARK
 16FE3         ; Alphabetic # Lm       OLD CHINESE ITERATION MARK
+16FF0..16FF1  ; Alphabetic # Mc   [2] VIETNAMESE ALTERNATE READING MARK CA..VIETNAMESE ALTERNATE READING MARK NHAY
 17000..187F7  ; Alphabetic # Lo [6136] TANGUT IDEOGRAPH-17000..TANGUT IDEOGRAPH-187F7
-18800..18AF2  ; Alphabetic # Lo [755] TANGUT COMPONENT-001..TANGUT COMPONENT-755
+18800..18CD5  ; Alphabetic # Lo [1238] TANGUT COMPONENT-001..KHITAN SMALL SCRIPT CHARACTER-18CD5
+18D00..18D08  ; Alphabetic # Lo   [9] TANGUT IDEOGRAPH-18D00..TANGUT IDEOGRAPH-18D08
 1B000..1B11E  ; Alphabetic # Lo [287] KATAKANA LETTER ARCHAIC E..HENTAIGANA LETTER N-MU-MO-2
 1B150..1B152  ; Alphabetic # Lo   [3] HIRAGANA LETTER SMALL WI..HIRAGANA LETTER SMALL WO
 1B164..1B167  ; Alphabetic # Lo   [4] KATAKANA LETTER SMALL WI..KATAKANA LETTER SMALL N
@@ -1312,14 +1337,15 @@ FFDA..FFDC    ; Alphabetic # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANG
 1F130..1F149  ; Alphabetic # So  [26] SQUARED LATIN CAPITAL LETTER A..SQUARED LATIN CAPITAL LETTER Z
 1F150..1F169  ; Alphabetic # So  [26] NEGATIVE CIRCLED LATIN CAPITAL LETTER A..NEGATIVE CIRCLED LATIN CAPITAL LETTER Z
 1F170..1F189  ; Alphabetic # So  [26] NEGATIVE SQUARED LATIN CAPITAL LETTER A..NEGATIVE SQUARED LATIN CAPITAL LETTER Z
-20000..2A6D6  ; Alphabetic # Lo [42711] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6D6
+20000..2A6DD  ; Alphabetic # Lo [42718] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6DD
 2A700..2B734  ; Alphabetic # Lo [4149] CJK UNIFIED IDEOGRAPH-2A700..CJK UNIFIED IDEOGRAPH-2B734
 2B740..2B81D  ; Alphabetic # Lo [222] CJK UNIFIED IDEOGRAPH-2B740..CJK UNIFIED IDEOGRAPH-2B81D
 2B820..2CEA1  ; Alphabetic # Lo [5762] CJK UNIFIED IDEOGRAPH-2B820..CJK UNIFIED IDEOGRAPH-2CEA1
 2CEB0..2EBE0  ; Alphabetic # Lo [7473] CJK UNIFIED IDEOGRAPH-2CEB0..CJK UNIFIED IDEOGRAPH-2EBE0
 2F800..2FA1D  ; Alphabetic # Lo [542] CJK COMPATIBILITY IDEOGRAPH-2F800..CJK COMPATIBILITY IDEOGRAPH-2FA1D
+30000..3134A  ; Alphabetic # Lo [4939] CJK UNIFIED IDEOGRAPH-30000..CJK UNIFIED IDEOGRAPH-3134A
 
-# Total code points: 127256
+# Total code points: 132875
 
 # ================================================
 
@@ -1945,11 +1971,14 @@ A7BB          ; Lowercase # L&       LATIN SMALL LETTER GLOTTAL A
 A7BD          ; Lowercase # L&       LATIN SMALL LETTER GLOTTAL I
 A7BF          ; Lowercase # L&       LATIN SMALL LETTER GLOTTAL U
 A7C3          ; Lowercase # L&       LATIN SMALL LETTER ANGLICANA W
+A7C8          ; Lowercase # L&       LATIN SMALL LETTER D WITH SHORT STROKE OVERLAY
+A7CA          ; Lowercase # L&       LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY
+A7F6          ; Lowercase # L&       LATIN SMALL LETTER REVERSED HALF H
 A7F8..A7F9    ; Lowercase # Lm   [2] MODIFIER LETTER CAPITAL H WITH STROKE..MODIFIER LETTER SMALL LIGATURE OE
 A7FA          ; Lowercase # L&       LATIN LETTER SMALL CAPITAL TURNED M
 AB30..AB5A    ; Lowercase # L&  [43] LATIN SMALL LETTER BARRED ALPHA..LATIN SMALL LETTER Y WITH SHORT RIGHT LEG
 AB5C..AB5F    ; Lowercase # Lm   [4] MODIFIER LETTER SMALL HENG..MODIFIER LETTER SMALL U WITH LEFT HOOK
-AB60..AB67    ; Lowercase # L&   [8] LATIN SMALL LETTER SAKHA YAT..LATIN SMALL LETTER TS DIGRAPH WITH RETROFLEX HOOK
+AB60..AB68    ; Lowercase # L&   [9] LATIN SMALL LETTER SAKHA YAT..LATIN SMALL LETTER TURNED R WITH MIDDLE TILDE
 AB70..ABBF    ; Lowercase # L&  [80] CHEROKEE SMALL LETTER A..CHEROKEE SMALL LETTER YA
 FB00..FB06    ; Lowercase # L&   [7] LATIN SMALL LIGATURE FF..LATIN SMALL LIGATURE ST
 FB13..FB17    ; Lowercase # L&   [5] ARMENIAN SMALL LIGATURE MEN NOW..ARMENIAN SMALL LIGATURE MEN XEH
@@ -1989,7 +2018,7 @@ FF41..FF5A    ; Lowercase # L&  [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH L
 1D7CB         ; Lowercase # L&       MATHEMATICAL BOLD SMALL DIGAMMA
 1E922..1E943  ; Lowercase # L&  [34] ADLAM SMALL LETTER ALIF..ADLAM SMALL LETTER SHA
 
-# Total code points: 2340
+# Total code points: 2344
 
 # ================================================
 
@@ -2595,7 +2624,9 @@ A7BA          ; Uppercase # L&       LATIN CAPITAL LETTER GLOTTAL A
 A7BC          ; Uppercase # L&       LATIN CAPITAL LETTER GLOTTAL I
 A7BE          ; Uppercase # L&       LATIN CAPITAL LETTER GLOTTAL U
 A7C2          ; Uppercase # L&       LATIN CAPITAL LETTER ANGLICANA W
-A7C4..A7C6    ; Uppercase # L&   [3] LATIN CAPITAL LETTER C WITH PALATAL HOOK..LATIN CAPITAL LETTER Z WITH PALATAL HOOK
+A7C4..A7C7    ; Uppercase # L&   [4] LATIN CAPITAL LETTER C WITH PALATAL HOOK..LATIN CAPITAL LETTER D WITH SHORT STROKE OVERLAY
+A7C9          ; Uppercase # L&       LATIN CAPITAL LETTER S WITH SHORT STROKE OVERLAY
+A7F5          ; Uppercase # L&       LATIN CAPITAL LETTER REVERSED HALF H
 FF21..FF3A    ; Uppercase # L&  [26] FULLWIDTH LATIN CAPITAL LETTER A..FULLWIDTH LATIN CAPITAL LETTER Z
 10400..10427  ; Uppercase # L&  [40] DESERET CAPITAL LETTER LONG I..DESERET CAPITAL LETTER EW
 104B0..104D3  ; Uppercase # L&  [36] OSAGE CAPITAL LETTER A..OSAGE CAPITAL LETTER ZHA
@@ -2638,7 +2669,7 @@ FF21..FF3A    ; Uppercase # L&  [26] FULLWIDTH LATIN CAPITAL LETTER A..FULLWIDTH
 1F150..1F169  ; Uppercase # So  [26] NEGATIVE CIRCLED LATIN CAPITAL LETTER A..NEGATIVE CIRCLED LATIN CAPITAL LETTER Z
 1F170..1F189  ; Uppercase # So  [26] NEGATIVE SQUARED LATIN CAPITAL LETTER A..NEGATIVE SQUARED LATIN CAPITAL LETTER Z
 
-# Total code points: 1908
+# Total code points: 1911
 
 # ================================================
 
@@ -2748,12 +2779,13 @@ A770          ; Cased # Lm       MODIFIER LETTER US
 A771..A787    ; Cased # L&  [23] LATIN SMALL LETTER DUM..LATIN SMALL LETTER INSULAR T
 A78B..A78E    ; Cased # L&   [4] LATIN CAPITAL LETTER SALTILLO..LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT
 A790..A7BF    ; Cased # L&  [48] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER GLOTTAL U
-A7C2..A7C6    ; Cased # L&   [5] LATIN CAPITAL LETTER ANGLICANA W..LATIN CAPITAL LETTER Z WITH PALATAL HOOK
+A7C2..A7CA    ; Cased # L&   [9] LATIN CAPITAL LETTER ANGLICANA W..LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY
+A7F5..A7F6    ; Cased # L&   [2] LATIN CAPITAL LETTER REVERSED HALF H..LATIN SMALL LETTER REVERSED HALF H
 A7F8..A7F9    ; Cased # Lm   [2] MODIFIER LETTER CAPITAL H WITH STROKE..MODIFIER LETTER SMALL LIGATURE OE
 A7FA          ; Cased # L&       LATIN LETTER SMALL CAPITAL TURNED M
 AB30..AB5A    ; Cased # L&  [43] LATIN SMALL LETTER BARRED ALPHA..LATIN SMALL LETTER Y WITH SHORT RIGHT LEG
 AB5C..AB5F    ; Cased # Lm   [4] MODIFIER LETTER SMALL HENG..MODIFIER LETTER SMALL U WITH LEFT HOOK
-AB60..AB67    ; Cased # L&   [8] LATIN SMALL LETTER SAKHA YAT..LATIN SMALL LETTER TS DIGRAPH WITH RETROFLEX HOOK
+AB60..AB68    ; Cased # L&   [9] LATIN SMALL LETTER SAKHA YAT..LATIN SMALL LETTER TURNED R WITH MIDDLE TILDE
 AB70..ABBF    ; Cased # L&  [80] CHEROKEE SMALL LETTER A..CHEROKEE SMALL LETTER YA
 FB00..FB06    ; Cased # L&   [7] LATIN SMALL LIGATURE FF..LATIN SMALL LIGATURE ST
 FB13..FB17    ; Cased # L&   [5] ARMENIAN SMALL LIGATURE MEN NOW..ARMENIAN SMALL LIGATURE MEN XEH
@@ -2801,7 +2833,7 @@ FF41..FF5A    ; Cased # L&  [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN
 1F150..1F169  ; Cased # So  [26] NEGATIVE CIRCLED LATIN CAPITAL LETTER A..NEGATIVE CIRCLED LATIN CAPITAL LETTER Z
 1F170..1F189  ; Cased # So  [26] NEGATIVE SQUARED LATIN CAPITAL LETTER A..NEGATIVE SQUARED LATIN CAPITAL LETTER Z
 
-# Total code points: 4279
+# Total code points: 4286
 
 # ================================================
 
@@ -2841,6 +2873,7 @@ FF41..FF5A    ; Cased # L&  [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN
 0483..0487    ; Case_Ignorable # Mn   [5] COMBINING CYRILLIC TITLO..COMBINING CYRILLIC POKRYTIE
 0488..0489    ; Case_Ignorable # Me   [2] COMBINING CYRILLIC HUNDRED THOUSANDS SIGN..COMBINING CYRILLIC MILLIONS SIGN
 0559          ; Case_Ignorable # Lm       ARMENIAN MODIFIER LETTER LEFT HALF RING
+055F          ; Case_Ignorable # Po       ARMENIAN ABBREVIATION MARK
 0591..05BD    ; Case_Ignorable # Mn  [45] HEBREW ACCENT ETNAHTA..HEBREW POINT METEG
 05BF          ; Case_Ignorable # Mn       HEBREW POINT RAFE
 05C1..05C2    ; Case_Ignorable # Mn   [2] HEBREW POINT SHIN DOT..HEBREW POINT SIN DOT
@@ -2911,7 +2944,7 @@ FF41..FF5A    ; Cased # L&  [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN
 0B3F          ; Case_Ignorable # Mn       ORIYA VOWEL SIGN I
 0B41..0B44    ; Case_Ignorable # Mn   [4] ORIYA VOWEL SIGN U..ORIYA VOWEL SIGN VOCALIC RR
 0B4D          ; Case_Ignorable # Mn       ORIYA SIGN VIRAMA
-0B56          ; Case_Ignorable # Mn       ORIYA AI LENGTH MARK
+0B55..0B56    ; Case_Ignorable # Mn   [2] ORIYA SIGN OVERLINE..ORIYA AI LENGTH MARK
 0B62..0B63    ; Case_Ignorable # Mn   [2] ORIYA VOWEL SIGN VOCALIC L..ORIYA VOWEL SIGN VOCALIC LL
 0B82          ; Case_Ignorable # Mn       TAMIL SIGN ANUSVARA
 0BC0          ; Case_Ignorable # Mn       TAMIL VOWEL SIGN II
@@ -2934,6 +2967,7 @@ FF41..FF5A    ; Cased # L&  [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN
 0D41..0D44    ; Case_Ignorable # Mn   [4] MALAYALAM VOWEL SIGN U..MALAYALAM VOWEL SIGN VOCALIC RR
 0D4D          ; Case_Ignorable # Mn       MALAYALAM SIGN VIRAMA
 0D62..0D63    ; Case_Ignorable # Mn   [2] MALAYALAM VOWEL SIGN VOCALIC L..MALAYALAM VOWEL SIGN VOCALIC LL
+0D81          ; Case_Ignorable # Mn       SINHALA SIGN CANDRABINDU
 0DCA          ; Case_Ignorable # Mn       SINHALA SIGN AL-LAKUNA
 0DD2..0DD4    ; Case_Ignorable # Mn   [3] SINHALA VOWEL SIGN KETTI IS-PILLA..SINHALA VOWEL SIGN KETTI PAA-PILLA
 0DD6          ; Case_Ignorable # Mn       SINHALA VOWEL SIGN DIGA PAA-PILLA
@@ -2999,6 +3033,7 @@ FF41..FF5A    ; Cased # L&  [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN
 1AA7          ; Case_Ignorable # Lm       TAI THAM SIGN MAI YAMOK
 1AB0..1ABD    ; Case_Ignorable # Mn  [14] COMBINING DOUBLED CIRCUMFLEX ACCENT..COMBINING PARENTHESES BELOW
 1ABE          ; Case_Ignorable # Me       COMBINING PARENTHESES OVERLAY
+1ABF..1AC0    ; Case_Ignorable # Mn   [2] COMBINING LATIN SMALL LETTER W BELOW..COMBINING LATIN SMALL LETTER TURNED W BELOW
 1B00..1B03    ; Case_Ignorable # Mn   [4] BALINESE SIGN ULU RICEM..BALINESE SIGN SURANG
 1B34          ; Case_Ignorable # Mn       BALINESE SIGN REREKAN
 1B36..1B3A    ; Case_Ignorable # Mn   [5] BALINESE VOWEL SIGN ULU..BALINESE VOWEL SIGN RA REPA
@@ -3084,6 +3119,7 @@ A802          ; Case_Ignorable # Mn       SYLOTI NAGRI SIGN DVISVARA
 A806          ; Case_Ignorable # Mn       SYLOTI NAGRI SIGN HASANTA
 A80B          ; Case_Ignorable # Mn       SYLOTI NAGRI SIGN ANUSVARA
 A825..A826    ; Case_Ignorable # Mn   [2] SYLOTI NAGRI VOWEL SIGN U..SYLOTI NAGRI VOWEL SIGN E
+A82C          ; Case_Ignorable # Mn       SYLOTI NAGRI SIGN ALTERNATE HASANTA
 A8C4..A8C5    ; Case_Ignorable # Mn   [2] SAURASHTRA SIGN VIRAMA..SAURASHTRA SIGN CANDRABINDU
 A8E0..A8F1    ; Case_Ignorable # Mn  [18] COMBINING DEVANAGARI DIGIT ZERO..COMBINING DEVANAGARI SIGN AVAGRAHA
 A8FF          ; Case_Ignorable # Mn       DEVANAGARI VOWEL SIGN AY
@@ -3114,6 +3150,8 @@ AAF3..AAF4    ; Case_Ignorable # Lm   [2] MEETEI MAYEK SYLLABLE REPETITION MARK.
 AAF6          ; Case_Ignorable # Mn       MEETEI MAYEK VIRAMA
 AB5B          ; Case_Ignorable # Sk       MODIFIER BREVE WITH INVERTED BREVE
 AB5C..AB5F    ; Case_Ignorable # Lm   [4] MODIFIER LETTER SMALL HENG..MODIFIER LETTER SMALL U WITH LEFT HOOK
+AB69          ; Case_Ignorable # Lm       MODIFIER LETTER SMALL TURNED W
+AB6A..AB6B    ; Case_Ignorable # Sk   [2] MODIFIER LETTER LEFT TACK..MODIFIER LETTER RIGHT TACK
 ABE5          ; Case_Ignorable # Mn       MEETEI MAYEK VOWEL SIGN ANAP
 ABE8          ; Case_Ignorable # Mn       MEETEI MAYEK VOWEL SIGN UNAP
 ABED          ; Case_Ignorable # Mn       MEETEI MAYEK APUN IYEK
@@ -3144,6 +3182,7 @@ FFF9..FFFB    ; Case_Ignorable # Cf   [3] INTERLINEAR ANNOTATION ANCHOR..INTERLI
 10A3F         ; Case_Ignorable # Mn       KHAROSHTHI VIRAMA
 10AE5..10AE6  ; Case_Ignorable # Mn   [2] MANICHAEAN ABBREVIATION MARK ABOVE..MANICHAEAN ABBREVIATION MARK BELOW
 10D24..10D27  ; Case_Ignorable # Mn   [4] HANIFI ROHINGYA SIGN HARBAHAY..HANIFI ROHINGYA SIGN TASSI
+10EAB..10EAC  ; Case_Ignorable # Mn   [2] YEZIDI COMBINING HAMZA MARK..YEZIDI COMBINING MADDA MARK
 10F46..10F50  ; Case_Ignorable # Mn  [11] SOGDIAN COMBINING DOT BELOW..SOGDIAN COMBINING STROKE BELOW
 11001         ; Case_Ignorable # Mn       BRAHMI SIGN ANUSVARA
 11038..11046  ; Case_Ignorable # Mn  [15] BRAHMI VOWEL SIGN AA..BRAHMI VIRAMA
@@ -3159,6 +3198,7 @@ FFF9..FFFB    ; Case_Ignorable # Cf   [3] INTERLINEAR ANNOTATION ANCHOR..INTERLI
 11180..11181  ; Case_Ignorable # Mn   [2] SHARADA SIGN CANDRABINDU..SHARADA SIGN ANUSVARA
 111B6..111BE  ; Case_Ignorable # Mn   [9] SHARADA VOWEL SIGN U..SHARADA VOWEL SIGN O
 111C9..111CC  ; Case_Ignorable # Mn   [4] SHARADA SANDHI MARK..SHARADA EXTRA SHORT VOWEL MARK
+111CF         ; Case_Ignorable # Mn       SHARADA SIGN INVERTED CANDRABINDU
 1122F..11231  ; Case_Ignorable # Mn   [3] KHOJKI VOWEL SIGN U..KHOJKI VOWEL SIGN AI
 11234         ; Case_Ignorable # Mn       KHOJKI SIGN ANUSVARA
 11236..11237  ; Case_Ignorable # Mn   [2] KHOJKI SIGN NUKTA..KHOJKI SIGN SHADDA
@@ -3194,6 +3234,9 @@ FFF9..FFFB    ; Case_Ignorable # Cf   [3] INTERLINEAR ANNOTATION ANCHOR..INTERLI
 11727..1172B  ; Case_Ignorable # Mn   [5] AHOM VOWEL SIGN AW..AHOM SIGN KILLER
 1182F..11837  ; Case_Ignorable # Mn   [9] DOGRA VOWEL SIGN U..DOGRA SIGN ANUSVARA
 11839..1183A  ; Case_Ignorable # Mn   [2] DOGRA SIGN VIRAMA..DOGRA SIGN NUKTA
+1193B..1193C  ; Case_Ignorable # Mn   [2] DIVES AKURU SIGN ANUSVARA..DIVES AKURU SIGN CANDRABINDU
+1193E         ; Case_Ignorable # Mn       DIVES AKURU VIRAMA
+11943         ; Case_Ignorable # Mn       DIVES AKURU SIGN NUKTA
 119D4..119D7  ; Case_Ignorable # Mn   [4] NANDINAGARI VOWEL SIGN U..NANDINAGARI VOWEL SIGN VOCALIC RR
 119DA..119DB  ; Case_Ignorable # Mn   [2] NANDINAGARI VOWEL SIGN E..NANDINAGARI VOWEL SIGN AI
 119E0         ; Case_Ignorable # Mn       NANDINAGARI SIGN VIRAMA
@@ -3230,6 +3273,7 @@ FFF9..FFFB    ; Case_Ignorable # Cf   [3] INTERLINEAR ANNOTATION ANCHOR..INTERLI
 16F93..16F9F  ; Case_Ignorable # Lm  [13] MIAO LETTER TONE-2..MIAO LETTER REFORMED TONE-8
 16FE0..16FE1  ; Case_Ignorable # Lm   [2] TANGUT ITERATION MARK..NUSHU ITERATION MARK
 16FE3         ; Case_Ignorable # Lm       OLD CHINESE ITERATION MARK
+16FE4         ; Case_Ignorable # Mn       KHITAN SMALL SCRIPT FILLER
 1BC9D..1BC9E  ; Case_Ignorable # Mn   [2] DUPLOYAN THICK LETTER SELECTOR..DUPLOYAN DOUBLE MARK
 1BCA0..1BCA3  ; Case_Ignorable # Cf   [4] SHORTHAND FORMAT LETTER OVERLAP..SHORTHAND FORMAT UP STEP
 1D167..1D169  ; Case_Ignorable # Mn   [3] MUSICAL SYMBOL COMBINING TREMOLO-1..MUSICAL SYMBOL COMBINING TREMOLO-3
@@ -3260,7 +3304,7 @@ E0001         ; Case_Ignorable # Cf       LANGUAGE TAG
 E0020..E007F  ; Case_Ignorable # Cf  [96] TAG SPACE..CANCEL TAG
 E0100..E01EF  ; Case_Ignorable # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256
 
-# Total code points: 2396
+# Total code points: 2413
 
 # ================================================
 
@@ -3860,7 +3904,9 @@ A7BA          ; Changes_When_Lowercased # L&       LATIN CAPITAL LETTER GLOTTAL
 A7BC          ; Changes_When_Lowercased # L&       LATIN CAPITAL LETTER GLOTTAL I
 A7BE          ; Changes_When_Lowercased # L&       LATIN CAPITAL LETTER GLOTTAL U
 A7C2          ; Changes_When_Lowercased # L&       LATIN CAPITAL LETTER ANGLICANA W
-A7C4..A7C6    ; Changes_When_Lowercased # L&   [3] LATIN CAPITAL LETTER C WITH PALATAL HOOK..LATIN CAPITAL LETTER Z WITH PALATAL HOOK
+A7C4..A7C7    ; Changes_When_Lowercased # L&   [4] LATIN CAPITAL LETTER C WITH PALATAL HOOK..LATIN CAPITAL LETTER D WITH SHORT STROKE OVERLAY
+A7C9          ; Changes_When_Lowercased # L&       LATIN CAPITAL LETTER S WITH SHORT STROKE OVERLAY
+A7F5          ; Changes_When_Lowercased # L&       LATIN CAPITAL LETTER REVERSED HALF H
 FF21..FF3A    ; Changes_When_Lowercased # L&  [26] FULLWIDTH LATIN CAPITAL LETTER A..FULLWIDTH LATIN CAPITAL LETTER Z
 10400..10427  ; Changes_When_Lowercased # L&  [40] DESERET CAPITAL LETTER LONG I..DESERET CAPITAL LETTER EW
 104B0..104D3  ; Changes_When_Lowercased # L&  [36] OSAGE CAPITAL LETTER A..OSAGE CAPITAL LETTER ZHA
@@ -3869,7 +3915,7 @@ FF21..FF3A    ; Changes_When_Lowercased # L&  [26] FULLWIDTH LATIN CAPITAL LETTE
 16E40..16E5F  ; Changes_When_Lowercased # L&  [32] MEDEFAIDRIN CAPITAL LETTER M..MEDEFAIDRIN CAPITAL LETTER Y
 1E900..1E921  ; Changes_When_Lowercased # L&  [34] ADLAM CAPITAL LETTER ALIF..ADLAM CAPITAL LETTER SHA
 
-# Total code points: 1390
+# Total code points: 1393
 
 # ================================================
 
@@ -4483,6 +4529,9 @@ A7BB          ; Changes_When_Uppercased # L&       LATIN SMALL LETTER GLOTTAL A
 A7BD          ; Changes_When_Uppercased # L&       LATIN SMALL LETTER GLOTTAL I
 A7BF          ; Changes_When_Uppercased # L&       LATIN SMALL LETTER GLOTTAL U
 A7C3          ; Changes_When_Uppercased # L&       LATIN SMALL LETTER ANGLICANA W
+A7C8          ; Changes_When_Uppercased # L&       LATIN SMALL LETTER D WITH SHORT STROKE OVERLAY
+A7CA          ; Changes_When_Uppercased # L&       LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY
+A7F6          ; Changes_When_Uppercased # L&       LATIN SMALL LETTER REVERSED HALF H
 AB53          ; Changes_When_Uppercased # L&       LATIN SMALL LETTER CHI
 AB70..ABBF    ; Changes_When_Uppercased # L&  [80] CHEROKEE SMALL LETTER A..CHEROKEE SMALL LETTER YA
 FB00..FB06    ; Changes_When_Uppercased # L&   [7] LATIN SMALL LIGATURE FF..LATIN SMALL LIGATURE ST
@@ -4495,7 +4544,7 @@ FF41..FF5A    ; Changes_When_Uppercased # L&  [26] FULLWIDTH LATIN SMALL LETTER
 16E60..16E7F  ; Changes_When_Uppercased # L&  [32] MEDEFAIDRIN SMALL LETTER M..MEDEFAIDRIN SMALL LETTER Y
 1E922..1E943  ; Changes_When_Uppercased # L&  [34] ADLAM SMALL LETTER ALIF..ADLAM SMALL LETTER SHA
 
-# Total code points: 1482
+# Total code points: 1485
 
 # ================================================
 
@@ -5108,6 +5157,9 @@ A7BB          ; Changes_When_Titlecased # L&       LATIN SMALL LETTER GLOTTAL A
 A7BD          ; Changes_When_Titlecased # L&       LATIN SMALL LETTER GLOTTAL I
 A7BF          ; Changes_When_Titlecased # L&       LATIN SMALL LETTER GLOTTAL U
 A7C3          ; Changes_When_Titlecased # L&       LATIN SMALL LETTER ANGLICANA W
+A7C8          ; Changes_When_Titlecased # L&       LATIN SMALL LETTER D WITH SHORT STROKE OVERLAY
+A7CA          ; Changes_When_Titlecased # L&       LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY
+A7F6          ; Changes_When_Titlecased # L&       LATIN SMALL LETTER REVERSED HALF H
 AB53          ; Changes_When_Titlecased # L&       LATIN SMALL LETTER CHI
 AB70..ABBF    ; Changes_When_Titlecased # L&  [80] CHEROKEE SMALL LETTER A..CHEROKEE SMALL LETTER YA
 FB00..FB06    ; Changes_When_Titlecased # L&   [7] LATIN SMALL LIGATURE FF..LATIN SMALL LIGATURE ST
@@ -5120,7 +5172,7 @@ FF41..FF5A    ; Changes_When_Titlecased # L&  [26] FULLWIDTH LATIN SMALL LETTER
 16E60..16E7F  ; Changes_When_Titlecased # L&  [32] MEDEFAIDRIN SMALL LETTER M..MEDEFAIDRIN SMALL LETTER Y
 1E922..1E943  ; Changes_When_Titlecased # L&  [34] ADLAM SMALL LETTER ALIF..ADLAM SMALL LETTER SHA
 
-# Total code points: 1409
+# Total code points: 1412
 
 # ================================================
 
@@ -5730,7 +5782,9 @@ A7BA          ; Changes_When_Casefolded # L&       LATIN CAPITAL LETTER GLOTTAL
 A7BC          ; Changes_When_Casefolded # L&       LATIN CAPITAL LETTER GLOTTAL I
 A7BE          ; Changes_When_Casefolded # L&       LATIN CAPITAL LETTER GLOTTAL U
 A7C2          ; Changes_When_Casefolded # L&       LATIN CAPITAL LETTER ANGLICANA W
-A7C4..A7C6    ; Changes_When_Casefolded # L&   [3] LATIN CAPITAL LETTER C WITH PALATAL HOOK..LATIN CAPITAL LETTER Z WITH PALATAL HOOK
+A7C4..A7C7    ; Changes_When_Casefolded # L&   [4] LATIN CAPITAL LETTER C WITH PALATAL HOOK..LATIN CAPITAL LETTER D WITH SHORT STROKE OVERLAY
+A7C9          ; Changes_When_Casefolded # L&       LATIN CAPITAL LETTER S WITH SHORT STROKE OVERLAY
+A7F5          ; Changes_When_Casefolded # L&       LATIN CAPITAL LETTER REVERSED HALF H
 AB70..ABBF    ; Changes_When_Casefolded # L&  [80] CHEROKEE SMALL LETTER A..CHEROKEE SMALL LETTER YA
 FB00..FB06    ; Changes_When_Casefolded # L&   [7] LATIN SMALL LIGATURE FF..LATIN SMALL LIGATURE ST
 FB13..FB17    ; Changes_When_Casefolded # L&   [5] ARMENIAN SMALL LIGATURE MEN NOW..ARMENIAN SMALL LIGATURE MEN XEH
@@ -5742,7 +5796,7 @@ FF21..FF3A    ; Changes_When_Casefolded # L&  [26] FULLWIDTH LATIN CAPITAL LETTE
 16E40..16E5F  ; Changes_When_Casefolded # L&  [32] MEDEFAIDRIN CAPITAL LETTER M..MEDEFAIDRIN CAPITAL LETTER Y
 1E900..1E921  ; Changes_When_Casefolded # L&  [34] ADLAM CAPITAL LETTER ALIF..ADLAM CAPITAL LETTER SHA
 
-# Total code points: 1463
+# Total code points: 1466
 
 # ================================================
 
@@ -5859,7 +5913,8 @@ A78B..A78D    ; Changes_When_Casemapped # L&   [3] LATIN CAPITAL LETTER SALTILLO
 A790..A794    ; Changes_When_Casemapped # L&   [5] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER C WITH PALATAL HOOK
 A796..A7AE    ; Changes_When_Casemapped # L&  [25] LATIN CAPITAL LETTER B WITH FLOURISH..LATIN CAPITAL LETTER SMALL CAPITAL I
 A7B0..A7BF    ; Changes_When_Casemapped # L&  [16] LATIN CAPITAL LETTER TURNED K..LATIN SMALL LETTER GLOTTAL U
-A7C2..A7C6    ; Changes_When_Casemapped # L&   [5] LATIN CAPITAL LETTER ANGLICANA W..LATIN CAPITAL LETTER Z WITH PALATAL HOOK
+A7C2..A7CA    ; Changes_When_Casemapped # L&   [9] LATIN CAPITAL LETTER ANGLICANA W..LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY
+A7F5..A7F6    ; Changes_When_Casemapped # L&   [2] LATIN CAPITAL LETTER REVERSED HALF H..LATIN SMALL LETTER REVERSED HALF H
 AB53          ; Changes_When_Casemapped # L&       LATIN SMALL LETTER CHI
 AB70..ABBF    ; Changes_When_Casemapped # L&  [80] CHEROKEE SMALL LETTER A..CHEROKEE SMALL LETTER YA
 FB00..FB06    ; Changes_When_Casemapped # L&   [7] LATIN SMALL LIGATURE FF..LATIN SMALL LIGATURE ST
@@ -5875,7 +5930,7 @@ FF41..FF5A    ; Changes_When_Casemapped # L&  [26] FULLWIDTH LATIN SMALL LETTER
 16E40..16E7F  ; Changes_When_Casemapped # L&  [64] MEDEFAIDRIN CAPITAL LETTER M..MEDEFAIDRIN SMALL LETTER Y
 1E900..1E943  ; Changes_When_Casemapped # L&  [68] ADLAM CAPITAL LETTER ALIF..ADLAM SMALL LETTER SHA
 
-# Total code points: 2841
+# Total code points: 2847
 
 # ================================================
 
@@ -5949,7 +6004,7 @@ FF41..FF5A    ; Changes_When_Casemapped # L&  [26] FULLWIDTH LATIN SMALL LETTER
 0840..0858    ; ID_Start # Lo  [25] MANDAIC LETTER HALQA..MANDAIC LETTER AIN
 0860..086A    ; ID_Start # Lo  [11] SYRIAC LETTER MALAYALAM NGA..SYRIAC LETTER MALAYALAM SSA
 08A0..08B4    ; ID_Start # Lo  [21] ARABIC LETTER BEH WITH SMALL V BELOW..ARABIC LETTER KAF WITH DOT BELOW
-08B6..08BD    ; ID_Start # Lo   [8] ARABIC LETTER BEH WITH SMALL MEEM ABOVE..ARABIC LETTER AFRICAN NOON
+08B6..08C7    ; ID_Start # Lo  [18] ARABIC LETTER BEH WITH SMALL MEEM ABOVE..ARABIC LETTER LAM WITH SMALL ARABIC LETTER TAH ABOVE
 0904..0939    ; ID_Start # Lo  [54] DEVANAGARI LETTER SHORT A..DEVANAGARI LETTER HA
 093D          ; ID_Start # Lo       DEVANAGARI SIGN AVAGRAHA
 0950          ; ID_Start # Lo       DEVANAGARI OM
@@ -6026,7 +6081,7 @@ FF41..FF5A    ; Changes_When_Casemapped # L&  [26] FULLWIDTH LATIN SMALL LETTER
 0CDE          ; ID_Start # Lo       KANNADA LETTER FA
 0CE0..0CE1    ; ID_Start # Lo   [2] KANNADA LETTER VOCALIC RR..KANNADA LETTER VOCALIC LL
 0CF1..0CF2    ; ID_Start # Lo   [2] KANNADA SIGN JIHVAMULIYA..KANNADA SIGN UPADHMANIYA
-0D05..0D0C    ; ID_Start # Lo   [8] MALAYALAM LETTER A..MALAYALAM LETTER VOCALIC L
+0D04..0D0C    ; ID_Start # Lo   [9] MALAYALAM LETTER VEDIC ANUSVARA..MALAYALAM LETTER VOCALIC L
 0D0E..0D10    ; ID_Start # Lo   [3] MALAYALAM LETTER E..MALAYALAM LETTER AI
 0D12..0D3A    ; ID_Start # Lo  [41] MALAYALAM LETTER O..MALAYALAM LETTER TTTA
 0D3D          ; ID_Start # Lo       MALAYALAM SIGN AVAGRAHA
@@ -6225,10 +6280,10 @@ FF41..FF5A    ; Changes_When_Casemapped # L&  [26] FULLWIDTH LATIN SMALL LETTER
 30FF          ; ID_Start # Lo       KATAKANA DIGRAPH KOTO
 3105..312F    ; ID_Start # Lo  [43] BOPOMOFO LETTER B..BOPOMOFO LETTER NN
 3131..318E    ; ID_Start # Lo  [94] HANGUL LETTER KIYEOK..HANGUL LETTER ARAEAE
-31A0..31BA    ; ID_Start # Lo  [27] BOPOMOFO LETTER BU..BOPOMOFO LETTER ZY
+31A0..31BF    ; ID_Start # Lo  [32] BOPOMOFO LETTER BU..BOPOMOFO LETTER AH
 31F0..31FF    ; ID_Start # Lo  [16] KATAKANA LETTER SMALL KU..KATAKANA LETTER SMALL RO
-3400..4DB5    ; ID_Start # Lo [6582] CJK UNIFIED IDEOGRAPH-3400..CJK UNIFIED IDEOGRAPH-4DB5
-4E00..9FEF    ; ID_Start # Lo [20976] CJK UNIFIED IDEOGRAPH-4E00..CJK UNIFIED IDEOGRAPH-9FEF
+3400..4DBF    ; ID_Start # Lo [6592] CJK UNIFIED IDEOGRAPH-3400..CJK UNIFIED IDEOGRAPH-4DBF
+4E00..9FFC    ; ID_Start # Lo [20989] CJK UNIFIED IDEOGRAPH-4E00..CJK UNIFIED IDEOGRAPH-9FFC
 A000..A014    ; ID_Start # Lo  [21] YI SYLLABLE IT..YI SYLLABLE E
 A015          ; ID_Start # Lm       YI SYLLABLE WU
 A016..A48C    ; ID_Start # Lo [1143] YI SYLLABLE BIT..YI SYLLABLE YYR
@@ -6253,7 +6308,8 @@ A788          ; ID_Start # Lm       MODIFIER LETTER LOW CIRCUMFLEX ACCENT
 A78B..A78E    ; ID_Start # L&   [4] LATIN CAPITAL LETTER SALTILLO..LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT
 A78F          ; ID_Start # Lo       LATIN LETTER SINOLOGICAL DOT
 A790..A7BF    ; ID_Start # L&  [48] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER GLOTTAL U
-A7C2..A7C6    ; ID_Start # L&   [5] LATIN CAPITAL LETTER ANGLICANA W..LATIN CAPITAL LETTER Z WITH PALATAL HOOK
+A7C2..A7CA    ; ID_Start # L&   [9] LATIN CAPITAL LETTER ANGLICANA W..LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY
+A7F5..A7F6    ; ID_Start # L&   [2] LATIN CAPITAL LETTER REVERSED HALF H..LATIN SMALL LETTER REVERSED HALF H
 A7F7          ; ID_Start # Lo       LATIN EPIGRAPHIC LETTER SIDEWAYS I
 A7F8..A7F9    ; ID_Start # Lm   [2] MODIFIER LETTER CAPITAL H WITH STROKE..MODIFIER LETTER SMALL LIGATURE OE
 A7FA          ; ID_Start # L&       LATIN LETTER SMALL CAPITAL TURNED M
@@ -6300,7 +6356,8 @@ AB20..AB26    ; ID_Start # Lo   [7] ETHIOPIC SYLLABLE CCHHA..ETHIOPIC SYLLABLE C
 AB28..AB2E    ; ID_Start # Lo   [7] ETHIOPIC SYLLABLE BBA..ETHIOPIC SYLLABLE BBO
 AB30..AB5A    ; ID_Start # L&  [43] LATIN SMALL LETTER BARRED ALPHA..LATIN SMALL LETTER Y WITH SHORT RIGHT LEG
 AB5C..AB5F    ; ID_Start # Lm   [4] MODIFIER LETTER SMALL HENG..MODIFIER LETTER SMALL U WITH LEFT HOOK
-AB60..AB67    ; ID_Start # L&   [8] LATIN SMALL LETTER SAKHA YAT..LATIN SMALL LETTER TS DIGRAPH WITH RETROFLEX HOOK
+AB60..AB68    ; ID_Start # L&   [9] LATIN SMALL LETTER SAKHA YAT..LATIN SMALL LETTER TURNED R WITH MIDDLE TILDE
+AB69          ; ID_Start # Lm       MODIFIER LETTER SMALL TURNED W
 AB70..ABBF    ; ID_Start # L&  [80] CHEROKEE SMALL LETTER A..CHEROKEE SMALL LETTER YA
 ABC0..ABE2    ; ID_Start # Lo  [35] MEETEI MAYEK LETTER KOK..MEETEI MAYEK LETTER I LONSUM
 AC00..D7A3    ; ID_Start # Lo [11172] HANGUL SYLLABLE GA..HANGUL SYLLABLE HIH
@@ -6394,15 +6451,19 @@ FFDA..FFDC    ; ID_Start # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL
 10C80..10CB2  ; ID_Start # L&  [51] OLD HUNGARIAN CAPITAL LETTER A..OLD HUNGARIAN CAPITAL LETTER US
 10CC0..10CF2  ; ID_Start # L&  [51] OLD HUNGARIAN SMALL LETTER A..OLD HUNGARIAN SMALL LETTER US
 10D00..10D23  ; ID_Start # Lo  [36] HANIFI ROHINGYA LETTER A..HANIFI ROHINGYA MARK NA KHONNA
+10E80..10EA9  ; ID_Start # Lo  [42] YEZIDI LETTER ELIF..YEZIDI LETTER ET
+10EB0..10EB1  ; ID_Start # Lo   [2] YEZIDI LETTER LAM WITH DOT ABOVE..YEZIDI LETTER YOT WITH CIRCUMFLEX ABOVE
 10F00..10F1C  ; ID_Start # Lo  [29] OLD SOGDIAN LETTER ALEPH..OLD SOGDIAN LETTER FINAL TAW WITH VERTICAL TAIL
 10F27         ; ID_Start # Lo       OLD SOGDIAN LIGATURE AYIN-DALETH
 10F30..10F45  ; ID_Start # Lo  [22] SOGDIAN LETTER ALEPH..SOGDIAN INDEPENDENT SHIN
+10FB0..10FC4  ; ID_Start # Lo  [21] CHORASMIAN LETTER ALEPH..CHORASMIAN LETTER TAW
 10FE0..10FF6  ; ID_Start # Lo  [23] ELYMAIC LETTER ALEPH..ELYMAIC LIGATURE ZAYIN-YODH
 11003..11037  ; ID_Start # Lo  [53] BRAHMI SIGN JIHVAMULIYA..BRAHMI LETTER OLD TAMIL NNNA
 11083..110AF  ; ID_Start # Lo  [45] KAITHI LETTER A..KAITHI LETTER HA
 110D0..110E8  ; ID_Start # Lo  [25] SORA SOMPENG LETTER SAH..SORA SOMPENG LETTER MAE
 11103..11126  ; ID_Start # Lo  [36] CHAKMA LETTER AA..CHAKMA LETTER HAA
 11144         ; ID_Start # Lo       CHAKMA LETTER LHAA
+11147         ; ID_Start # Lo       CHAKMA LETTER VAA
 11150..11172  ; ID_Start # Lo  [35] MAHAJANI LETTER A..MAHAJANI LETTER RRA
 11176         ; ID_Start # Lo       MAHAJANI LIGATURE SHRI
 11183..111B2  ; ID_Start # Lo  [48] SHARADA LETTER A..SHARADA LETTER HA
@@ -6428,7 +6489,7 @@ FFDA..FFDC    ; ID_Start # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL
 1135D..11361  ; ID_Start # Lo   [5] GRANTHA SIGN PLUTA..GRANTHA LETTER VOCALIC LL
 11400..11434  ; ID_Start # Lo  [53] NEWA LETTER A..NEWA LETTER HA
 11447..1144A  ; ID_Start # Lo   [4] NEWA SIGN AVAGRAHA..NEWA SIDDHI
-1145F         ; ID_Start # Lo       NEWA LETTER VEDIC ANUSVARA
+1145F..11461  ; ID_Start # Lo   [3] NEWA LETTER VEDIC ANUSVARA..NEWA SIGN UPADHMANIYA
 11480..114AF  ; ID_Start # Lo  [48] TIRHUTA ANJI..TIRHUTA LETTER HA
 114C4..114C5  ; ID_Start # Lo   [2] TIRHUTA SIGN AVAGRAHA..TIRHUTA GVANG
 114C7         ; ID_Start # Lo       TIRHUTA OM
@@ -6441,7 +6502,13 @@ FFDA..FFDC    ; ID_Start # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL
 11700..1171A  ; ID_Start # Lo  [27] AHOM LETTER KA..AHOM LETTER ALTERNATE BA
 11800..1182B  ; ID_Start # Lo  [44] DOGRA LETTER A..DOGRA LETTER RRA
 118A0..118DF  ; ID_Start # L&  [64] WARANG CITI CAPITAL LETTER NGAA..WARANG CITI SMALL LETTER VIYO
-118FF         ; ID_Start # Lo       WARANG CITI OM
+118FF..11906  ; ID_Start # Lo   [8] WARANG CITI OM..DIVES AKURU LETTER E
+11909         ; ID_Start # Lo       DIVES AKURU LETTER O
+1190C..11913  ; ID_Start # Lo   [8] DIVES AKURU LETTER KA..DIVES AKURU LETTER JA
+11915..11916  ; ID_Start # Lo   [2] DIVES AKURU LETTER NYA..DIVES AKURU LETTER TTA
+11918..1192F  ; ID_Start # Lo  [24] DIVES AKURU LETTER DDA..DIVES AKURU LETTER ZA
+1193F         ; ID_Start # Lo       DIVES AKURU PREFIXED NASAL SIGN
+11941         ; ID_Start # Lo       DIVES AKURU INITIAL RA
 119A0..119A7  ; ID_Start # Lo   [8] NANDINAGARI LETTER A..NANDINAGARI LETTER VOCALIC RR
 119AA..119D0  ; ID_Start # Lo  [39] NANDINAGARI LETTER E..NANDINAGARI LETTER RRA
 119E1         ; ID_Start # Lo       NANDINAGARI SIGN AVAGRAHA
@@ -6466,6 +6533,7 @@ FFDA..FFDC    ; ID_Start # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL
 11D6A..11D89  ; ID_Start # Lo  [32] GUNJALA GONDI LETTER OO..GUNJALA GONDI LETTER SA
 11D98         ; ID_Start # Lo       GUNJALA GONDI OM
 11EE0..11EF2  ; ID_Start # Lo  [19] MAKASAR LETTER KA..MAKASAR ANGKA
+11FB0         ; ID_Start # Lo       LISU LETTER YHA
 12000..12399  ; ID_Start # Lo [922] CUNEIFORM SIGN A..CUNEIFORM SIGN U U
 12400..1246E  ; ID_Start # Nl [111] CUNEIFORM NUMERIC SIGN TWO ASH..CUNEIFORM NUMERIC SIGN NINE U VARIANT FORM
 12480..12543  ; ID_Start # Lo [196] CUNEIFORM SIGN AB TIMES NUN TENU..CUNEIFORM SIGN ZU5 TIMES THREE DISH TENU
@@ -6485,7 +6553,8 @@ FFDA..FFDC    ; ID_Start # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL
 16FE0..16FE1  ; ID_Start # Lm   [2] TANGUT ITERATION MARK..NUSHU ITERATION MARK
 16FE3         ; ID_Start # Lm       OLD CHINESE ITERATION MARK
 17000..187F7  ; ID_Start # Lo [6136] TANGUT IDEOGRAPH-17000..TANGUT IDEOGRAPH-187F7
-18800..18AF2  ; ID_Start # Lo [755] TANGUT COMPONENT-001..TANGUT COMPONENT-755
+18800..18CD5  ; ID_Start # Lo [1238] TANGUT COMPONENT-001..KHITAN SMALL SCRIPT CHARACTER-18CD5
+18D00..18D08  ; ID_Start # Lo   [9] TANGUT IDEOGRAPH-18D00..TANGUT IDEOGRAPH-18D08
 1B000..1B11E  ; ID_Start # Lo [287] KATAKANA LETTER ARCHAIC E..HENTAIGANA LETTER N-MU-MO-2
 1B150..1B152  ; ID_Start # Lo   [3] HIRAGANA LETTER SMALL WI..HIRAGANA LETTER SMALL WO
 1B164..1B167  ; ID_Start # Lo   [4] KATAKANA LETTER SMALL WI..KATAKANA LETTER SMALL N
@@ -6564,14 +6633,15 @@ FFDA..FFDC    ; ID_Start # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL
 1EEA1..1EEA3  ; ID_Start # Lo   [3] ARABIC MATHEMATICAL DOUBLE-STRUCK BEH..ARABIC MATHEMATICAL DOUBLE-STRUCK DAL
 1EEA5..1EEA9  ; ID_Start # Lo   [5] ARABIC MATHEMATICAL DOUBLE-STRUCK WAW..ARABIC MATHEMATICAL DOUBLE-STRUCK YEH
 1EEAB..1EEBB  ; ID_Start # Lo  [17] ARABIC MATHEMATICAL DOUBLE-STRUCK LAM..ARABIC MATHEMATICAL DOUBLE-STRUCK GHAIN
-20000..2A6D6  ; ID_Start # Lo [42711] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6D6
+20000..2A6DD  ; ID_Start # Lo [42718] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6DD
 2A700..2B734  ; ID_Start # Lo [4149] CJK UNIFIED IDEOGRAPH-2A700..CJK UNIFIED IDEOGRAPH-2B734
 2B740..2B81D  ; ID_Start # Lo [222] CJK UNIFIED IDEOGRAPH-2B740..CJK UNIFIED IDEOGRAPH-2B81D
 2B820..2CEA1  ; ID_Start # Lo [5762] CJK UNIFIED IDEOGRAPH-2B820..CJK UNIFIED IDEOGRAPH-2CEA1
 2CEB0..2EBE0  ; ID_Start # Lo [7473] CJK UNIFIED IDEOGRAPH-2CEB0..CJK UNIFIED IDEOGRAPH-2EBE0
 2F800..2FA1D  ; ID_Start # Lo [542] CJK COMPATIBILITY IDEOGRAPH-2F800..CJK COMPATIBILITY IDEOGRAPH-2FA1D
+30000..3134A  ; ID_Start # Lo [4939] CJK UNIFIED IDEOGRAPH-30000..CJK UNIFIED IDEOGRAPH-3134A
 
-# Total code points: 125884
+# Total code points: 131482
 
 # ================================================
 
@@ -6677,7 +6747,7 @@ FFDA..FFDC    ; ID_Start # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL
 0859..085B    ; ID_Continue # Mn   [3] MANDAIC AFFRICATION MARK..MANDAIC GEMINATION MARK
 0860..086A    ; ID_Continue # Lo  [11] SYRIAC LETTER MALAYALAM NGA..SYRIAC LETTER MALAYALAM SSA
 08A0..08B4    ; ID_Continue # Lo  [21] ARABIC LETTER BEH WITH SMALL V BELOW..ARABIC LETTER KAF WITH DOT BELOW
-08B6..08BD    ; ID_Continue # Lo   [8] ARABIC LETTER BEH WITH SMALL MEEM ABOVE..ARABIC LETTER AFRICAN NOON
+08B6..08C7    ; ID_Continue # Lo  [18] ARABIC LETTER BEH WITH SMALL MEEM ABOVE..ARABIC LETTER LAM WITH SMALL ARABIC LETTER TAH ABOVE
 08D3..08E1    ; ID_Continue # Mn  [15] ARABIC SMALL LOW WAW..ARABIC SMALL HIGH SIGN SAFHA
 08E3..0902    ; ID_Continue # Mn  [32] ARABIC TURNED DAMMA BELOW..DEVANAGARI SIGN ANUSVARA
 0903          ; ID_Continue # Mc       DEVANAGARI SIGN VISARGA
@@ -6782,7 +6852,7 @@ FFDA..FFDC    ; ID_Start # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL
 0B47..0B48    ; ID_Continue # Mc   [2] ORIYA VOWEL SIGN E..ORIYA VOWEL SIGN AI
 0B4B..0B4C    ; ID_Continue # Mc   [2] ORIYA VOWEL SIGN O..ORIYA VOWEL SIGN AU
 0B4D          ; ID_Continue # Mn       ORIYA SIGN VIRAMA
-0B56          ; ID_Continue # Mn       ORIYA AI LENGTH MARK
+0B55..0B56    ; ID_Continue # Mn   [2] ORIYA SIGN OVERLINE..ORIYA AI LENGTH MARK
 0B57          ; ID_Continue # Mc       ORIYA AU LENGTH MARK
 0B5C..0B5D    ; ID_Continue # Lo   [2] ORIYA LETTER RRA..ORIYA LETTER RHA
 0B5F..0B61    ; ID_Continue # Lo   [3] ORIYA LETTER YYA..ORIYA LETTER VOCALIC LL
@@ -6851,7 +6921,7 @@ FFDA..FFDC    ; ID_Start # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL
 0CF1..0CF2    ; ID_Continue # Lo   [2] KANNADA SIGN JIHVAMULIYA..KANNADA SIGN UPADHMANIYA
 0D00..0D01    ; ID_Continue # Mn   [2] MALAYALAM SIGN COMBINING ANUSVARA ABOVE..MALAYALAM SIGN CANDRABINDU
 0D02..0D03    ; ID_Continue # Mc   [2] MALAYALAM SIGN ANUSVARA..MALAYALAM SIGN VISARGA
-0D05..0D0C    ; ID_Continue # Lo   [8] MALAYALAM LETTER A..MALAYALAM LETTER VOCALIC L
+0D04..0D0C    ; ID_Continue # Lo   [9] MALAYALAM LETTER VEDIC ANUSVARA..MALAYALAM LETTER VOCALIC L
 0D0E..0D10    ; ID_Continue # Lo   [3] MALAYALAM LETTER E..MALAYALAM LETTER AI
 0D12..0D3A    ; ID_Continue # Lo  [41] MALAYALAM LETTER O..MALAYALAM LETTER TTTA
 0D3B..0D3C    ; ID_Continue # Mn   [2] MALAYALAM SIGN VERTICAL BAR VIRAMA..MALAYALAM SIGN CIRCULAR VIRAMA
@@ -6868,6 +6938,7 @@ FFDA..FFDC    ; ID_Start # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL
 0D62..0D63    ; ID_Continue # Mn   [2] MALAYALAM VOWEL SIGN VOCALIC L..MALAYALAM VOWEL SIGN VOCALIC LL
 0D66..0D6F    ; ID_Continue # Nd  [10] MALAYALAM DIGIT ZERO..MALAYALAM DIGIT NINE
 0D7A..0D7F    ; ID_Continue # Lo   [6] MALAYALAM LETTER CHILLU NN..MALAYALAM LETTER CHILLU K
+0D81          ; ID_Continue # Mn       SINHALA SIGN CANDRABINDU
 0D82..0D83    ; ID_Continue # Mc   [2] SINHALA SIGN ANUSVARAYA..SINHALA SIGN VISARGAYA
 0D85..0D96    ; ID_Continue # Lo  [18] SINHALA LETTER AYANNA..SINHALA LETTER AUYANNA
 0D9A..0DB1    ; ID_Continue # Lo  [24] SINHALA LETTER ALPAPRAANA KAYANNA..SINHALA LETTER DANTAJA NAYANNA
@@ -7057,6 +7128,7 @@ FFDA..FFDC    ; ID_Start # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL
 1A90..1A99    ; ID_Continue # Nd  [10] TAI THAM THAM DIGIT ZERO..TAI THAM THAM DIGIT NINE
 1AA7          ; ID_Continue # Lm       TAI THAM SIGN MAI YAMOK
 1AB0..1ABD    ; ID_Continue # Mn  [14] COMBINING DOUBLED CIRCUMFLEX ACCENT..COMBINING PARENTHESES BELOW
+1ABF..1AC0    ; ID_Continue # Mn   [2] COMBINING LATIN SMALL LETTER W BELOW..COMBINING LATIN SMALL LETTER TURNED W BELOW
 1B00..1B03    ; ID_Continue # Mn   [4] BALINESE SIGN ULU RICEM..BALINESE SIGN SURANG
 1B04          ; ID_Continue # Mc       BALINESE SIGN BISAH
 1B05..1B33    ; ID_Continue # Lo  [47] BALINESE LETTER AKARA..BALINESE LETTER HA
@@ -7215,10 +7287,10 @@ FFDA..FFDC    ; ID_Start # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL
 30FF          ; ID_Continue # Lo       KATAKANA DIGRAPH KOTO
 3105..312F    ; ID_Continue # Lo  [43] BOPOMOFO LETTER B..BOPOMOFO LETTER NN
 3131..318E    ; ID_Continue # Lo  [94] HANGUL LETTER KIYEOK..HANGUL LETTER ARAEAE
-31A0..31BA    ; ID_Continue # Lo  [27] BOPOMOFO LETTER BU..BOPOMOFO LETTER ZY
+31A0..31BF    ; ID_Continue # Lo  [32] BOPOMOFO LETTER BU..BOPOMOFO LETTER AH
 31F0..31FF    ; ID_Continue # Lo  [16] KATAKANA LETTER SMALL KU..KATAKANA LETTER SMALL RO
-3400..4DB5    ; ID_Continue # Lo [6582] CJK UNIFIED IDEOGRAPH-3400..CJK UNIFIED IDEOGRAPH-4DB5
-4E00..9FEF    ; ID_Continue # Lo [20976] CJK UNIFIED IDEOGRAPH-4E00..CJK UNIFIED IDEOGRAPH-9FEF
+3400..4DBF    ; ID_Continue # Lo [6592] CJK UNIFIED IDEOGRAPH-3400..CJK UNIFIED IDEOGRAPH-4DBF
+4E00..9FFC    ; ID_Continue # Lo [20989] CJK UNIFIED IDEOGRAPH-4E00..CJK UNIFIED IDEOGRAPH-9FFC
 A000..A014    ; ID_Continue # Lo  [21] YI SYLLABLE IT..YI SYLLABLE E
 A015          ; ID_Continue # Lm       YI SYLLABLE WU
 A016..A48C    ; ID_Continue # Lo [1143] YI SYLLABLE BIT..YI SYLLABLE YYR
@@ -7248,7 +7320,8 @@ A788          ; ID_Continue # Lm       MODIFIER LETTER LOW CIRCUMFLEX ACCENT
 A78B..A78E    ; ID_Continue # L&   [4] LATIN CAPITAL LETTER SALTILLO..LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT
 A78F          ; ID_Continue # Lo       LATIN LETTER SINOLOGICAL DOT
 A790..A7BF    ; ID_Continue # L&  [48] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER GLOTTAL U
-A7C2..A7C6    ; ID_Continue # L&   [5] LATIN CAPITAL LETTER ANGLICANA W..LATIN CAPITAL LETTER Z WITH PALATAL HOOK
+A7C2..A7CA    ; ID_Continue # L&   [9] LATIN CAPITAL LETTER ANGLICANA W..LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY
+A7F5..A7F6    ; ID_Continue # L&   [2] LATIN CAPITAL LETTER REVERSED HALF H..LATIN SMALL LETTER REVERSED HALF H
 A7F7          ; ID_Continue # Lo       LATIN EPIGRAPHIC LETTER SIDEWAYS I
 A7F8..A7F9    ; ID_Continue # Lm   [2] MODIFIER LETTER CAPITAL H WITH STROKE..MODIFIER LETTER SMALL LIGATURE OE
 A7FA          ; ID_Continue # L&       LATIN LETTER SMALL CAPITAL TURNED M
@@ -7262,6 +7335,7 @@ A80C..A822    ; ID_Continue # Lo  [23] SYLOTI NAGRI LETTER CO..SYLOTI NAGRI LETT
 A823..A824    ; ID_Continue # Mc   [2] SYLOTI NAGRI VOWEL SIGN A..SYLOTI NAGRI VOWEL SIGN I
 A825..A826    ; ID_Continue # Mn   [2] SYLOTI NAGRI VOWEL SIGN U..SYLOTI NAGRI VOWEL SIGN E
 A827          ; ID_Continue # Mc       SYLOTI NAGRI VOWEL SIGN OO
+A82C          ; ID_Continue # Mn       SYLOTI NAGRI SIGN ALTERNATE HASANTA
 A840..A873    ; ID_Continue # Lo  [52] PHAGS-PA LETTER KA..PHAGS-PA LETTER CANDRABINDU
 A880..A881    ; ID_Continue # Mc   [2] SAURASHTRA SIGN ANUSVARA..SAURASHTRA SIGN VISARGA
 A882..A8B3    ; ID_Continue # Lo  [50] SAURASHTRA LETTER A..SAURASHTRA LETTER LLA
@@ -7344,7 +7418,8 @@ AB20..AB26    ; ID_Continue # Lo   [7] ETHIOPIC SYLLABLE CCHHA..ETHIOPIC SYLLABL
 AB28..AB2E    ; ID_Continue # Lo   [7] ETHIOPIC SYLLABLE BBA..ETHIOPIC SYLLABLE BBO
 AB30..AB5A    ; ID_Continue # L&  [43] LATIN SMALL LETTER BARRED ALPHA..LATIN SMALL LETTER Y WITH SHORT RIGHT LEG
 AB5C..AB5F    ; ID_Continue # Lm   [4] MODIFIER LETTER SMALL HENG..MODIFIER LETTER SMALL U WITH LEFT HOOK
-AB60..AB67    ; ID_Continue # L&   [8] LATIN SMALL LETTER SAKHA YAT..LATIN SMALL LETTER TS DIGRAPH WITH RETROFLEX HOOK
+AB60..AB68    ; ID_Continue # L&   [9] LATIN SMALL LETTER SAKHA YAT..LATIN SMALL LETTER TURNED R WITH MIDDLE TILDE
+AB69          ; ID_Continue # Lm       MODIFIER LETTER SMALL TURNED W
 AB70..ABBF    ; ID_Continue # L&  [80] CHEROKEE SMALL LETTER A..CHEROKEE SMALL LETTER YA
 ABC0..ABE2    ; ID_Continue # Lo  [35] MEETEI MAYEK LETTER KOK..MEETEI MAYEK LETTER I LONSUM
 ABE3..ABE4    ; ID_Continue # Mc   [2] MEETEI MAYEK VOWEL SIGN ONAP..MEETEI MAYEK VOWEL SIGN INAP
@@ -7465,10 +7540,14 @@ FFDA..FFDC    ; ID_Continue # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HAN
 10D00..10D23  ; ID_Continue # Lo  [36] HANIFI ROHINGYA LETTER A..HANIFI ROHINGYA MARK NA KHONNA
 10D24..10D27  ; ID_Continue # Mn   [4] HANIFI ROHINGYA SIGN HARBAHAY..HANIFI ROHINGYA SIGN TASSI
 10D30..10D39  ; ID_Continue # Nd  [10] HANIFI ROHINGYA DIGIT ZERO..HANIFI ROHINGYA DIGIT NINE
+10E80..10EA9  ; ID_Continue # Lo  [42] YEZIDI LETTER ELIF..YEZIDI LETTER ET
+10EAB..10EAC  ; ID_Continue # Mn   [2] YEZIDI COMBINING HAMZA MARK..YEZIDI COMBINING MADDA MARK
+10EB0..10EB1  ; ID_Continue # Lo   [2] YEZIDI LETTER LAM WITH DOT ABOVE..YEZIDI LETTER YOT WITH CIRCUMFLEX ABOVE
 10F00..10F1C  ; ID_Continue # Lo  [29] OLD SOGDIAN LETTER ALEPH..OLD SOGDIAN LETTER FINAL TAW WITH VERTICAL TAIL
 10F27         ; ID_Continue # Lo       OLD SOGDIAN LIGATURE AYIN-DALETH
 10F30..10F45  ; ID_Continue # Lo  [22] SOGDIAN LETTER ALEPH..SOGDIAN INDEPENDENT SHIN
 10F46..10F50  ; ID_Continue # Mn  [11] SOGDIAN COMBINING DOT BELOW..SOGDIAN COMBINING STROKE BELOW
+10FB0..10FC4  ; ID_Continue # Lo  [21] CHORASMIAN LETTER ALEPH..CHORASMIAN LETTER TAW
 10FE0..10FF6  ; ID_Continue # Lo  [23] ELYMAIC LETTER ALEPH..ELYMAIC LIGATURE ZAYIN-YODH
 11000         ; ID_Continue # Mc       BRAHMI SIGN CANDRABINDU
 11001         ; ID_Continue # Mn       BRAHMI SIGN ANUSVARA
@@ -7493,6 +7572,7 @@ FFDA..FFDC    ; ID_Continue # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HAN
 11136..1113F  ; ID_Continue # Nd  [10] CHAKMA DIGIT ZERO..CHAKMA DIGIT NINE
 11144         ; ID_Continue # Lo       CHAKMA LETTER LHAA
 11145..11146  ; ID_Continue # Mc   [2] CHAKMA VOWEL SIGN AA..CHAKMA VOWEL SIGN EI
+11147         ; ID_Continue # Lo       CHAKMA LETTER VAA
 11150..11172  ; ID_Continue # Lo  [35] MAHAJANI LETTER A..MAHAJANI LETTER RRA
 11173         ; ID_Continue # Mn       MAHAJANI SIGN NUKTA
 11176         ; ID_Continue # Lo       MAHAJANI LIGATURE SHRI
@@ -7504,6 +7584,8 @@ FFDA..FFDC    ; ID_Continue # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HAN
 111BF..111C0  ; ID_Continue # Mc   [2] SHARADA VOWEL SIGN AU..SHARADA SIGN VIRAMA
 111C1..111C4  ; ID_Continue # Lo   [4] SHARADA SIGN AVAGRAHA..SHARADA OM
 111C9..111CC  ; ID_Continue # Mn   [4] SHARADA SANDHI MARK..SHARADA EXTRA SHORT VOWEL MARK
+111CE         ; ID_Continue # Mc       SHARADA VOWEL SIGN PRISHTHAMATRA E
+111CF         ; ID_Continue # Mn       SHARADA SIGN INVERTED CANDRABINDU
 111D0..111D9  ; ID_Continue # Nd  [10] SHARADA DIGIT ZERO..SHARADA DIGIT NINE
 111DA         ; ID_Continue # Lo       SHARADA EKAM
 111DC         ; ID_Continue # Lo       SHARADA HEADSTROKE
@@ -7557,7 +7639,7 @@ FFDA..FFDC    ; ID_Continue # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HAN
 11447..1144A  ; ID_Continue # Lo   [4] NEWA SIGN AVAGRAHA..NEWA SIDDHI
 11450..11459  ; ID_Continue # Nd  [10] NEWA DIGIT ZERO..NEWA DIGIT NINE
 1145E         ; ID_Continue # Mn       NEWA SANDHI MARK
-1145F         ; ID_Continue # Lo       NEWA LETTER VEDIC ANUSVARA
+1145F..11461  ; ID_Continue # Lo   [3] NEWA LETTER VEDIC ANUSVARA..NEWA SIGN UPADHMANIYA
 11480..114AF  ; ID_Continue # Lo  [48] TIRHUTA ANJI..TIRHUTA LETTER HA
 114B0..114B2  ; ID_Continue # Mc   [3] TIRHUTA VOWEL SIGN AA..TIRHUTA VOWEL SIGN II
 114B3..114B8  ; ID_Continue # Mn   [6] TIRHUTA VOWEL SIGN U..TIRHUTA VOWEL SIGN VOCALIC LL
@@ -7612,7 +7694,22 @@ FFDA..FFDC    ; ID_Continue # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HAN
 11839..1183A  ; ID_Continue # Mn   [2] DOGRA SIGN VIRAMA..DOGRA SIGN NUKTA
 118A0..118DF  ; ID_Continue # L&  [64] WARANG CITI CAPITAL LETTER NGAA..WARANG CITI SMALL LETTER VIYO
 118E0..118E9  ; ID_Continue # Nd  [10] WARANG CITI DIGIT ZERO..WARANG CITI DIGIT NINE
-118FF         ; ID_Continue # Lo       WARANG CITI OM
+118FF..11906  ; ID_Continue # Lo   [8] WARANG CITI OM..DIVES AKURU LETTER E
+11909         ; ID_Continue # Lo       DIVES AKURU LETTER O
+1190C..11913  ; ID_Continue # Lo   [8] DIVES AKURU LETTER KA..DIVES AKURU LETTER JA
+11915..11916  ; ID_Continue # Lo   [2] DIVES AKURU LETTER NYA..DIVES AKURU LETTER TTA
+11918..1192F  ; ID_Continue # Lo  [24] DIVES AKURU LETTER DDA..DIVES AKURU LETTER ZA
+11930..11935  ; ID_Continue # Mc   [6] DIVES AKURU VOWEL SIGN AA..DIVES AKURU VOWEL SIGN E
+11937..11938  ; ID_Continue # Mc   [2] DIVES AKURU VOWEL SIGN AI..DIVES AKURU VOWEL SIGN O
+1193B..1193C  ; ID_Continue # Mn   [2] DIVES AKURU SIGN ANUSVARA..DIVES AKURU SIGN CANDRABINDU
+1193D         ; ID_Continue # Mc       DIVES AKURU SIGN HALANTA
+1193E         ; ID_Continue # Mn       DIVES AKURU VIRAMA
+1193F         ; ID_Continue # Lo       DIVES AKURU PREFIXED NASAL SIGN
+11940         ; ID_Continue # Mc       DIVES AKURU MEDIAL YA
+11941         ; ID_Continue # Lo       DIVES AKURU INITIAL RA
+11942         ; ID_Continue # Mc       DIVES AKURU MEDIAL RA
+11943         ; ID_Continue # Mn       DIVES AKURU SIGN NUKTA
+11950..11959  ; ID_Continue # Nd  [10] DIVES AKURU DIGIT ZERO..DIVES AKURU DIGIT NINE
 119A0..119A7  ; ID_Continue # Lo   [8] NANDINAGARI LETTER A..NANDINAGARI LETTER VOCALIC RR
 119AA..119D0  ; ID_Continue # Lo  [39] NANDINAGARI LETTER E..NANDINAGARI LETTER RRA
 119D1..119D3  ; ID_Continue # Mc   [3] NANDINAGARI VOWEL SIGN AA..NANDINAGARI VOWEL SIGN II
@@ -7682,6 +7779,7 @@ FFDA..FFDC    ; ID_Continue # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HAN
 11EE0..11EF2  ; ID_Continue # Lo  [19] MAKASAR LETTER KA..MAKASAR ANGKA
 11EF3..11EF4  ; ID_Continue # Mn   [2] MAKASAR VOWEL SIGN I..MAKASAR VOWEL SIGN U
 11EF5..11EF6  ; ID_Continue # Mc   [2] MAKASAR VOWEL SIGN E..MAKASAR VOWEL SIGN O
+11FB0         ; ID_Continue # Lo       LISU LETTER YHA
 12000..12399  ; ID_Continue # Lo [922] CUNEIFORM SIGN A..CUNEIFORM SIGN U U
 12400..1246E  ; ID_Continue # Nl [111] CUNEIFORM NUMERIC SIGN TWO ASH..CUNEIFORM NUMERIC SIGN NINE U VARIANT FORM
 12480..12543  ; ID_Continue # Lo [196] CUNEIFORM SIGN AB TIMES NUN TENU..CUNEIFORM SIGN ZU5 TIMES THREE DISH TENU
@@ -7707,8 +7805,11 @@ FFDA..FFDC    ; ID_Continue # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HAN
 16F93..16F9F  ; ID_Continue # Lm  [13] MIAO LETTER TONE-2..MIAO LETTER REFORMED TONE-8
 16FE0..16FE1  ; ID_Continue # Lm   [2] TANGUT ITERATION MARK..NUSHU ITERATION MARK
 16FE3         ; ID_Continue # Lm       OLD CHINESE ITERATION MARK
+16FE4         ; ID_Continue # Mn       KHITAN SMALL SCRIPT FILLER
+16FF0..16FF1  ; ID_Continue # Mc   [2] VIETNAMESE ALTERNATE READING MARK CA..VIETNAMESE ALTERNATE READING MARK NHAY
 17000..187F7  ; ID_Continue # Lo [6136] TANGUT IDEOGRAPH-17000..TANGUT IDEOGRAPH-187F7
-18800..18AF2  ; ID_Continue # Lo [755] TANGUT COMPONENT-001..TANGUT COMPONENT-755
+18800..18CD5  ; ID_Continue # Lo [1238] TANGUT COMPONENT-001..KHITAN SMALL SCRIPT CHARACTER-18CD5
+18D00..18D08  ; ID_Continue # Lo   [9] TANGUT IDEOGRAPH-18D00..TANGUT IDEOGRAPH-18D08
 1B000..1B11E  ; ID_Continue # Lo [287] KATAKANA LETTER ARCHAIC E..HENTAIGANA LETTER N-MU-MO-2
 1B150..1B152  ; ID_Continue # Lo   [3] HIRAGANA LETTER SMALL WI..HIRAGANA LETTER SMALL WO
 1B164..1B167  ; ID_Continue # Lo   [4] KATAKANA LETTER SMALL WI..KATAKANA LETTER SMALL N
@@ -7814,15 +7915,17 @@ FFDA..FFDC    ; ID_Continue # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HAN
 1EEA1..1EEA3  ; ID_Continue # Lo   [3] ARABIC MATHEMATICAL DOUBLE-STRUCK BEH..ARABIC MATHEMATICAL DOUBLE-STRUCK DAL
 1EEA5..1EEA9  ; ID_Continue # Lo   [5] ARABIC MATHEMATICAL DOUBLE-STRUCK WAW..ARABIC MATHEMATICAL DOUBLE-STRUCK YEH
 1EEAB..1EEBB  ; ID_Continue # Lo  [17] ARABIC MATHEMATICAL DOUBLE-STRUCK LAM..ARABIC MATHEMATICAL DOUBLE-STRUCK GHAIN
-20000..2A6D6  ; ID_Continue # Lo [42711] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6D6
+1FBF0..1FBF9  ; ID_Continue # Nd  [10] SEGMENTED DIGIT ZERO..SEGMENTED DIGIT NINE
+20000..2A6DD  ; ID_Continue # Lo [42718] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6DD
 2A700..2B734  ; ID_Continue # Lo [4149] CJK UNIFIED IDEOGRAPH-2A700..CJK UNIFIED IDEOGRAPH-2B734
 2B740..2B81D  ; ID_Continue # Lo [222] CJK UNIFIED IDEOGRAPH-2B740..CJK UNIFIED IDEOGRAPH-2B81D
 2B820..2CEA1  ; ID_Continue # Lo [5762] CJK UNIFIED IDEOGRAPH-2B820..CJK UNIFIED IDEOGRAPH-2CEA1
 2CEB0..2EBE0  ; ID_Continue # Lo [7473] CJK UNIFIED IDEOGRAPH-2CEB0..CJK UNIFIED IDEOGRAPH-2EBE0
 2F800..2FA1D  ; ID_Continue # Lo [542] CJK COMPATIBILITY IDEOGRAPH-2F800..CJK COMPATIBILITY IDEOGRAPH-2FA1D
+30000..3134A  ; ID_Continue # Lo [4939] CJK UNIFIED IDEOGRAPH-30000..CJK UNIFIED IDEOGRAPH-3134A
 E0100..E01EF  ; ID_Continue # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256
 
-# Total code points: 128789
+# Total code points: 134434
 
 # ================================================
 
@@ -7893,7 +7996,7 @@ E0100..E01EF  ; ID_Continue # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR
 0840..0858    ; XID_Start # Lo  [25] MANDAIC LETTER HALQA..MANDAIC LETTER AIN
 0860..086A    ; XID_Start # Lo  [11] SYRIAC LETTER MALAYALAM NGA..SYRIAC LETTER MALAYALAM SSA
 08A0..08B4    ; XID_Start # Lo  [21] ARABIC LETTER BEH WITH SMALL V BELOW..ARABIC LETTER KAF WITH DOT BELOW
-08B6..08BD    ; XID_Start # Lo   [8] ARABIC LETTER BEH WITH SMALL MEEM ABOVE..ARABIC LETTER AFRICAN NOON
+08B6..08C7    ; XID_Start # Lo  [18] ARABIC LETTER BEH WITH SMALL MEEM ABOVE..ARABIC LETTER LAM WITH SMALL ARABIC LETTER TAH ABOVE
 0904..0939    ; XID_Start # Lo  [54] DEVANAGARI LETTER SHORT A..DEVANAGARI LETTER HA
 093D          ; XID_Start # Lo       DEVANAGARI SIGN AVAGRAHA
 0950          ; XID_Start # Lo       DEVANAGARI OM
@@ -7970,7 +8073,7 @@ E0100..E01EF  ; ID_Continue # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR
 0CDE          ; XID_Start # Lo       KANNADA LETTER FA
 0CE0..0CE1    ; XID_Start # Lo   [2] KANNADA LETTER VOCALIC RR..KANNADA LETTER VOCALIC LL
 0CF1..0CF2    ; XID_Start # Lo   [2] KANNADA SIGN JIHVAMULIYA..KANNADA SIGN UPADHMANIYA
-0D05..0D0C    ; XID_Start # Lo   [8] MALAYALAM LETTER A..MALAYALAM LETTER VOCALIC L
+0D04..0D0C    ; XID_Start # Lo   [9] MALAYALAM LETTER VEDIC ANUSVARA..MALAYALAM LETTER VOCALIC L
 0D0E..0D10    ; XID_Start # Lo   [3] MALAYALAM LETTER E..MALAYALAM LETTER AI
 0D12..0D3A    ; XID_Start # Lo  [41] MALAYALAM LETTER O..MALAYALAM LETTER TTTA
 0D3D          ; XID_Start # Lo       MALAYALAM SIGN AVAGRAHA
@@ -8168,10 +8271,10 @@ E0100..E01EF  ; ID_Continue # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR
 30FF          ; XID_Start # Lo       KATAKANA DIGRAPH KOTO
 3105..312F    ; XID_Start # Lo  [43] BOPOMOFO LETTER B..BOPOMOFO LETTER NN
 3131..318E    ; XID_Start # Lo  [94] HANGUL LETTER KIYEOK..HANGUL LETTER ARAEAE
-31A0..31BA    ; XID_Start # Lo  [27] BOPOMOFO LETTER BU..BOPOMOFO LETTER ZY
+31A0..31BF    ; XID_Start # Lo  [32] BOPOMOFO LETTER BU..BOPOMOFO LETTER AH
 31F0..31FF    ; XID_Start # Lo  [16] KATAKANA LETTER SMALL KU..KATAKANA LETTER SMALL RO
-3400..4DB5    ; XID_Start # Lo [6582] CJK UNIFIED IDEOGRAPH-3400..CJK UNIFIED IDEOGRAPH-4DB5
-4E00..9FEF    ; XID_Start # Lo [20976] CJK UNIFIED IDEOGRAPH-4E00..CJK UNIFIED IDEOGRAPH-9FEF
+3400..4DBF    ; XID_Start # Lo [6592] CJK UNIFIED IDEOGRAPH-3400..CJK UNIFIED IDEOGRAPH-4DBF
+4E00..9FFC    ; XID_Start # Lo [20989] CJK UNIFIED IDEOGRAPH-4E00..CJK UNIFIED IDEOGRAPH-9FFC
 A000..A014    ; XID_Start # Lo  [21] YI SYLLABLE IT..YI SYLLABLE E
 A015          ; XID_Start # Lm       YI SYLLABLE WU
 A016..A48C    ; XID_Start # Lo [1143] YI SYLLABLE BIT..YI SYLLABLE YYR
@@ -8196,7 +8299,8 @@ A788          ; XID_Start # Lm       MODIFIER LETTER LOW CIRCUMFLEX ACCENT
 A78B..A78E    ; XID_Start # L&   [4] LATIN CAPITAL LETTER SALTILLO..LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT
 A78F          ; XID_Start # Lo       LATIN LETTER SINOLOGICAL DOT
 A790..A7BF    ; XID_Start # L&  [48] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER GLOTTAL U
-A7C2..A7C6    ; XID_Start # L&   [5] LATIN CAPITAL LETTER ANGLICANA W..LATIN CAPITAL LETTER Z WITH PALATAL HOOK
+A7C2..A7CA    ; XID_Start # L&   [9] LATIN CAPITAL LETTER ANGLICANA W..LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY
+A7F5..A7F6    ; XID_Start # L&   [2] LATIN CAPITAL LETTER REVERSED HALF H..LATIN SMALL LETTER REVERSED HALF H
 A7F7          ; XID_Start # Lo       LATIN EPIGRAPHIC LETTER SIDEWAYS I
 A7F8..A7F9    ; XID_Start # Lm   [2] MODIFIER LETTER CAPITAL H WITH STROKE..MODIFIER LETTER SMALL LIGATURE OE
 A7FA          ; XID_Start # L&       LATIN LETTER SMALL CAPITAL TURNED M
@@ -8243,7 +8347,8 @@ AB20..AB26    ; XID_Start # Lo   [7] ETHIOPIC SYLLABLE CCHHA..ETHIOPIC SYLLABLE
 AB28..AB2E    ; XID_Start # Lo   [7] ETHIOPIC SYLLABLE BBA..ETHIOPIC SYLLABLE BBO
 AB30..AB5A    ; XID_Start # L&  [43] LATIN SMALL LETTER BARRED ALPHA..LATIN SMALL LETTER Y WITH SHORT RIGHT LEG
 AB5C..AB5F    ; XID_Start # Lm   [4] MODIFIER LETTER SMALL HENG..MODIFIER LETTER SMALL U WITH LEFT HOOK
-AB60..AB67    ; XID_Start # L&   [8] LATIN SMALL LETTER SAKHA YAT..LATIN SMALL LETTER TS DIGRAPH WITH RETROFLEX HOOK
+AB60..AB68    ; XID_Start # L&   [9] LATIN SMALL LETTER SAKHA YAT..LATIN SMALL LETTER TURNED R WITH MIDDLE TILDE
+AB69          ; XID_Start # Lm       MODIFIER LETTER SMALL TURNED W
 AB70..ABBF    ; XID_Start # L&  [80] CHEROKEE SMALL LETTER A..CHEROKEE SMALL LETTER YA
 ABC0..ABE2    ; XID_Start # Lo  [35] MEETEI MAYEK LETTER KOK..MEETEI MAYEK LETTER I LONSUM
 AC00..D7A3    ; XID_Start # Lo [11172] HANGUL SYLLABLE GA..HANGUL SYLLABLE HIH
@@ -8342,15 +8447,19 @@ FFDA..FFDC    ; XID_Start # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGU
 10C80..10CB2  ; XID_Start # L&  [51] OLD HUNGARIAN CAPITAL LETTER A..OLD HUNGARIAN CAPITAL LETTER US
 10CC0..10CF2  ; XID_Start # L&  [51] OLD HUNGARIAN SMALL LETTER A..OLD HUNGARIAN SMALL LETTER US
 10D00..10D23  ; XID_Start # Lo  [36] HANIFI ROHINGYA LETTER A..HANIFI ROHINGYA MARK NA KHONNA
+10E80..10EA9  ; XID_Start # Lo  [42] YEZIDI LETTER ELIF..YEZIDI LETTER ET
+10EB0..10EB1  ; XID_Start # Lo   [2] YEZIDI LETTER LAM WITH DOT ABOVE..YEZIDI LETTER YOT WITH CIRCUMFLEX ABOVE
 10F00..10F1C  ; XID_Start # Lo  [29] OLD SOGDIAN LETTER ALEPH..OLD SOGDIAN LETTER FINAL TAW WITH VERTICAL TAIL
 10F27         ; XID_Start # Lo       OLD SOGDIAN LIGATURE AYIN-DALETH
 10F30..10F45  ; XID_Start # Lo  [22] SOGDIAN LETTER ALEPH..SOGDIAN INDEPENDENT SHIN
+10FB0..10FC4  ; XID_Start # Lo  [21] CHORASMIAN LETTER ALEPH..CHORASMIAN LETTER TAW
 10FE0..10FF6  ; XID_Start # Lo  [23] ELYMAIC LETTER ALEPH..ELYMAIC LIGATURE ZAYIN-YODH
 11003..11037  ; XID_Start # Lo  [53] BRAHMI SIGN JIHVAMULIYA..BRAHMI LETTER OLD TAMIL NNNA
 11083..110AF  ; XID_Start # Lo  [45] KAITHI LETTER A..KAITHI LETTER HA
 110D0..110E8  ; XID_Start # Lo  [25] SORA SOMPENG LETTER SAH..SORA SOMPENG LETTER MAE
 11103..11126  ; XID_Start # Lo  [36] CHAKMA LETTER AA..CHAKMA LETTER HAA
 11144         ; XID_Start # Lo       CHAKMA LETTER LHAA
+11147         ; XID_Start # Lo       CHAKMA LETTER VAA
 11150..11172  ; XID_Start # Lo  [35] MAHAJANI LETTER A..MAHAJANI LETTER RRA
 11176         ; XID_Start # Lo       MAHAJANI LIGATURE SHRI
 11183..111B2  ; XID_Start # Lo  [48] SHARADA LETTER A..SHARADA LETTER HA
@@ -8376,7 +8485,7 @@ FFDA..FFDC    ; XID_Start # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGU
 1135D..11361  ; XID_Start # Lo   [5] GRANTHA SIGN PLUTA..GRANTHA LETTER VOCALIC LL
 11400..11434  ; XID_Start # Lo  [53] NEWA LETTER A..NEWA LETTER HA
 11447..1144A  ; XID_Start # Lo   [4] NEWA SIGN AVAGRAHA..NEWA SIDDHI
-1145F         ; XID_Start # Lo       NEWA LETTER VEDIC ANUSVARA
+1145F..11461  ; XID_Start # Lo   [3] NEWA LETTER VEDIC ANUSVARA..NEWA SIGN UPADHMANIYA
 11480..114AF  ; XID_Start # Lo  [48] TIRHUTA ANJI..TIRHUTA LETTER HA
 114C4..114C5  ; XID_Start # Lo   [2] TIRHUTA SIGN AVAGRAHA..TIRHUTA GVANG
 114C7         ; XID_Start # Lo       TIRHUTA OM
@@ -8389,7 +8498,13 @@ FFDA..FFDC    ; XID_Start # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGU
 11700..1171A  ; XID_Start # Lo  [27] AHOM LETTER KA..AHOM LETTER ALTERNATE BA
 11800..1182B  ; XID_Start # Lo  [44] DOGRA LETTER A..DOGRA LETTER RRA
 118A0..118DF  ; XID_Start # L&  [64] WARANG CITI CAPITAL LETTER NGAA..WARANG CITI SMALL LETTER VIYO
-118FF         ; XID_Start # Lo       WARANG CITI OM
+118FF..11906  ; XID_Start # Lo   [8] WARANG CITI OM..DIVES AKURU LETTER E
+11909         ; XID_Start # Lo       DIVES AKURU LETTER O
+1190C..11913  ; XID_Start # Lo   [8] DIVES AKURU LETTER KA..DIVES AKURU LETTER JA
+11915..11916  ; XID_Start # Lo   [2] DIVES AKURU LETTER NYA..DIVES AKURU LETTER TTA
+11918..1192F  ; XID_Start # Lo  [24] DIVES AKURU LETTER DDA..DIVES AKURU LETTER ZA
+1193F         ; XID_Start # Lo       DIVES AKURU PREFIXED NASAL SIGN
+11941         ; XID_Start # Lo       DIVES AKURU INITIAL RA
 119A0..119A7  ; XID_Start # Lo   [8] NANDINAGARI LETTER A..NANDINAGARI LETTER VOCALIC RR
 119AA..119D0  ; XID_Start # Lo  [39] NANDINAGARI LETTER E..NANDINAGARI LETTER RRA
 119E1         ; XID_Start # Lo       NANDINAGARI SIGN AVAGRAHA
@@ -8414,6 +8529,7 @@ FFDA..FFDC    ; XID_Start # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGU
 11D6A..11D89  ; XID_Start # Lo  [32] GUNJALA GONDI LETTER OO..GUNJALA GONDI LETTER SA
 11D98         ; XID_Start # Lo       GUNJALA GONDI OM
 11EE0..11EF2  ; XID_Start # Lo  [19] MAKASAR LETTER KA..MAKASAR ANGKA
+11FB0         ; XID_Start # Lo       LISU LETTER YHA
 12000..12399  ; XID_Start # Lo [922] CUNEIFORM SIGN A..CUNEIFORM SIGN U U
 12400..1246E  ; XID_Start # Nl [111] CUNEIFORM NUMERIC SIGN TWO ASH..CUNEIFORM NUMERIC SIGN NINE U VARIANT FORM
 12480..12543  ; XID_Start # Lo [196] CUNEIFORM SIGN AB TIMES NUN TENU..CUNEIFORM SIGN ZU5 TIMES THREE DISH TENU
@@ -8433,7 +8549,8 @@ FFDA..FFDC    ; XID_Start # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGU
 16FE0..16FE1  ; XID_Start # Lm   [2] TANGUT ITERATION MARK..NUSHU ITERATION MARK
 16FE3         ; XID_Start # Lm       OLD CHINESE ITERATION MARK
 17000..187F7  ; XID_Start # Lo [6136] TANGUT IDEOGRAPH-17000..TANGUT IDEOGRAPH-187F7
-18800..18AF2  ; XID_Start # Lo [755] TANGUT COMPONENT-001..TANGUT COMPONENT-755
+18800..18CD5  ; XID_Start # Lo [1238] TANGUT COMPONENT-001..KHITAN SMALL SCRIPT CHARACTER-18CD5
+18D00..18D08  ; XID_Start # Lo   [9] TANGUT IDEOGRAPH-18D00..TANGUT IDEOGRAPH-18D08
 1B000..1B11E  ; XID_Start # Lo [287] KATAKANA LETTER ARCHAIC E..HENTAIGANA LETTER N-MU-MO-2
 1B150..1B152  ; XID_Start # Lo   [3] HIRAGANA LETTER SMALL WI..HIRAGANA LETTER SMALL WO
 1B164..1B167  ; XID_Start # Lo   [4] KATAKANA LETTER SMALL WI..KATAKANA LETTER SMALL N
@@ -8512,14 +8629,15 @@ FFDA..FFDC    ; XID_Start # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGU
 1EEA1..1EEA3  ; XID_Start # Lo   [3] ARABIC MATHEMATICAL DOUBLE-STRUCK BEH..ARABIC MATHEMATICAL DOUBLE-STRUCK DAL
 1EEA5..1EEA9  ; XID_Start # Lo   [5] ARABIC MATHEMATICAL DOUBLE-STRUCK WAW..ARABIC MATHEMATICAL DOUBLE-STRUCK YEH
 1EEAB..1EEBB  ; XID_Start # Lo  [17] ARABIC MATHEMATICAL DOUBLE-STRUCK LAM..ARABIC MATHEMATICAL DOUBLE-STRUCK GHAIN
-20000..2A6D6  ; XID_Start # Lo [42711] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6D6
+20000..2A6DD  ; XID_Start # Lo [42718] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6DD
 2A700..2B734  ; XID_Start # Lo [4149] CJK UNIFIED IDEOGRAPH-2A700..CJK UNIFIED IDEOGRAPH-2B734
 2B740..2B81D  ; XID_Start # Lo [222] CJK UNIFIED IDEOGRAPH-2B740..CJK UNIFIED IDEOGRAPH-2B81D
 2B820..2CEA1  ; XID_Start # Lo [5762] CJK UNIFIED IDEOGRAPH-2B820..CJK UNIFIED IDEOGRAPH-2CEA1
 2CEB0..2EBE0  ; XID_Start # Lo [7473] CJK UNIFIED IDEOGRAPH-2CEB0..CJK UNIFIED IDEOGRAPH-2EBE0
 2F800..2FA1D  ; XID_Start # Lo [542] CJK COMPATIBILITY IDEOGRAPH-2F800..CJK COMPATIBILITY IDEOGRAPH-2FA1D
+30000..3134A  ; XID_Start # Lo [4939] CJK UNIFIED IDEOGRAPH-30000..CJK UNIFIED IDEOGRAPH-3134A
 
-# Total code points: 125861
+# Total code points: 131459
 
 # ================================================
 
@@ -8621,7 +8739,7 @@ FFDA..FFDC    ; XID_Start # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGU
 0859..085B    ; XID_Continue # Mn   [3] MANDAIC AFFRICATION MARK..MANDAIC GEMINATION MARK
 0860..086A    ; XID_Continue # Lo  [11] SYRIAC LETTER MALAYALAM NGA..SYRIAC LETTER MALAYALAM SSA
 08A0..08B4    ; XID_Continue # Lo  [21] ARABIC LETTER BEH WITH SMALL V BELOW..ARABIC LETTER KAF WITH DOT BELOW
-08B6..08BD    ; XID_Continue # Lo   [8] ARABIC LETTER BEH WITH SMALL MEEM ABOVE..ARABIC LETTER AFRICAN NOON
+08B6..08C7    ; XID_Continue # Lo  [18] ARABIC LETTER BEH WITH SMALL MEEM ABOVE..ARABIC LETTER LAM WITH SMALL ARABIC LETTER TAH ABOVE
 08D3..08E1    ; XID_Continue # Mn  [15] ARABIC SMALL LOW WAW..ARABIC SMALL HIGH SIGN SAFHA
 08E3..0902    ; XID_Continue # Mn  [32] ARABIC TURNED DAMMA BELOW..DEVANAGARI SIGN ANUSVARA
 0903          ; XID_Continue # Mc       DEVANAGARI SIGN VISARGA
@@ -8726,7 +8844,7 @@ FFDA..FFDC    ; XID_Start # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGU
 0B47..0B48    ; XID_Continue # Mc   [2] ORIYA VOWEL SIGN E..ORIYA VOWEL SIGN AI
 0B4B..0B4C    ; XID_Continue # Mc   [2] ORIYA VOWEL SIGN O..ORIYA VOWEL SIGN AU
 0B4D          ; XID_Continue # Mn       ORIYA SIGN VIRAMA
-0B56          ; XID_Continue # Mn       ORIYA AI LENGTH MARK
+0B55..0B56    ; XID_Continue # Mn   [2] ORIYA SIGN OVERLINE..ORIYA AI LENGTH MARK
 0B57          ; XID_Continue # Mc       ORIYA AU LENGTH MARK
 0B5C..0B5D    ; XID_Continue # Lo   [2] ORIYA LETTER RRA..ORIYA LETTER RHA
 0B5F..0B61    ; XID_Continue # Lo   [3] ORIYA LETTER YYA..ORIYA LETTER VOCALIC LL
@@ -8795,7 +8913,7 @@ FFDA..FFDC    ; XID_Start # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGU
 0CF1..0CF2    ; XID_Continue # Lo   [2] KANNADA SIGN JIHVAMULIYA..KANNADA SIGN UPADHMANIYA
 0D00..0D01    ; XID_Continue # Mn   [2] MALAYALAM SIGN COMBINING ANUSVARA ABOVE..MALAYALAM SIGN CANDRABINDU
 0D02..0D03    ; XID_Continue # Mc   [2] MALAYALAM SIGN ANUSVARA..MALAYALAM SIGN VISARGA
-0D05..0D0C    ; XID_Continue # Lo   [8] MALAYALAM LETTER A..MALAYALAM LETTER VOCALIC L
+0D04..0D0C    ; XID_Continue # Lo   [9] MALAYALAM LETTER VEDIC ANUSVARA..MALAYALAM LETTER VOCALIC L
 0D0E..0D10    ; XID_Continue # Lo   [3] MALAYALAM LETTER E..MALAYALAM LETTER AI
 0D12..0D3A    ; XID_Continue # Lo  [41] MALAYALAM LETTER O..MALAYALAM LETTER TTTA
 0D3B..0D3C    ; XID_Continue # Mn   [2] MALAYALAM SIGN VERTICAL BAR VIRAMA..MALAYALAM SIGN CIRCULAR VIRAMA
@@ -8812,6 +8930,7 @@ FFDA..FFDC    ; XID_Start # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGU
 0D62..0D63    ; XID_Continue # Mn   [2] MALAYALAM VOWEL SIGN VOCALIC L..MALAYALAM VOWEL SIGN VOCALIC LL
 0D66..0D6F    ; XID_Continue # Nd  [10] MALAYALAM DIGIT ZERO..MALAYALAM DIGIT NINE
 0D7A..0D7F    ; XID_Continue # Lo   [6] MALAYALAM LETTER CHILLU NN..MALAYALAM LETTER CHILLU K
+0D81          ; XID_Continue # Mn       SINHALA SIGN CANDRABINDU
 0D82..0D83    ; XID_Continue # Mc   [2] SINHALA SIGN ANUSVARAYA..SINHALA SIGN VISARGAYA
 0D85..0D96    ; XID_Continue # Lo  [18] SINHALA LETTER AYANNA..SINHALA LETTER AUYANNA
 0D9A..0DB1    ; XID_Continue # Lo  [24] SINHALA LETTER ALPAPRAANA KAYANNA..SINHALA LETTER DANTAJA NAYANNA
@@ -9001,6 +9120,7 @@ FFDA..FFDC    ; XID_Start # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGU
 1A90..1A99    ; XID_Continue # Nd  [10] TAI THAM THAM DIGIT ZERO..TAI THAM THAM DIGIT NINE
 1AA7          ; XID_Continue # Lm       TAI THAM SIGN MAI YAMOK
 1AB0..1ABD    ; XID_Continue # Mn  [14] COMBINING DOUBLED CIRCUMFLEX ACCENT..COMBINING PARENTHESES BELOW
+1ABF..1AC0    ; XID_Continue # Mn   [2] COMBINING LATIN SMALL LETTER W BELOW..COMBINING LATIN SMALL LETTER TURNED W BELOW
 1B00..1B03    ; XID_Continue # Mn   [4] BALINESE SIGN ULU RICEM..BALINESE SIGN SURANG
 1B04          ; XID_Continue # Mc       BALINESE SIGN BISAH
 1B05..1B33    ; XID_Continue # Lo  [47] BALINESE LETTER AKARA..BALINESE LETTER HA
@@ -9158,10 +9278,10 @@ FFDA..FFDC    ; XID_Start # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGU
 30FF          ; XID_Continue # Lo       KATAKANA DIGRAPH KOTO
 3105..312F    ; XID_Continue # Lo  [43] BOPOMOFO LETTER B..BOPOMOFO LETTER NN
 3131..318E    ; XID_Continue # Lo  [94] HANGUL LETTER KIYEOK..HANGUL LETTER ARAEAE
-31A0..31BA    ; XID_Continue # Lo  [27] BOPOMOFO LETTER BU..BOPOMOFO LETTER ZY
+31A0..31BF    ; XID_Continue # Lo  [32] BOPOMOFO LETTER BU..BOPOMOFO LETTER AH
 31F0..31FF    ; XID_Continue # Lo  [16] KATAKANA LETTER SMALL KU..KATAKANA LETTER SMALL RO
-3400..4DB5    ; XID_Continue # Lo [6582] CJK UNIFIED IDEOGRAPH-3400..CJK UNIFIED IDEOGRAPH-4DB5
-4E00..9FEF    ; XID_Continue # Lo [20976] CJK UNIFIED IDEOGRAPH-4E00..CJK UNIFIED IDEOGRAPH-9FEF
+3400..4DBF    ; XID_Continue # Lo [6592] CJK UNIFIED IDEOGRAPH-3400..CJK UNIFIED IDEOGRAPH-4DBF
+4E00..9FFC    ; XID_Continue # Lo [20989] CJK UNIFIED IDEOGRAPH-4E00..CJK UNIFIED IDEOGRAPH-9FFC
 A000..A014    ; XID_Continue # Lo  [21] YI SYLLABLE IT..YI SYLLABLE E
 A015          ; XID_Continue # Lm       YI SYLLABLE WU
 A016..A48C    ; XID_Continue # Lo [1143] YI SYLLABLE BIT..YI SYLLABLE YYR
@@ -9191,7 +9311,8 @@ A788          ; XID_Continue # Lm       MODIFIER LETTER LOW CIRCUMFLEX ACCENT
 A78B..A78E    ; XID_Continue # L&   [4] LATIN CAPITAL LETTER SALTILLO..LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT
 A78F          ; XID_Continue # Lo       LATIN LETTER SINOLOGICAL DOT
 A790..A7BF    ; XID_Continue # L&  [48] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER GLOTTAL U
-A7C2..A7C6    ; XID_Continue # L&   [5] LATIN CAPITAL LETTER ANGLICANA W..LATIN CAPITAL LETTER Z WITH PALATAL HOOK
+A7C2..A7CA    ; XID_Continue # L&   [9] LATIN CAPITAL LETTER ANGLICANA W..LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY
+A7F5..A7F6    ; XID_Continue # L&   [2] LATIN CAPITAL LETTER REVERSED HALF H..LATIN SMALL LETTER REVERSED HALF H
 A7F7          ; XID_Continue # Lo       LATIN EPIGRAPHIC LETTER SIDEWAYS I
 A7F8..A7F9    ; XID_Continue # Lm   [2] MODIFIER LETTER CAPITAL H WITH STROKE..MODIFIER LETTER SMALL LIGATURE OE
 A7FA          ; XID_Continue # L&       LATIN LETTER SMALL CAPITAL TURNED M
@@ -9205,6 +9326,7 @@ A80C..A822    ; XID_Continue # Lo  [23] SYLOTI NAGRI LETTER CO..SYLOTI NAGRI LET
 A823..A824    ; XID_Continue # Mc   [2] SYLOTI NAGRI VOWEL SIGN A..SYLOTI NAGRI VOWEL SIGN I
 A825..A826    ; XID_Continue # Mn   [2] SYLOTI NAGRI VOWEL SIGN U..SYLOTI NAGRI VOWEL SIGN E
 A827          ; XID_Continue # Mc       SYLOTI NAGRI VOWEL SIGN OO
+A82C          ; XID_Continue # Mn       SYLOTI NAGRI SIGN ALTERNATE HASANTA
 A840..A873    ; XID_Continue # Lo  [52] PHAGS-PA LETTER KA..PHAGS-PA LETTER CANDRABINDU
 A880..A881    ; XID_Continue # Mc   [2] SAURASHTRA SIGN ANUSVARA..SAURASHTRA SIGN VISARGA
 A882..A8B3    ; XID_Continue # Lo  [50] SAURASHTRA LETTER A..SAURASHTRA LETTER LLA
@@ -9287,7 +9409,8 @@ AB20..AB26    ; XID_Continue # Lo   [7] ETHIOPIC SYLLABLE CCHHA..ETHIOPIC SYLLAB
 AB28..AB2E    ; XID_Continue # Lo   [7] ETHIOPIC SYLLABLE BBA..ETHIOPIC SYLLABLE BBO
 AB30..AB5A    ; XID_Continue # L&  [43] LATIN SMALL LETTER BARRED ALPHA..LATIN SMALL LETTER Y WITH SHORT RIGHT LEG
 AB5C..AB5F    ; XID_Continue # Lm   [4] MODIFIER LETTER SMALL HENG..MODIFIER LETTER SMALL U WITH LEFT HOOK
-AB60..AB67    ; XID_Continue # L&   [8] LATIN SMALL LETTER SAKHA YAT..LATIN SMALL LETTER TS DIGRAPH WITH RETROFLEX HOOK
+AB60..AB68    ; XID_Continue # L&   [9] LATIN SMALL LETTER SAKHA YAT..LATIN SMALL LETTER TURNED R WITH MIDDLE TILDE
+AB69          ; XID_Continue # Lm       MODIFIER LETTER SMALL TURNED W
 AB70..ABBF    ; XID_Continue # L&  [80] CHEROKEE SMALL LETTER A..CHEROKEE SMALL LETTER YA
 ABC0..ABE2    ; XID_Continue # Lo  [35] MEETEI MAYEK LETTER KOK..MEETEI MAYEK LETTER I LONSUM
 ABE3..ABE4    ; XID_Continue # Mc   [2] MEETEI MAYEK VOWEL SIGN ONAP..MEETEI MAYEK VOWEL SIGN INAP
@@ -9414,10 +9537,14 @@ FFDA..FFDC    ; XID_Continue # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HA
 10D00..10D23  ; XID_Continue # Lo  [36] HANIFI ROHINGYA LETTER A..HANIFI ROHINGYA MARK NA KHONNA
 10D24..10D27  ; XID_Continue # Mn   [4] HANIFI ROHINGYA SIGN HARBAHAY..HANIFI ROHINGYA SIGN TASSI
 10D30..10D39  ; XID_Continue # Nd  [10] HANIFI ROHINGYA DIGIT ZERO..HANIFI ROHINGYA DIGIT NINE
+10E80..10EA9  ; XID_Continue # Lo  [42] YEZIDI LETTER ELIF..YEZIDI LETTER ET
+10EAB..10EAC  ; XID_Continue # Mn   [2] YEZIDI COMBINING HAMZA MARK..YEZIDI COMBINING MADDA MARK
+10EB0..10EB1  ; XID_Continue # Lo   [2] YEZIDI LETTER LAM WITH DOT ABOVE..YEZIDI LETTER YOT WITH CIRCUMFLEX ABOVE
 10F00..10F1C  ; XID_Continue # Lo  [29] OLD SOGDIAN LETTER ALEPH..OLD SOGDIAN LETTER FINAL TAW WITH VERTICAL TAIL
 10F27         ; XID_Continue # Lo       OLD SOGDIAN LIGATURE AYIN-DALETH
 10F30..10F45  ; XID_Continue # Lo  [22] SOGDIAN LETTER ALEPH..SOGDIAN INDEPENDENT SHIN
 10F46..10F50  ; XID_Continue # Mn  [11] SOGDIAN COMBINING DOT BELOW..SOGDIAN COMBINING STROKE BELOW
+10FB0..10FC4  ; XID_Continue # Lo  [21] CHORASMIAN LETTER ALEPH..CHORASMIAN LETTER TAW
 10FE0..10FF6  ; XID_Continue # Lo  [23] ELYMAIC LETTER ALEPH..ELYMAIC LIGATURE ZAYIN-YODH
 11000         ; XID_Continue # Mc       BRAHMI SIGN CANDRABINDU
 11001         ; XID_Continue # Mn       BRAHMI SIGN ANUSVARA
@@ -9442,6 +9569,7 @@ FFDA..FFDC    ; XID_Continue # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HA
 11136..1113F  ; XID_Continue # Nd  [10] CHAKMA DIGIT ZERO..CHAKMA DIGIT NINE
 11144         ; XID_Continue # Lo       CHAKMA LETTER LHAA
 11145..11146  ; XID_Continue # Mc   [2] CHAKMA VOWEL SIGN AA..CHAKMA VOWEL SIGN EI
+11147         ; XID_Continue # Lo       CHAKMA LETTER VAA
 11150..11172  ; XID_Continue # Lo  [35] MAHAJANI LETTER A..MAHAJANI LETTER RRA
 11173         ; XID_Continue # Mn       MAHAJANI SIGN NUKTA
 11176         ; XID_Continue # Lo       MAHAJANI LIGATURE SHRI
@@ -9453,6 +9581,8 @@ FFDA..FFDC    ; XID_Continue # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HA
 111BF..111C0  ; XID_Continue # Mc   [2] SHARADA VOWEL SIGN AU..SHARADA SIGN VIRAMA
 111C1..111C4  ; XID_Continue # Lo   [4] SHARADA SIGN AVAGRAHA..SHARADA OM
 111C9..111CC  ; XID_Continue # Mn   [4] SHARADA SANDHI MARK..SHARADA EXTRA SHORT VOWEL MARK
+111CE         ; XID_Continue # Mc       SHARADA VOWEL SIGN PRISHTHAMATRA E
+111CF         ; XID_Continue # Mn       SHARADA SIGN INVERTED CANDRABINDU
 111D0..111D9  ; XID_Continue # Nd  [10] SHARADA DIGIT ZERO..SHARADA DIGIT NINE
 111DA         ; XID_Continue # Lo       SHARADA EKAM
 111DC         ; XID_Continue # Lo       SHARADA HEADSTROKE
@@ -9506,7 +9636,7 @@ FFDA..FFDC    ; XID_Continue # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HA
 11447..1144A  ; XID_Continue # Lo   [4] NEWA SIGN AVAGRAHA..NEWA SIDDHI
 11450..11459  ; XID_Continue # Nd  [10] NEWA DIGIT ZERO..NEWA DIGIT NINE
 1145E         ; XID_Continue # Mn       NEWA SANDHI MARK
-1145F         ; XID_Continue # Lo       NEWA LETTER VEDIC ANUSVARA
+1145F..11461  ; XID_Continue # Lo   [3] NEWA LETTER VEDIC ANUSVARA..NEWA SIGN UPADHMANIYA
 11480..114AF  ; XID_Continue # Lo  [48] TIRHUTA ANJI..TIRHUTA LETTER HA
 114B0..114B2  ; XID_Continue # Mc   [3] TIRHUTA VOWEL SIGN AA..TIRHUTA VOWEL SIGN II
 114B3..114B8  ; XID_Continue # Mn   [6] TIRHUTA VOWEL SIGN U..TIRHUTA VOWEL SIGN VOCALIC LL
@@ -9561,7 +9691,22 @@ FFDA..FFDC    ; XID_Continue # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HA
 11839..1183A  ; XID_Continue # Mn   [2] DOGRA SIGN VIRAMA..DOGRA SIGN NUKTA
 118A0..118DF  ; XID_Continue # L&  [64] WARANG CITI CAPITAL LETTER NGAA..WARANG CITI SMALL LETTER VIYO
 118E0..118E9  ; XID_Continue # Nd  [10] WARANG CITI DIGIT ZERO..WARANG CITI DIGIT NINE
-118FF         ; XID_Continue # Lo       WARANG CITI OM
+118FF..11906  ; XID_Continue # Lo   [8] WARANG CITI OM..DIVES AKURU LETTER E
+11909         ; XID_Continue # Lo       DIVES AKURU LETTER O
+1190C..11913  ; XID_Continue # Lo   [8] DIVES AKURU LETTER KA..DIVES AKURU LETTER JA
+11915..11916  ; XID_Continue # Lo   [2] DIVES AKURU LETTER NYA..DIVES AKURU LETTER TTA
+11918..1192F  ; XID_Continue # Lo  [24] DIVES AKURU LETTER DDA..DIVES AKURU LETTER ZA
+11930..11935  ; XID_Continue # Mc   [6] DIVES AKURU VOWEL SIGN AA..DIVES AKURU VOWEL SIGN E
+11937..11938  ; XID_Continue # Mc   [2] DIVES AKURU VOWEL SIGN AI..DIVES AKURU VOWEL SIGN O
+1193B..1193C  ; XID_Continue # Mn   [2] DIVES AKURU SIGN ANUSVARA..DIVES AKURU SIGN CANDRABINDU
+1193D         ; XID_Continue # Mc       DIVES AKURU SIGN HALANTA
+1193E         ; XID_Continue # Mn       DIVES AKURU VIRAMA
+1193F         ; XID_Continue # Lo       DIVES AKURU PREFIXED NASAL SIGN
+11940         ; XID_Continue # Mc       DIVES AKURU MEDIAL YA
+11941         ; XID_Continue # Lo       DIVES AKURU INITIAL RA
+11942         ; XID_Continue # Mc       DIVES AKURU MEDIAL RA
+11943         ; XID_Continue # Mn       DIVES AKURU SIGN NUKTA
+11950..11959  ; XID_Continue # Nd  [10] DIVES AKURU DIGIT ZERO..DIVES AKURU DIGIT NINE
 119A0..119A7  ; XID_Continue # Lo   [8] NANDINAGARI LETTER A..NANDINAGARI LETTER VOCALIC RR
 119AA..119D0  ; XID_Continue # Lo  [39] NANDINAGARI LETTER E..NANDINAGARI LETTER RRA
 119D1..119D3  ; XID_Continue # Mc   [3] NANDINAGARI VOWEL SIGN AA..NANDINAGARI VOWEL SIGN II
@@ -9631,6 +9776,7 @@ FFDA..FFDC    ; XID_Continue # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HA
 11EE0..11EF2  ; XID_Continue # Lo  [19] MAKASAR LETTER KA..MAKASAR ANGKA
 11EF3..11EF4  ; XID_Continue # Mn   [2] MAKASAR VOWEL SIGN I..MAKASAR VOWEL SIGN U
 11EF5..11EF6  ; XID_Continue # Mc   [2] MAKASAR VOWEL SIGN E..MAKASAR VOWEL SIGN O
+11FB0         ; XID_Continue # Lo       LISU LETTER YHA
 12000..12399  ; XID_Continue # Lo [922] CUNEIFORM SIGN A..CUNEIFORM SIGN U U
 12400..1246E  ; XID_Continue # Nl [111] CUNEIFORM NUMERIC SIGN TWO ASH..CUNEIFORM NUMERIC SIGN NINE U VARIANT FORM
 12480..12543  ; XID_Continue # Lo [196] CUNEIFORM SIGN AB TIMES NUN TENU..CUNEIFORM SIGN ZU5 TIMES THREE DISH TENU
@@ -9656,8 +9802,11 @@ FFDA..FFDC    ; XID_Continue # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HA
 16F93..16F9F  ; XID_Continue # Lm  [13] MIAO LETTER TONE-2..MIAO LETTER REFORMED TONE-8
 16FE0..16FE1  ; XID_Continue # Lm   [2] TANGUT ITERATION MARK..NUSHU ITERATION MARK
 16FE3         ; XID_Continue # Lm       OLD CHINESE ITERATION MARK
+16FE4         ; XID_Continue # Mn       KHITAN SMALL SCRIPT FILLER
+16FF0..16FF1  ; XID_Continue # Mc   [2] VIETNAMESE ALTERNATE READING MARK CA..VIETNAMESE ALTERNATE READING MARK NHAY
 17000..187F7  ; XID_Continue # Lo [6136] TANGUT IDEOGRAPH-17000..TANGUT IDEOGRAPH-187F7
-18800..18AF2  ; XID_Continue # Lo [755] TANGUT COMPONENT-001..TANGUT COMPONENT-755
+18800..18CD5  ; XID_Continue # Lo [1238] TANGUT COMPONENT-001..KHITAN SMALL SCRIPT CHARACTER-18CD5
+18D00..18D08  ; XID_Continue # Lo   [9] TANGUT IDEOGRAPH-18D00..TANGUT IDEOGRAPH-18D08
 1B000..1B11E  ; XID_Continue # Lo [287] KATAKANA LETTER ARCHAIC E..HENTAIGANA LETTER N-MU-MO-2
 1B150..1B152  ; XID_Continue # Lo   [3] HIRAGANA LETTER SMALL WI..HIRAGANA LETTER SMALL WO
 1B164..1B167  ; XID_Continue # Lo   [4] KATAKANA LETTER SMALL WI..KATAKANA LETTER SMALL N
@@ -9763,15 +9912,17 @@ FFDA..FFDC    ; XID_Continue # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HA
 1EEA1..1EEA3  ; XID_Continue # Lo   [3] ARABIC MATHEMATICAL DOUBLE-STRUCK BEH..ARABIC MATHEMATICAL DOUBLE-STRUCK DAL
 1EEA5..1EEA9  ; XID_Continue # Lo   [5] ARABIC MATHEMATICAL DOUBLE-STRUCK WAW..ARABIC MATHEMATICAL DOUBLE-STRUCK YEH
 1EEAB..1EEBB  ; XID_Continue # Lo  [17] ARABIC MATHEMATICAL DOUBLE-STRUCK LAM..ARABIC MATHEMATICAL DOUBLE-STRUCK GHAIN
-20000..2A6D6  ; XID_Continue # Lo [42711] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6D6
+1FBF0..1FBF9  ; XID_Continue # Nd  [10] SEGMENTED DIGIT ZERO..SEGMENTED DIGIT NINE
+20000..2A6DD  ; XID_Continue # Lo [42718] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6DD
 2A700..2B734  ; XID_Continue # Lo [4149] CJK UNIFIED IDEOGRAPH-2A700..CJK UNIFIED IDEOGRAPH-2B734
 2B740..2B81D  ; XID_Continue # Lo [222] CJK UNIFIED IDEOGRAPH-2B740..CJK UNIFIED IDEOGRAPH-2B81D
 2B820..2CEA1  ; XID_Continue # Lo [5762] CJK UNIFIED IDEOGRAPH-2B820..CJK UNIFIED IDEOGRAPH-2CEA1
 2CEB0..2EBE0  ; XID_Continue # Lo [7473] CJK UNIFIED IDEOGRAPH-2CEB0..CJK UNIFIED IDEOGRAPH-2EBE0
 2F800..2FA1D  ; XID_Continue # Lo [542] CJK COMPATIBILITY IDEOGRAPH-2F800..CJK COMPATIBILITY IDEOGRAPH-2FA1D
+30000..3134A  ; XID_Continue # Lo [4939] CJK UNIFIED IDEOGRAPH-30000..CJK UNIFIED IDEOGRAPH-3134A
 E0100..E01EF  ; XID_Continue # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256
 
-# Total code points: 128770
+# Total code points: 134415
 
 # ================================================
 
@@ -9883,7 +10034,7 @@ E01F0..E0FFF  ; Default_Ignorable_Code_Point # Cn [3600] ........
 2B76..2B95    ; Pattern_Syntax # So  [32] NORTH WEST TRIANGLE-HEADED ARROW TO BAR..RIGHTWARDS BLACK ARROW
-2B96..2B97    ; Pattern_Syntax # Cn   [2] ..
-2B98..2BFF    ; Pattern_Syntax # So [104] THREE-D TOP-LIGHTED LEFTWARDS EQUILATERAL ARROWHEAD..HELLSCHREIBER PAUSE SYMBOL
+2B96          ; Pattern_Syntax # Cn       
+2B97..2BFF    ; Pattern_Syntax # So [105] SYMBOL FOR TYPE A ELECTRONICS..HELLSCHREIBER PAUSE SYMBOL
 2E00..2E01    ; Pattern_Syntax # Po   [2] RIGHT ANGLE SUBSTITUTION MARKER..RIGHT ANGLE DOTTED SUBSTITUTION MARKER
 2E02          ; Pattern_Syntax # Pi       LEFT SUBSTITUTION BRACKET
 2E03          ; Pattern_Syntax # Pf       RIGHT SUBSTITUTION BRACKET
@@ -1614,7 +1643,9 @@ E0100..E01EF  ; Variation_Selector # Mn [240] VARIATION SELECTOR-17..VARIATION S
 2E41          ; Pattern_Syntax # Po       REVERSED COMMA
 2E42          ; Pattern_Syntax # Ps       DOUBLE LOW-REVERSED-9 QUOTATION MARK
 2E43..2E4F    ; Pattern_Syntax # Po  [13] DASH WITH LEFT UPTURN..CORNISH VERSE DIVIDER
-2E50..2E7F    ; Pattern_Syntax # Cn  [48] ..
+2E50..2E51    ; Pattern_Syntax # So   [2] CROSS PATTY WITH RIGHT CROSSBAR..CROSS PATTY WITH LEFT CROSSBAR
+2E52          ; Pattern_Syntax # Po       TIRONIAN SIGN CAPITAL ET
+2E53..2E7F    ; Pattern_Syntax # Cn  [45] ..
 3001..3003    ; Pattern_Syntax # Po   [3] IDEOGRAPHIC COMMA..DITTO MARK
 3008          ; Pattern_Syntax # Ps       LEFT ANGLE BRACKET
 3009          ; Pattern_Syntax # Pe       RIGHT ANGLE BRACKET
diff --git a/make/data/unicodedata/PropertyValueAliases.txt b/make/data/unicodedata/PropertyValueAliases.txt
index 6e03745c5b6..a72c8671591 100644
--- a/make/data/unicodedata/PropertyValueAliases.txt
+++ b/make/data/unicodedata/PropertyValueAliases.txt
@@ -1,5 +1,5 @@
-# PropertyValueAliases-12.1.0.txt
-# Date: 2019-03-10, 10:53:18 GMT
+# PropertyValueAliases-13.0.0.txt
+# Date: 2019-11-13, 21:52:10 GMT
 # Copyright (c) 2019 Unicode, Inc.
 # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
 # For terms of use, see http://www.unicode.org/terms_of_use.html
@@ -88,6 +88,7 @@ age; 10.0                             ; V10_0
 age; 11.0                             ; V11_0
 age; 12.0                             ; V12_0
 age; 12.1                             ; V12_1
+age; 13.0                             ; V13_0
 age; NA                               ; Unassigned
 
 # Alphabetic (Alpha)
@@ -190,6 +191,7 @@ blk; Cham                             ; Cham
 blk; Cherokee                         ; Cherokee
 blk; Cherokee_Sup                     ; Cherokee_Supplement
 blk; Chess_Symbols                    ; Chess_Symbols
+blk; Chorasmian                       ; Chorasmian
 blk; CJK                              ; CJK_Unified_Ideographs
 blk; CJK_Compat                       ; CJK_Compatibility
 blk; CJK_Compat_Forms                 ; CJK_Compatibility_Forms
@@ -201,6 +203,7 @@ blk; CJK_Ext_C                        ; CJK_Unified_Ideographs_Extension_C
 blk; CJK_Ext_D                        ; CJK_Unified_Ideographs_Extension_D
 blk; CJK_Ext_E                        ; CJK_Unified_Ideographs_Extension_E
 blk; CJK_Ext_F                        ; CJK_Unified_Ideographs_Extension_F
+blk; CJK_Ext_G                        ; CJK_Unified_Ideographs_Extension_G
 blk; CJK_Radicals_Sup                 ; CJK_Radicals_Supplement
 blk; CJK_Strokes                      ; CJK_Strokes
 blk; CJK_Symbols                      ; CJK_Symbols_And_Punctuation
@@ -226,6 +229,7 @@ blk; Diacriticals_Ext                 ; Combining_Diacritical_Marks_Extended
 blk; Diacriticals_For_Symbols         ; Combining_Diacritical_Marks_For_Symbols; Combining_Marks_For_Symbols
 blk; Diacriticals_Sup                 ; Combining_Diacritical_Marks_Supplement
 blk; Dingbats                         ; Dingbats
+blk; Dives_Akuru                      ; Dives_Akuru
 blk; Dogra                            ; Dogra
 blk; Domino                           ; Domino_Tiles
 blk; Duployan                         ; Duployan
@@ -289,6 +293,7 @@ blk; Katakana                         ; Katakana
 blk; Katakana_Ext                     ; Katakana_Phonetic_Extensions
 blk; Kayah_Li                         ; Kayah_Li
 blk; Kharoshthi                       ; Kharoshthi
+blk; Khitan_Small_Script              ; Khitan_Small_Script
 blk; Khmer                            ; Khmer
 blk; Khmer_Symbols                    ; Khmer_Symbols
 blk; Khojki                           ; Khojki
@@ -308,6 +313,7 @@ blk; Linear_A                         ; Linear_A
 blk; Linear_B_Ideograms               ; Linear_B_Ideograms
 blk; Linear_B_Syllabary               ; Linear_B_Syllabary
 blk; Lisu                             ; Lisu
+blk; Lisu_Sup                         ; Lisu_Supplement
 blk; Low_Surrogates                   ; Low_Surrogates
 blk; Lycian                           ; Lycian
 blk; Lydian                           ; Lydian
@@ -414,6 +420,7 @@ blk; Super_And_Sub                    ; Superscripts_And_Subscripts
 blk; Sutton_SignWriting               ; Sutton_SignWriting
 blk; Syloti_Nagri                     ; Syloti_Nagri
 blk; Symbols_And_Pictographs_Ext_A    ; Symbols_And_Pictographs_Extended_A
+blk; Symbols_For_Legacy_Computing     ; Symbols_For_Legacy_Computing
 blk; Syriac                           ; Syriac
 blk; Syriac_Sup                       ; Syriac_Supplement
 blk; Tagalog                          ; Tagalog
@@ -428,6 +435,7 @@ blk; Tamil                            ; Tamil
 blk; Tamil_Sup                        ; Tamil_Supplement
 blk; Tangut                           ; Tangut
 blk; Tangut_Components                ; Tangut_Components
+blk; Tangut_Sup                       ; Tangut_Supplement
 blk; Telugu                           ; Telugu
 blk; Thaana                           ; Thaana
 blk; Thai                             ; Thai
@@ -445,6 +453,7 @@ blk; VS                               ; Variation_Selectors
 blk; VS_Sup                           ; Variation_Selectors_Supplement
 blk; Wancho                           ; Wancho
 blk; Warang_Citi                      ; Warang_Citi
+blk; Yezidi                           ; Yezidi
 blk; Yi_Radicals                      ; Yi_Radicals
 blk; Yi_Syllables                     ; Yi_Syllables
 blk; Yijing                           ; Yijing_Hexagram_Symbols
@@ -454,6 +463,7 @@ blk; Zanabazar_Square                 ; Zanabazar_Square
 
 ccc;   0; NR                         ; Not_Reordered
 ccc;   1; OV                         ; Overlay
+ccc;   6; HANR                       ; Han_Reading
 ccc;   7; NK                         ; Nukta
 ccc;   8; KV                         ; Kana_Voicing
 ccc;   9; VR                         ; Virama
@@ -613,6 +623,31 @@ ea ; N                                ; Neutral
 ea ; Na                               ; Narrow
 ea ; W                                ; Wide
 
+# Emoji (Emoji)
+
+Emoji; N                              ; No                               ; F                                ; False
+Emoji; Y                              ; Yes                              ; T                                ; True
+
+# Emoji_Component (EComp)
+
+EComp; N                              ; No                               ; F                                ; False
+EComp; Y                              ; Yes                              ; T                                ; True
+
+# Emoji_Modifier (EMod)
+
+EMod; N                               ; No                               ; F                                ; False
+EMod; Y                               ; Yes                              ; T                                ; True
+
+# Emoji_Modifier_Base (EBase)
+
+EBase; N                              ; No                               ; F                                ; False
+EBase; Y                              ; Yes                              ; T                                ; True
+
+# Emoji_Presentation (EPres)
+
+EPres; N                              ; No                               ; F                                ; False
+EPres; Y                              ; Yes                              ; T                                ; True
+
 # Equivalent_Unified_Ideograph (EqUIdeo)
 
 # @missing: 0000..10FFFF; Equivalent_Unified_Ideograph; 
@@ -637,6 +672,11 @@ XO_NFKC; Y                            ; Yes                              ; T
 XO_NFKD; N                            ; No                               ; F                                ; False
 XO_NFKD; Y                            ; Yes                              ; T                                ; True
 
+# Extended_Pictographic (ExtPict)
+
+ExtPict; N                            ; No                               ; F                                ; False
+ExtPict; Y                            ; Yes                              ; T                                ; True
+
 # Extender (Ext)
 
 Ext; N                                ; No                               ; F                                ; False
@@ -789,6 +829,7 @@ InPC; Overstruck                      ; Overstruck
 InPC; Right                           ; Right
 InPC; Top                             ; Top
 InPC; Top_And_Bottom                  ; Top_And_Bottom
+InPC; Top_And_Bottom_And_Left         ; Top_And_Bottom_And_Left
 InPC; Top_And_Bottom_And_Right        ; Top_And_Bottom_And_Right
 InPC; Top_And_Left                    ; Top_And_Left
 InPC; Top_And_Left_And_Right          ; Top_And_Left_And_Right
@@ -1219,10 +1260,12 @@ sc ; Cans                             ; Canadian_Aboriginal
 sc ; Cari                             ; Carian
 sc ; Cham                             ; Cham
 sc ; Cher                             ; Cherokee
+sc ; Chrs                             ; Chorasmian
 sc ; Copt                             ; Coptic                           ; Qaac
 sc ; Cprt                             ; Cypriot
 sc ; Cyrl                             ; Cyrillic
 sc ; Deva                             ; Devanagari
+sc ; Diak                             ; Dives_Akuru
 sc ; Dogr                             ; Dogra
 sc ; Dsrt                             ; Deseret
 sc ; Dupl                             ; Duployan
@@ -1257,6 +1300,7 @@ sc ; Kana                             ; Katakana
 sc ; Khar                             ; Kharoshthi
 sc ; Khmr                             ; Khmer
 sc ; Khoj                             ; Khojki
+sc ; Kits                             ; Khitan_Small_Script
 sc ; Knda                             ; Kannada
 sc ; Kthi                             ; Kaithi
 sc ; Lana                             ; Tai_Tham
@@ -1345,6 +1389,7 @@ sc ; Wara                             ; Warang_Citi
 sc ; Wcho                             ; Wancho
 sc ; Xpeo                             ; Old_Persian
 sc ; Xsux                             ; Cuneiform
+sc ; Yezi                             ; Yezidi
 sc ; Yiii                             ; Yi
 sc ; Zanb                             ; Zanabazar_Square
 sc ; Zinh                             ; Inherited                        ; Qaai
@@ -1515,10 +1560,18 @@ XIDS; Y                               ; Yes                              ; T
 
 # @missing: 0000..10FFFF; cjkIRG_MSource; 
 
+# cjkIRG_SSource (cjkIRG_SSource)
+
+# @missing: 0000..10FFFF; cjkIRG_SSource; 
+
 # cjkIRG_TSource (cjkIRG_TSource)
 
 # @missing: 0000..10FFFF; cjkIRG_TSource; 
 
+# cjkIRG_UKSource (cjkIRG_UKSource)
+
+# @missing: 0000..10FFFF; cjkIRG_UKSource; 
+
 # cjkIRG_USource (cjkIRG_USource)
 
 # @missing: 0000..10FFFF; cjkIRG_USource; 
diff --git a/make/data/unicodedata/Scripts.txt b/make/data/unicodedata/Scripts.txt
index 2b28ec238a4..eb3cd86e0c7 100644
--- a/make/data/unicodedata/Scripts.txt
+++ b/make/data/unicodedata/Scripts.txt
@@ -1,6 +1,6 @@
-# Scripts-12.1.0.txt
-# Date: 2019-04-01, 09:10:42 GMT
-# Copyright (c) 2019 Unicode, Inc.
+# Scripts-13.0.0.txt
+# Date: 2020-01-22, 00:07:43 GMT
+# Copyright (c) 2020 Unicode, Inc.
 # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
 # For terms of use, see http://www.unicode.org/terms_of_use.html
 #
@@ -89,7 +89,6 @@
 037E          ; Common # Po       GREEK QUESTION MARK
 0385          ; Common # Sk       GREEK DIALYTIKA TONOS
 0387          ; Common # Po       GREEK ANO TELEIA
-0589          ; Common # Po       ARMENIAN FULL STOP
 0605          ; Common # Cf       ARABIC NUMBER MARK ABOVE
 060C          ; Common # Po       ARABIC COMMA
 061B          ; Common # Po       ARABIC SEMICOLON
@@ -308,7 +307,7 @@
 2B47..2B4C    ; Common # Sm   [6] REVERSE TILDE OPERATOR ABOVE RIGHTWARDS ARROW..RIGHTWARDS ARROW ABOVE REVERSE TILDE OPERATOR
 2B4D..2B73    ; Common # So  [39] DOWNWARDS TRIANGLE-HEADED ZIGZAG ARROW..DOWNWARDS TRIANGLE-HEADED ARROW TO BAR
 2B76..2B95    ; Common # So  [32] NORTH WEST TRIANGLE-HEADED ARROW TO BAR..RIGHTWARDS BLACK ARROW
-2B98..2BFF    ; Common # So [104] THREE-D TOP-LIGHTED LEFTWARDS EQUILATERAL ARROWHEAD..HELLSCHREIBER PAUSE SYMBOL
+2B97..2BFF    ; Common # So [105] SYMBOL FOR TYPE A ELECTRONICS..HELLSCHREIBER PAUSE SYMBOL
 2E00..2E01    ; Common # Po   [2] RIGHT ANGLE SUBSTITUTION MARKER..RIGHT ANGLE DOTTED SUBSTITUTION MARKER
 2E02          ; Common # Pi       LEFT SUBSTITUTION BRACKET
 2E03          ; Common # Pf       RIGHT SUBSTITUTION BRACKET
@@ -347,6 +346,8 @@
 2E41          ; Common # Po       REVERSED COMMA
 2E42          ; Common # Ps       DOUBLE LOW-REVERSED-9 QUOTATION MARK
 2E43..2E4F    ; Common # Po  [13] DASH WITH LEFT UPTURN..CORNISH VERSE DIVIDER
+2E50..2E51    ; Common # So   [2] CROSS PATTY WITH RIGHT CROSSBAR..CROSS PATTY WITH LEFT CROSSBAR
+2E52          ; Common # Po       TIRONIAN SIGN CAPITAL ET
 2FF0..2FFB    ; Common # So  [12] IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO RIGHT..IDEOGRAPHIC DESCRIPTION CHARACTER OVERLAID
 3000          ; Common # Zs       IDEOGRAPHIC SPACE
 3001..3003    ; Common # Po   [3] IDEOGRAPHIC COMMA..DITTO MARK
@@ -414,6 +415,7 @@ A839          ; Common # So       NORTH INDIC QUANTITY MARK
 A92E          ; Common # Po       KAYAH LI SIGN CWI
 A9CF          ; Common # Lm       JAVANESE PANGRANGKEP
 AB5B          ; Common # Sk       MODIFIER BREVE WITH INVERTED BREVE
+AB6A..AB6B    ; Common # Sk   [2] MODIFIER LETTER LEFT TACK..MODIFIER LETTER RIGHT TACK
 FD3E          ; Common # Pe       ORNATE LEFT PARENTHESIS
 FD3F          ; Common # Ps       ORNATE RIGHT PARENTHESIS
 FE10..FE16    ; Common # Po   [7] PRESENTATION FORM FOR VERTICAL COMMA..PRESENTATION FORM FOR VERTICAL QUESTION MARK
@@ -506,7 +508,7 @@ FFFC..FFFD    ; Common # So   [2] OBJECT REPLACEMENT CHARACTER..REPLACEMENT CHAR
 10100..10102  ; Common # Po   [3] AEGEAN WORD SEPARATOR LINE..AEGEAN CHECK MARK
 10107..10133  ; Common # No  [45] AEGEAN NUMBER ONE..AEGEAN NUMBER NINETY THOUSAND
 10137..1013F  ; Common # So   [9] AEGEAN WEIGHT BASE UNIT..AEGEAN MEASURE THIRD SUBUNIT
-10190..1019B  ; Common # So  [12] ROMAN SEXTANS SIGN..ROMAN CENTURIAL SIGN
+10190..1019C  ; Common # So  [13] ROMAN SEXTANS SIGN..ASCIA SYMBOL
 101D0..101FC  ; Common # So  [45] PHAISTOS DISC SIGN PEDESTRIAN..PHAISTOS DISC SIGN WAVY BAND
 102E1..102FB  ; Common # No  [27] COPTIC EPACT DIGIT ONE..COPTIC EPACT NUMBER NINE HUNDRED
 16FE2         ; Common # Po       OLD CHINESE HOOK MARK
@@ -581,8 +583,7 @@ FFFC..FFFD    ; Common # So   [2] OBJECT REPLACEMENT CHARACTER..REPLACEMENT CHAR
 1F0C1..1F0CF  ; Common # So  [15] PLAYING CARD ACE OF DIAMONDS..PLAYING CARD BLACK JOKER
 1F0D1..1F0F5  ; Common # So  [37] PLAYING CARD ACE OF CLUBS..PLAYING CARD TRUMP-21
 1F100..1F10C  ; Common # No  [13] DIGIT ZERO FULL STOP..DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ZERO
-1F110..1F16C  ; Common # So  [93] PARENTHESIZED LATIN CAPITAL LETTER A..RAISED MR SIGN
-1F170..1F1AC  ; Common # So  [61] NEGATIVE SQUARED LATIN CAPITAL LETTER A..SQUARED VOD
+1F10D..1F1AD  ; Common # So [161] CIRCLED ZERO WITH SLASH..MASK WORK SYMBOL
 1F1E6..1F1FF  ; Common # So  [26] REGIONAL INDICATOR SYMBOL LETTER A..REGIONAL INDICATOR SYMBOL LETTER Z
 1F201..1F202  ; Common # So   [2] SQUARED KATAKANA KOKO..SQUARED KATAKANA SA
 1F210..1F23B  ; Common # So  [44] SQUARED CJK UNIFIED IDEOGRAPH-624B..SQUARED CJK UNIFIED IDEOGRAPH-914D
@@ -591,9 +592,9 @@ FFFC..FFFD    ; Common # So   [2] OBJECT REPLACEMENT CHARACTER..REPLACEMENT CHAR
 1F260..1F265  ; Common # So   [6] ROUNDED SYMBOL FOR FU..ROUNDED SYMBOL FOR CAI
 1F300..1F3FA  ; Common # So [251] CYCLONE..AMPHORA
 1F3FB..1F3FF  ; Common # Sk   [5] EMOJI MODIFIER FITZPATRICK TYPE-1-2..EMOJI MODIFIER FITZPATRICK TYPE-6
-1F400..1F6D5  ; Common # So [726] RAT..HINDU TEMPLE
+1F400..1F6D7  ; Common # So [728] RAT..ELEVATOR
 1F6E0..1F6EC  ; Common # So  [13] HAMMER AND WRENCH..AIRPLANE ARRIVING
-1F6F0..1F6FA  ; Common # So  [11] SATELLITE..AUTO RICKSHAW
+1F6F0..1F6FC  ; Common # So  [13] SATELLITE..ROLLER SKATE
 1F700..1F773  ; Common # So [116] ALCHEMICAL SYMBOL FOR QUINTESSENCE..ALCHEMICAL SYMBOL FOR HALF OUNCE
 1F780..1F7D8  ; Common # So  [89] BLACK LEFT-POINTING ISOSCELES RIGHT TRIANGLE..NEGATIVE CIRCLED SQUARE
 1F7E0..1F7EB  ; Common # So  [12] LARGE ORANGE CIRCLE..LARGE BROWN SQUARE
@@ -602,22 +603,25 @@ FFFC..FFFD    ; Common # So   [2] OBJECT REPLACEMENT CHARACTER..REPLACEMENT CHAR
 1F850..1F859  ; Common # So  [10] LEFTWARDS SANS-SERIF ARROW..UP DOWN SANS-SERIF ARROW
 1F860..1F887  ; Common # So  [40] WIDE-HEADED LEFTWARDS LIGHT BARB ARROW..WIDE-HEADED SOUTH WEST VERY HEAVY BARB ARROW
 1F890..1F8AD  ; Common # So  [30] LEFTWARDS TRIANGLE ARROWHEAD..WHITE ARROW SHAFT WIDTH TWO THIRDS
-1F900..1F90B  ; Common # So  [12] CIRCLED CROSS FORMEE WITH FOUR DOTS..DOWNWARD FACING NOTCHED HOOK WITH DOT
-1F90D..1F971  ; Common # So [101] WHITE HEART..YAWNING FACE
-1F973..1F976  ; Common # So   [4] FACE WITH PARTY HORN AND PARTY HAT..FREEZING FACE
-1F97A..1F9A2  ; Common # So  [41] FACE WITH PLEADING EYES..SWAN
-1F9A5..1F9AA  ; Common # So   [6] SLOTH..OYSTER
-1F9AE..1F9CA  ; Common # So  [29] GUIDE DOG..ICE CUBE
+1F8B0..1F8B1  ; Common # So   [2] ARROW POINTING UPWARDS THEN NORTH WEST..ARROW POINTING RIGHTWARDS THEN CURVING SOUTH WEST
+1F900..1F978  ; Common # So [121] CIRCLED CROSS FORMEE WITH FOUR DOTS..DISGUISED FACE
+1F97A..1F9CB  ; Common # So  [82] FACE WITH PLEADING EYES..BUBBLE TEA
 1F9CD..1FA53  ; Common # So [135] STANDING PERSON..BLACK CHESS KNIGHT-BISHOP
 1FA60..1FA6D  ; Common # So  [14] XIANGQI RED GENERAL..XIANGQI BLACK SOLDIER
-1FA70..1FA73  ; Common # So   [4] BALLET SHOES..SHORTS
+1FA70..1FA74  ; Common # So   [5] BALLET SHOES..THONG SANDAL
 1FA78..1FA7A  ; Common # So   [3] DROP OF BLOOD..STETHOSCOPE
-1FA80..1FA82  ; Common # So   [3] YO-YO..PARACHUTE
-1FA90..1FA95  ; Common # So   [6] RINGED PLANET..BANJO
+1FA80..1FA86  ; Common # So   [7] YO-YO..NESTING DOLLS
+1FA90..1FAA8  ; Common # So  [25] RINGED PLANET..ROCK
+1FAB0..1FAB6  ; Common # So   [7] FLY..FEATHER
+1FAC0..1FAC2  ; Common # So   [3] ANATOMICAL HEART..PEOPLE HUGGING
+1FAD0..1FAD6  ; Common # So   [7] BLUEBERRIES..TEAPOT
+1FB00..1FB92  ; Common # So [147] BLOCK SEXTANT-1..UPPER HALF INVERSE MEDIUM SHADE AND LOWER HALF BLOCK
+1FB94..1FBCA  ; Common # So  [55] LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK..WHITE UP-POINTING CHEVRON
+1FBF0..1FBF9  ; Common # Nd  [10] SEGMENTED DIGIT ZERO..SEGMENTED DIGIT NINE
 E0001         ; Common # Cf       LANGUAGE TAG
 E0020..E007F  ; Common # Cf  [96] TAG SPACE..CANCEL TAG
 
-# Total code points: 7805
+# Total code points: 8087
 
 # ================================================
 
@@ -661,7 +665,8 @@ A771..A787    ; Latin # L&  [23] LATIN SMALL LETTER DUM..LATIN SMALL LETTER INSU
 A78B..A78E    ; Latin # L&   [4] LATIN CAPITAL LETTER SALTILLO..LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT
 A78F          ; Latin # Lo       LATIN LETTER SINOLOGICAL DOT
 A790..A7BF    ; Latin # L&  [48] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER GLOTTAL U
-A7C2..A7C6    ; Latin # L&   [5] LATIN CAPITAL LETTER ANGLICANA W..LATIN CAPITAL LETTER Z WITH PALATAL HOOK
+A7C2..A7CA    ; Latin # L&   [9] LATIN CAPITAL LETTER ANGLICANA W..LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY
+A7F5..A7F6    ; Latin # L&   [2] LATIN CAPITAL LETTER REVERSED HALF H..LATIN SMALL LETTER REVERSED HALF H
 A7F7          ; Latin # Lo       LATIN EPIGRAPHIC LETTER SIDEWAYS I
 A7F8..A7F9    ; Latin # Lm   [2] MODIFIER LETTER CAPITAL H WITH STROKE..MODIFIER LETTER SMALL LIGATURE OE
 A7FA          ; Latin # L&       LATIN LETTER SMALL CAPITAL TURNED M
@@ -669,12 +674,13 @@ A7FB..A7FF    ; Latin # Lo   [5] LATIN EPIGRAPHIC LETTER REVERSED F..LATIN EPIGR
 AB30..AB5A    ; Latin # L&  [43] LATIN SMALL LETTER BARRED ALPHA..LATIN SMALL LETTER Y WITH SHORT RIGHT LEG
 AB5C..AB5F    ; Latin # Lm   [4] MODIFIER LETTER SMALL HENG..MODIFIER LETTER SMALL U WITH LEFT HOOK
 AB60..AB64    ; Latin # L&   [5] LATIN SMALL LETTER SAKHA YAT..LATIN SMALL LETTER INVERTED ALPHA
-AB66..AB67    ; Latin # L&   [2] LATIN SMALL LETTER DZ DIGRAPH WITH RETROFLEX HOOK..LATIN SMALL LETTER TS DIGRAPH WITH RETROFLEX HOOK
+AB66..AB68    ; Latin # L&   [3] LATIN SMALL LETTER DZ DIGRAPH WITH RETROFLEX HOOK..LATIN SMALL LETTER TURNED R WITH MIDDLE TILDE
+AB69          ; Latin # Lm       MODIFIER LETTER SMALL TURNED W
 FB00..FB06    ; Latin # L&   [7] LATIN SMALL LIGATURE FF..LATIN SMALL LIGATURE ST
 FF21..FF3A    ; Latin # L&  [26] FULLWIDTH LATIN CAPITAL LETTER A..FULLWIDTH LATIN CAPITAL LETTER Z
 FF41..FF5A    ; Latin # L&  [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN SMALL LETTER Z
 
-# Total code points: 1366
+# Total code points: 1374
 
 # ================================================
 
@@ -769,12 +775,13 @@ FE2E..FE2F    ; Cyrillic # Mn   [2] COMBINING CYRILLIC TITLO LEFT HALF..COMBININ
 0559          ; Armenian # Lm       ARMENIAN MODIFIER LETTER LEFT HALF RING
 055A..055F    ; Armenian # Po   [6] ARMENIAN APOSTROPHE..ARMENIAN ABBREVIATION MARK
 0560..0588    ; Armenian # L&  [41] ARMENIAN SMALL LETTER TURNED AYB..ARMENIAN SMALL LETTER YI WITH STROKE
+0589          ; Armenian # Po       ARMENIAN FULL STOP
 058A          ; Armenian # Pd       ARMENIAN HYPHEN
 058D..058E    ; Armenian # So   [2] RIGHT-FACING ARMENIAN ETERNITY SIGN..LEFT-FACING ARMENIAN ETERNITY SIGN
 058F          ; Armenian # Sc       ARMENIAN DRAM SIGN
 FB13..FB17    ; Armenian # L&   [5] ARMENIAN SMALL LIGATURE MEN NOW..ARMENIAN SMALL LIGATURE MEN XEH
 
-# Total code points: 95
+# Total code points: 96
 
 # ================================================
 
@@ -837,7 +844,7 @@ FB46..FB4F    ; Hebrew # Lo  [10] HEBREW LETTER TSADI WITH DAGESH..HEBREW LIGATU
 06FF          ; Arabic # Lo       ARABIC LETTER HEH WITH INVERTED V
 0750..077F    ; Arabic # Lo  [48] ARABIC LETTER BEH WITH THREE DOTS HORIZONTALLY BELOW..ARABIC LETTER KAF WITH TWO DOTS ABOVE
 08A0..08B4    ; Arabic # Lo  [21] ARABIC LETTER BEH WITH SMALL V BELOW..ARABIC LETTER KAF WITH DOT BELOW
-08B6..08BD    ; Arabic # Lo   [8] ARABIC LETTER BEH WITH SMALL MEEM ABOVE..ARABIC LETTER AFRICAN NOON
+08B6..08C7    ; Arabic # Lo  [18] ARABIC LETTER BEH WITH SMALL MEEM ABOVE..ARABIC LETTER LAM WITH SMALL ARABIC LETTER TAH ABOVE
 08D3..08E1    ; Arabic # Mn  [15] ARABIC SMALL LOW WAW..ARABIC SMALL HIGH SIGN SAFHA
 08E3..08FF    ; Arabic # Mn  [29] ARABIC TURNED DAMMA BELOW..ARABIC MARK SIDEWAYS NOON GHUNNA
 FB50..FBB1    ; Arabic # Lo  [98] ARABIC LETTER ALEF WASLA ISOLATED FORM..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE FINAL FORM
@@ -886,7 +893,7 @@ FE76..FEFC    ; Arabic # Lo [135] ARABIC FATHA ISOLATED FORM..ARABIC LIGATURE LA
 1EEAB..1EEBB  ; Arabic # Lo  [17] ARABIC MATHEMATICAL DOUBLE-STRUCK LAM..ARABIC MATHEMATICAL DOUBLE-STRUCK GHAIN
 1EEF0..1EEF1  ; Arabic # Sm   [2] ARABIC MATHEMATICAL OPERATOR MEEM WITH HAH WITH TATWEEL..ARABIC MATHEMATICAL OPERATOR HAH WITH DAL
 
-# Total code points: 1281
+# Total code points: 1291
 
 # ================================================
 
@@ -1051,7 +1058,7 @@ A8FF          ; Devanagari # Mn       DEVANAGARI VOWEL SIGN AY
 0B47..0B48    ; Oriya # Mc   [2] ORIYA VOWEL SIGN E..ORIYA VOWEL SIGN AI
 0B4B..0B4C    ; Oriya # Mc   [2] ORIYA VOWEL SIGN O..ORIYA VOWEL SIGN AU
 0B4D          ; Oriya # Mn       ORIYA SIGN VIRAMA
-0B56          ; Oriya # Mn       ORIYA AI LENGTH MARK
+0B55..0B56    ; Oriya # Mn   [2] ORIYA SIGN OVERLINE..ORIYA AI LENGTH MARK
 0B57          ; Oriya # Mc       ORIYA AU LENGTH MARK
 0B5C..0B5D    ; Oriya # Lo   [2] ORIYA LETTER RRA..ORIYA LETTER RHA
 0B5F..0B61    ; Oriya # Lo   [3] ORIYA LETTER YYA..ORIYA LETTER VOCALIC LL
@@ -1061,7 +1068,7 @@ A8FF          ; Devanagari # Mn       DEVANAGARI VOWEL SIGN AY
 0B71          ; Oriya # Lo       ORIYA LETTER WA
 0B72..0B77    ; Oriya # No   [6] ORIYA FRACTION ONE QUARTER..ORIYA FRACTION THREE SIXTEENTHS
 
-# Total code points: 90
+# Total code points: 91
 
 # ================================================
 
@@ -1155,7 +1162,7 @@ A8FF          ; Devanagari # Mn       DEVANAGARI VOWEL SIGN AY
 
 0D00..0D01    ; Malayalam # Mn   [2] MALAYALAM SIGN COMBINING ANUSVARA ABOVE..MALAYALAM SIGN CANDRABINDU
 0D02..0D03    ; Malayalam # Mc   [2] MALAYALAM SIGN ANUSVARA..MALAYALAM SIGN VISARGA
-0D05..0D0C    ; Malayalam # Lo   [8] MALAYALAM LETTER A..MALAYALAM LETTER VOCALIC L
+0D04..0D0C    ; Malayalam # Lo   [9] MALAYALAM LETTER VEDIC ANUSVARA..MALAYALAM LETTER VOCALIC L
 0D0E..0D10    ; Malayalam # Lo   [3] MALAYALAM LETTER E..MALAYALAM LETTER AI
 0D12..0D3A    ; Malayalam # Lo  [41] MALAYALAM LETTER O..MALAYALAM LETTER TTTA
 0D3B..0D3C    ; Malayalam # Mn   [2] MALAYALAM SIGN VERTICAL BAR VIRAMA..MALAYALAM SIGN CIRCULAR VIRAMA
@@ -1177,10 +1184,11 @@ A8FF          ; Devanagari # Mn       DEVANAGARI VOWEL SIGN AY
 0D79          ; Malayalam # So       MALAYALAM DATE MARK
 0D7A..0D7F    ; Malayalam # Lo   [6] MALAYALAM LETTER CHILLU NN..MALAYALAM LETTER CHILLU K
 
-# Total code points: 117
+# Total code points: 118
 
 # ================================================
 
+0D81          ; Sinhala # Mn       SINHALA SIGN CANDRABINDU
 0D82..0D83    ; Sinhala # Mc   [2] SINHALA SIGN ANUSVARAYA..SINHALA SIGN VISARGAYA
 0D85..0D96    ; Sinhala # Lo  [18] SINHALA LETTER AYANNA..SINHALA LETTER AUYANNA
 0D9A..0DB1    ; Sinhala # Lo  [24] SINHALA LETTER ALPAPRAANA KAYANNA..SINHALA LETTER DANTAJA NAYANNA
@@ -1197,7 +1205,7 @@ A8FF          ; Devanagari # Mn       DEVANAGARI VOWEL SIGN AY
 0DF4          ; Sinhala # Po       SINHALA PUNCTUATION KUNDDALIYA
 111E1..111F4  ; Sinhala # No  [20] SINHALA ARCHAIC DIGIT ONE..SINHALA ARCHAIC NUMBER ONE THOUSAND
 
-# Total code points: 110
+# Total code points: 111
 
 # ================================================
 
@@ -1515,9 +1523,9 @@ FF71..FF9D    ; Katakana # Lo  [45] HALFWIDTH KATAKANA LETTER A..HALFWIDTH KATAK
 
 02EA..02EB    ; Bopomofo # Sk   [2] MODIFIER LETTER YIN DEPARTING TONE MARK..MODIFIER LETTER YANG DEPARTING TONE MARK
 3105..312F    ; Bopomofo # Lo  [43] BOPOMOFO LETTER B..BOPOMOFO LETTER NN
-31A0..31BA    ; Bopomofo # Lo  [27] BOPOMOFO LETTER BU..BOPOMOFO LETTER ZY
+31A0..31BF    ; Bopomofo # Lo  [32] BOPOMOFO LETTER BU..BOPOMOFO LETTER AH
 
-# Total code points: 72
+# Total code points: 77
 
 # ================================================
 
@@ -1529,18 +1537,20 @@ FF71..FF9D    ; Katakana # Lo  [45] HALFWIDTH KATAKANA LETTER A..HALFWIDTH KATAK
 3021..3029    ; Han # Nl   [9] HANGZHOU NUMERAL ONE..HANGZHOU NUMERAL NINE
 3038..303A    ; Han # Nl   [3] HANGZHOU NUMERAL TEN..HANGZHOU NUMERAL THIRTY
 303B          ; Han # Lm       VERTICAL IDEOGRAPHIC ITERATION MARK
-3400..4DB5    ; Han # Lo [6582] CJK UNIFIED IDEOGRAPH-3400..CJK UNIFIED IDEOGRAPH-4DB5
-4E00..9FEF    ; Han # Lo [20976] CJK UNIFIED IDEOGRAPH-4E00..CJK UNIFIED IDEOGRAPH-9FEF
+3400..4DBF    ; Han # Lo [6592] CJK UNIFIED IDEOGRAPH-3400..CJK UNIFIED IDEOGRAPH-4DBF
+4E00..9FFC    ; Han # Lo [20989] CJK UNIFIED IDEOGRAPH-4E00..CJK UNIFIED IDEOGRAPH-9FFC
 F900..FA6D    ; Han # Lo [366] CJK COMPATIBILITY IDEOGRAPH-F900..CJK COMPATIBILITY IDEOGRAPH-FA6D
 FA70..FAD9    ; Han # Lo [106] CJK COMPATIBILITY IDEOGRAPH-FA70..CJK COMPATIBILITY IDEOGRAPH-FAD9
-20000..2A6D6  ; Han # Lo [42711] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6D6
+16FF0..16FF1  ; Han # Mc   [2] VIETNAMESE ALTERNATE READING MARK CA..VIETNAMESE ALTERNATE READING MARK NHAY
+20000..2A6DD  ; Han # Lo [42718] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6DD
 2A700..2B734  ; Han # Lo [4149] CJK UNIFIED IDEOGRAPH-2A700..CJK UNIFIED IDEOGRAPH-2B734
 2B740..2B81D  ; Han # Lo [222] CJK UNIFIED IDEOGRAPH-2B740..CJK UNIFIED IDEOGRAPH-2B81D
 2B820..2CEA1  ; Han # Lo [5762] CJK UNIFIED IDEOGRAPH-2B820..CJK UNIFIED IDEOGRAPH-2CEA1
 2CEB0..2EBE0  ; Han # Lo [7473] CJK UNIFIED IDEOGRAPH-2CEB0..CJK UNIFIED IDEOGRAPH-2EBE0
 2F800..2FA1D  ; Han # Lo [542] CJK COMPATIBILITY IDEOGRAPH-2F800..CJK COMPATIBILITY IDEOGRAPH-2FA1D
+30000..3134A  ; Han # Lo [4939] CJK UNIFIED IDEOGRAPH-30000..CJK UNIFIED IDEOGRAPH-3134A
 
-# Total code points: 89233
+# Total code points: 94204
 
 # ================================================
 
@@ -1583,6 +1593,7 @@ A490..A4C6    ; Yi # So  [55] YI RADICAL QOT..YI RADICAL KE
 0951..0954    ; Inherited # Mn   [4] DEVANAGARI STRESS SIGN UDATTA..DEVANAGARI ACUTE ACCENT
 1AB0..1ABD    ; Inherited # Mn  [14] COMBINING DOUBLED CIRCUMFLEX ACCENT..COMBINING PARENTHESES BELOW
 1ABE          ; Inherited # Me       COMBINING PARENTHESES OVERLAY
+1ABF..1AC0    ; Inherited # Mn   [2] COMBINING LATIN SMALL LETTER W BELOW..COMBINING LATIN SMALL LETTER TURNED W BELOW
 1CD0..1CD2    ; Inherited # Mn   [3] VEDIC TONE KARSHANA..VEDIC TONE PRENKHA
 1CD4..1CE0    ; Inherited # Mn  [13] VEDIC SIGN YAJURVEDIC MIDLINE SVARITA..VEDIC TONE RIGVEDIC KASHMIRI INDEPENDENT SVARITA
 1CE2..1CE8    ; Inherited # Mn   [7] VEDIC SIGN VISARGA SVARITA..VEDIC SIGN VISARGA ANUDATTA WITH TAIL
@@ -1610,7 +1621,7 @@ FE20..FE2D    ; Inherited # Mn  [14] COMBINING LIGATURE LEFT HALF..COMBINING CON
 1D1AA..1D1AD  ; Inherited # Mn   [4] MUSICAL SYMBOL COMBINING DOWN BOW..MUSICAL SYMBOL COMBINING SNAP PIZZICATO
 E0100..E01EF  ; Inherited # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256
 
-# Total code points: 571
+# Total code points: 573
 
 # ================================================
 
@@ -1783,8 +1794,9 @@ A823..A824    ; Syloti_Nagri # Mc   [2] SYLOTI NAGRI VOWEL SIGN A..SYLOTI NAGRI
 A825..A826    ; Syloti_Nagri # Mn   [2] SYLOTI NAGRI VOWEL SIGN U..SYLOTI NAGRI VOWEL SIGN E
 A827          ; Syloti_Nagri # Mc       SYLOTI NAGRI VOWEL SIGN OO
 A828..A82B    ; Syloti_Nagri # So   [4] SYLOTI NAGRI POETRY MARK-1..SYLOTI NAGRI POETRY MARK-4
+A82C          ; Syloti_Nagri # Mn       SYLOTI NAGRI SIGN ALTERNATE HASANTA
 
-# Total code points: 44
+# Total code points: 45
 
 # ================================================
 
@@ -2063,8 +2075,9 @@ AADE..AADF    ; Tai_Viet # Po   [2] TAI VIET SYMBOL HO HOI..TAI VIET SYMBOL KOI
 A4D0..A4F7    ; Lisu # Lo  [40] LISU LETTER BA..LISU LETTER OE
 A4F8..A4FD    ; Lisu # Lm   [6] LISU LETTER TONE MYA TI..LISU LETTER TONE MYA JEU
 A4FE..A4FF    ; Lisu # Po   [2] LISU PUNCTUATION COMMA..LISU PUNCTUATION FULL STOP
+11FB0         ; Lisu # Lo       LISU LETTER YHA
 
-# Total code points: 48
+# Total code points: 49
 
 # ================================================
 
@@ -2217,8 +2230,9 @@ ABF0..ABF9    ; Meetei_Mayek # Nd  [10] MEETEI MAYEK DIGIT ZERO..MEETEI MAYEK DI
 11140..11143  ; Chakma # Po   [4] CHAKMA SECTION MARK..CHAKMA QUESTION MARK
 11144         ; Chakma # Lo       CHAKMA LETTER LHAA
 11145..11146  ; Chakma # Mc   [2] CHAKMA VOWEL SIGN AA..CHAKMA VOWEL SIGN EI
+11147         ; Chakma # Lo       CHAKMA LETTER VAA
 
-# Total code points: 70
+# Total code points: 71
 
 # ================================================
 
@@ -2259,13 +2273,15 @@ ABF0..ABF9    ; Meetei_Mayek # Nd  [10] MEETEI MAYEK DIGIT ZERO..MEETEI MAYEK DI
 111C5..111C8  ; Sharada # Po   [4] SHARADA DANDA..SHARADA SEPARATOR
 111C9..111CC  ; Sharada # Mn   [4] SHARADA SANDHI MARK..SHARADA EXTRA SHORT VOWEL MARK
 111CD         ; Sharada # Po       SHARADA SUTRA MARK
+111CE         ; Sharada # Mc       SHARADA VOWEL SIGN PRISHTHAMATRA E
+111CF         ; Sharada # Mn       SHARADA SIGN INVERTED CANDRABINDU
 111D0..111D9  ; Sharada # Nd  [10] SHARADA DIGIT ZERO..SHARADA DIGIT NINE
 111DA         ; Sharada # Lo       SHARADA EKAM
 111DB         ; Sharada # Po       SHARADA SIGN SIDDHAM
 111DC         ; Sharada # Lo       SHARADA HEADSTROKE
 111DD..111DF  ; Sharada # Po   [3] SHARADA CONTINUATION SIGN..SHARADA SECTION MARK-2
 
-# Total code points: 94
+# Total code points: 96
 
 # ================================================
 
@@ -2650,12 +2666,12 @@ ABF0..ABF9    ; Meetei_Mayek # Nd  [10] MEETEI MAYEK DIGIT ZERO..MEETEI MAYEK DI
 11447..1144A  ; Newa # Lo   [4] NEWA SIGN AVAGRAHA..NEWA SIDDHI
 1144B..1144F  ; Newa # Po   [5] NEWA DANDA..NEWA ABBREVIATION SIGN
 11450..11459  ; Newa # Nd  [10] NEWA DIGIT ZERO..NEWA DIGIT NINE
-1145B         ; Newa # Po       NEWA PLACEHOLDER MARK
+1145A..1145B  ; Newa # Po   [2] NEWA DOUBLE COMMA..NEWA PLACEHOLDER MARK
 1145D         ; Newa # Po       NEWA INSERTION SIGN
 1145E         ; Newa # Mn       NEWA SANDHI MARK
-1145F         ; Newa # Lo       NEWA LETTER VEDIC ANUSVARA
+1145F..11461  ; Newa # Lo   [3] NEWA LETTER VEDIC ANUSVARA..NEWA SIGN UPADHMANIYA
 
-# Total code points: 94
+# Total code points: 97
 
 # ================================================
 
@@ -2668,9 +2684,10 @@ ABF0..ABF9    ; Meetei_Mayek # Nd  [10] MEETEI MAYEK DIGIT ZERO..MEETEI MAYEK DI
 
 16FE0         ; Tangut # Lm       TANGUT ITERATION MARK
 17000..187F7  ; Tangut # Lo [6136] TANGUT IDEOGRAPH-17000..TANGUT IDEOGRAPH-187F7
-18800..18AF2  ; Tangut # Lo [755] TANGUT COMPONENT-001..TANGUT COMPONENT-755
+18800..18AFF  ; Tangut # Lo [768] TANGUT COMPONENT-001..TANGUT COMPONENT-768
+18D00..18D08  ; Tangut # Lo   [9] TANGUT IDEOGRAPH-18D00..TANGUT IDEOGRAPH-18D08
 
-# Total code points: 6892
+# Total code points: 6914
 
 # ================================================
 
@@ -2835,4 +2852,49 @@ ABF0..ABF9    ; Meetei_Mayek # Nd  [10] MEETEI MAYEK DIGIT ZERO..MEETEI MAYEK DI
 
 # Total code points: 59
 
+# ================================================
+
+10FB0..10FC4  ; Chorasmian # Lo  [21] CHORASMIAN LETTER ALEPH..CHORASMIAN LETTER TAW
+10FC5..10FCB  ; Chorasmian # No   [7] CHORASMIAN NUMBER ONE..CHORASMIAN NUMBER ONE HUNDRED
+
+# Total code points: 28
+
+# ================================================
+
+11900..11906  ; Dives_Akuru # Lo   [7] DIVES AKURU LETTER A..DIVES AKURU LETTER E
+11909         ; Dives_Akuru # Lo       DIVES AKURU LETTER O
+1190C..11913  ; Dives_Akuru # Lo   [8] DIVES AKURU LETTER KA..DIVES AKURU LETTER JA
+11915..11916  ; Dives_Akuru # Lo   [2] DIVES AKURU LETTER NYA..DIVES AKURU LETTER TTA
+11918..1192F  ; Dives_Akuru # Lo  [24] DIVES AKURU LETTER DDA..DIVES AKURU LETTER ZA
+11930..11935  ; Dives_Akuru # Mc   [6] DIVES AKURU VOWEL SIGN AA..DIVES AKURU VOWEL SIGN E
+11937..11938  ; Dives_Akuru # Mc   [2] DIVES AKURU VOWEL SIGN AI..DIVES AKURU VOWEL SIGN O
+1193B..1193C  ; Dives_Akuru # Mn   [2] DIVES AKURU SIGN ANUSVARA..DIVES AKURU SIGN CANDRABINDU
+1193D         ; Dives_Akuru # Mc       DIVES AKURU SIGN HALANTA
+1193E         ; Dives_Akuru # Mn       DIVES AKURU VIRAMA
+1193F         ; Dives_Akuru # Lo       DIVES AKURU PREFIXED NASAL SIGN
+11940         ; Dives_Akuru # Mc       DIVES AKURU MEDIAL YA
+11941         ; Dives_Akuru # Lo       DIVES AKURU INITIAL RA
+11942         ; Dives_Akuru # Mc       DIVES AKURU MEDIAL RA
+11943         ; Dives_Akuru # Mn       DIVES AKURU SIGN NUKTA
+11944..11946  ; Dives_Akuru # Po   [3] DIVES AKURU DOUBLE DANDA..DIVES AKURU END OF TEXT MARK
+11950..11959  ; Dives_Akuru # Nd  [10] DIVES AKURU DIGIT ZERO..DIVES AKURU DIGIT NINE
+
+# Total code points: 72
+
+# ================================================
+
+16FE4         ; Khitan_Small_Script # Mn       KHITAN SMALL SCRIPT FILLER
+18B00..18CD5  ; Khitan_Small_Script # Lo [470] KHITAN SMALL SCRIPT CHARACTER-18B00..KHITAN SMALL SCRIPT CHARACTER-18CD5
+
+# Total code points: 471
+
+# ================================================
+
+10E80..10EA9  ; Yezidi # Lo  [42] YEZIDI LETTER ELIF..YEZIDI LETTER ET
+10EAB..10EAC  ; Yezidi # Mn   [2] YEZIDI COMBINING HAMZA MARK..YEZIDI COMBINING MADDA MARK
+10EAD         ; Yezidi # Pd       YEZIDI HYPHENATION MARK
+10EB0..10EB1  ; Yezidi # Lo   [2] YEZIDI LETTER LAM WITH DOT ABOVE..YEZIDI LETTER YOT WITH CIRCUMFLEX ABOVE
+
+# Total code points: 47
+
 # EOF
diff --git a/make/data/unicodedata/SpecialCasing.txt b/make/data/unicodedata/SpecialCasing.txt
index 8977f8f238a..ae71d58f644 100644
--- a/make/data/unicodedata/SpecialCasing.txt
+++ b/make/data/unicodedata/SpecialCasing.txt
@@ -1,5 +1,5 @@
-# SpecialCasing-12.1.0.txt
-# Date: 2019-03-10, 10:53:28 GMT
+# SpecialCasing-13.0.0.txt
+# Date: 2019-09-08, 23:31:24 GMT
 # Copyright (c) 2019 Unicode, Inc.
 # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
 # For terms of use, see http://www.unicode.org/terms_of_use.html
diff --git a/make/data/unicodedata/UnicodeData.txt b/make/data/unicodedata/UnicodeData.txt
index e65aec52f71..e22f967bbab 100644
--- a/make/data/unicodedata/UnicodeData.txt
+++ b/make/data/unicodedata/UnicodeData.txt
@@ -2118,6 +2118,16 @@
 08BB;ARABIC LETTER AFRICAN FEH;Lo;0;AL;;;;;N;;;;;
 08BC;ARABIC LETTER AFRICAN QAF;Lo;0;AL;;;;;N;;;;;
 08BD;ARABIC LETTER AFRICAN NOON;Lo;0;AL;;;;;N;;;;;
+08BE;ARABIC LETTER PEH WITH SMALL V;Lo;0;AL;;;;;N;;;;;
+08BF;ARABIC LETTER TEH WITH SMALL V;Lo;0;AL;;;;;N;;;;;
+08C0;ARABIC LETTER TTEH WITH SMALL V;Lo;0;AL;;;;;N;;;;;
+08C1;ARABIC LETTER TCHEH WITH SMALL V;Lo;0;AL;;;;;N;;;;;
+08C2;ARABIC LETTER KEHEH WITH SMALL V;Lo;0;AL;;;;;N;;;;;
+08C3;ARABIC LETTER GHAIN WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+08C4;ARABIC LETTER AFRICAN QAF WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+08C5;ARABIC LETTER JEEM WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+08C6;ARABIC LETTER JEEM WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;;
+08C7;ARABIC LETTER LAM WITH SMALL ARABIC LETTER TAH ABOVE;Lo;0;AL;;;;;N;;;;;
 08D3;ARABIC SMALL LOW WAW;Mn;220;NSM;;;;;N;;;;;
 08D4;ARABIC SMALL HIGH WORD AR-RUB;Mn;230;NSM;;;;;N;;;;;
 08D5;ARABIC SMALL HIGH SAD;Mn;230;NSM;;;;;N;;;;;
@@ -2621,6 +2631,7 @@
 0B4B;ORIYA VOWEL SIGN O;Mc;0;L;0B47 0B3E;;;;N;;;;;
 0B4C;ORIYA VOWEL SIGN AU;Mc;0;L;0B47 0B57;;;;N;;;;;
 0B4D;ORIYA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+0B55;ORIYA SIGN OVERLINE;Mn;0;NSM;;;;;N;;;;;
 0B56;ORIYA AI LENGTH MARK;Mn;0;NSM;;;;;N;;;;;
 0B57;ORIYA AU LENGTH MARK;Mc;0;L;;;;;N;;;;;
 0B5C;ORIYA LETTER RRA;Lo;0;L;0B21 0B3C;;;;N;;;;;
@@ -2911,6 +2922,7 @@
 0D01;MALAYALAM SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
 0D02;MALAYALAM SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;
 0D03;MALAYALAM SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+0D04;MALAYALAM LETTER VEDIC ANUSVARA;Lo;0;L;;;;;N;;;;;
 0D05;MALAYALAM LETTER A;Lo;0;L;;;;;N;;;;;
 0D06;MALAYALAM LETTER AA;Lo;0;L;;;;;N;;;;;
 0D07;MALAYALAM LETTER I;Lo;0;L;;;;;N;;;;;
@@ -3024,6 +3036,7 @@
 0D7D;MALAYALAM LETTER CHILLU L;Lo;0;L;;;;;N;;;;;
 0D7E;MALAYALAM LETTER CHILLU LL;Lo;0;L;;;;;N;;;;;
 0D7F;MALAYALAM LETTER CHILLU K;Lo;0;L;;;;;N;;;;;
+0D81;SINHALA SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
 0D82;SINHALA SIGN ANUSVARAYA;Mc;0;L;;;;;N;;;;;
 0D83;SINHALA SIGN VISARGAYA;Mc;0;L;;;;;N;;;;;
 0D85;SINHALA LETTER AYANNA;Lo;0;L;;;;;N;;;;;
@@ -6044,6 +6057,8 @@
 1ABC;COMBINING DOUBLE PARENTHESES ABOVE;Mn;230;NSM;;;;;N;;;;;
 1ABD;COMBINING PARENTHESES BELOW;Mn;220;NSM;;;;;N;;;;;
 1ABE;COMBINING PARENTHESES OVERLAY;Me;0;NSM;;;;;N;;;;;
+1ABF;COMBINING LATIN SMALL LETTER W BELOW;Mn;220;NSM;;;;;N;;;;;
+1AC0;COMBINING LATIN SMALL LETTER TURNED W BELOW;Mn;220;NSM;;;;;N;;;;;
 1B00;BALINESE SIGN ULU RICEM;Mn;0;NSM;;;;;N;;;;;
 1B01;BALINESE SIGN ULU CANDRA;Mn;0;NSM;;;;;N;;;;;
 1B02;BALINESE SIGN CECEK;Mn;0;NSM;;;;;N;;;;;
@@ -10133,6 +10148,7 @@
 2B93;NEWLINE RIGHT;So;0;ON;;;;;N;;;;;
 2B94;FOUR CORNER ARROWS CIRCLING ANTICLOCKWISE;So;0;ON;;;;;N;;;;;
 2B95;RIGHTWARDS BLACK ARROW;So;0;ON;;;;;N;;;;;
+2B97;SYMBOL FOR TYPE A ELECTRONICS;So;0;ON;;;;;N;;;;;
 2B98;THREE-D TOP-LIGHTED LEFTWARDS EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
 2B99;THREE-D RIGHT-LIGHTED UPWARDS EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
 2B9A;THREE-D TOP-LIGHTED RIGHTWARDS EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
@@ -10776,6 +10792,9 @@
 2E4D;PARAGRAPHUS MARK;Po;0;ON;;;;;N;;;;;
 2E4E;PUNCTUS ELEVATUS MARK;Po;0;ON;;;;;N;;;;;
 2E4F;CORNISH VERSE DIVIDER;Po;0;ON;;;;;N;;;;;
+2E50;CROSS PATTY WITH RIGHT CROSSBAR;So;0;ON;;;;;N;;;;;
+2E51;CROSS PATTY WITH LEFT CROSSBAR;So;0;ON;;;;;N;;;;;
+2E52;TIRONIAN SIGN CAPITAL ET;Po;0;ON;;;;;N;;;;;
 2E80;CJK RADICAL REPEAT;So;0;ON;;;;;N;;;;;
 2E81;CJK RADICAL CLIFF;So;0;ON;;;;;N;;;;;
 2E82;CJK RADICAL SECOND ONE;So;0;ON;;;;;N;;;;;
@@ -11550,6 +11569,11 @@
 31B8;BOPOMOFO LETTER GH;Lo;0;L;;;;;N;;;;;
 31B9;BOPOMOFO LETTER LH;Lo;0;L;;;;;N;;;;;
 31BA;BOPOMOFO LETTER ZY;Lo;0;L;;;;;N;;;;;
+31BB;BOPOMOFO FINAL LETTER G;Lo;0;L;;;;;N;;;;;
+31BC;BOPOMOFO LETTER GW;Lo;0;L;;;;;N;;;;;
+31BD;BOPOMOFO LETTER KW;Lo;0;L;;;;;N;;;;;
+31BE;BOPOMOFO LETTER OE;Lo;0;L;;;;;N;;;;;
+31BF;BOPOMOFO LETTER AH;Lo;0;L;;;;;N;;;;;
 31C0;CJK STROKE T;So;0;ON;;;;;N;;;;;
 31C1;CJK STROKE WG;So;0;ON;;;;;N;;;;;
 31C2;CJK STROKE XG;So;0;ON;;;;;N;;;;;
@@ -12114,7 +12138,7 @@
 33FE;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTY-ONE;So;0;L; 0033 0031 65E5;;;;N;;;;;
 33FF;SQUARE GAL;So;0;ON; 0067 0061 006C;;;;N;;;;;
 3400;;Lo;0;L;;;;;N;;;;;
-4DB5;;Lo;0;L;;;;;N;;;;;
+4DBF;;Lo;0;L;;;;;N;;;;;
 4DC0;HEXAGRAM FOR THE CREATIVE HEAVEN;So;0;ON;;;;;N;;;;;
 4DC1;HEXAGRAM FOR THE RECEPTIVE EARTH;So;0;ON;;;;;N;;;;;
 4DC2;HEXAGRAM FOR DIFFICULTY AT THE BEGINNING;So;0;ON;;;;;N;;;;;
@@ -12180,7 +12204,7 @@
 4DFE;HEXAGRAM FOR AFTER COMPLETION;So;0;ON;;;;;N;;;;;
 4DFF;HEXAGRAM FOR BEFORE COMPLETION;So;0;ON;;;;;N;;;;;
 4E00;;Lo;0;L;;;;;N;;;;;
-9FEF;;Lo;0;L;;;;;N;;;;;
+9FFC;;Lo;0;L;;;;;N;;;;;
 A000;YI SYLLABLE IT;Lo;0;L;;;;;N;;;;;
 A001;YI SYLLABLE IX;Lo;0;L;;;;;N;;;;;
 A002;YI SYLLABLE I;Lo;0;L;;;;;N;;;;;
@@ -14130,6 +14154,12 @@ A7C3;LATIN SMALL LETTER ANGLICANA W;Ll;0;L;;;;;N;;;A7C2;;A7C2
 A7C4;LATIN CAPITAL LETTER C WITH PALATAL HOOK;Lu;0;L;;;;;N;;;;A794;
 A7C5;LATIN CAPITAL LETTER S WITH HOOK;Lu;0;L;;;;;N;;;;0282;
 A7C6;LATIN CAPITAL LETTER Z WITH PALATAL HOOK;Lu;0;L;;;;;N;;;;1D8E;
+A7C7;LATIN CAPITAL LETTER D WITH SHORT STROKE OVERLAY;Lu;0;L;;;;;N;;;;A7C8;
+A7C8;LATIN SMALL LETTER D WITH SHORT STROKE OVERLAY;Ll;0;L;;;;;N;;;A7C7;;A7C7
+A7C9;LATIN CAPITAL LETTER S WITH SHORT STROKE OVERLAY;Lu;0;L;;;;;N;;;;A7CA;
+A7CA;LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY;Ll;0;L;;;;;N;;;A7C9;;A7C9
+A7F5;LATIN CAPITAL LETTER REVERSED HALF H;Lu;0;L;;;;;N;;;;A7F6;
+A7F6;LATIN SMALL LETTER REVERSED HALF H;Ll;0;L;;;;;N;;;A7F5;;A7F5
 A7F7;LATIN EPIGRAPHIC LETTER SIDEWAYS I;Lo;0;L;;;;;N;;;;;
 A7F8;MODIFIER LETTER CAPITAL H WITH STROKE;Lm;0;L; 0126;;;;N;;;;;
 A7F9;MODIFIER LETTER SMALL LIGATURE OE;Lm;0;L; 0153;;;;N;;;;;
@@ -14183,6 +14213,7 @@ A828;SYLOTI NAGRI POETRY MARK-1;So;0;ON;;;;;N;;;;;
 A829;SYLOTI NAGRI POETRY MARK-2;So;0;ON;;;;;N;;;;;
 A82A;SYLOTI NAGRI POETRY MARK-3;So;0;ON;;;;;N;;;;;
 A82B;SYLOTI NAGRI POETRY MARK-4;So;0;ON;;;;;N;;;;;
+A82C;SYLOTI NAGRI SIGN ALTERNATE HASANTA;Mn;9;NSM;;;;;N;;;;;
 A830;NORTH INDIC FRACTION ONE QUARTER;No;0;L;;;;1/4;N;;;;;
 A831;NORTH INDIC FRACTION ONE HALF;No;0;L;;;;1/2;N;;;;;
 A832;NORTH INDIC FRACTION THREE QUARTERS;No;0;L;;;;3/4;N;;;;;
@@ -14897,6 +14928,10 @@ AB64;LATIN SMALL LETTER INVERTED ALPHA;Ll;0;L;;;;;N;;;;;
 AB65;GREEK LETTER SMALL CAPITAL OMEGA;Ll;0;L;;;;;N;;;;;
 AB66;LATIN SMALL LETTER DZ DIGRAPH WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
 AB67;LATIN SMALL LETTER TS DIGRAPH WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
+AB68;LATIN SMALL LETTER TURNED R WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;
+AB69;MODIFIER LETTER SMALL TURNED W;Lm;0;L; 028D;;;;N;;;;;
+AB6A;MODIFIER LETTER LEFT TACK;Sk;0;ON;;;;;N;;;;;
+AB6B;MODIFIER LETTER RIGHT TACK;Sk;0;ON;;;;;N;;;;;
 AB70;CHEROKEE SMALL LETTER A;Ll;0;L;;;;;N;;;13A0;;13A0
 AB71;CHEROKEE SMALL LETTER E;Ll;0;L;;;;;N;;;13A1;;13A1
 AB72;CHEROKEE SMALL LETTER I;Ll;0;L;;;;;N;;;13A2;;13A2
@@ -17086,6 +17121,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
 10199;ROMAN DUPONDIUS SIGN;So;0;ON;;;;;N;;;;;
 1019A;ROMAN AS SIGN;So;0;ON;;;;;N;;;;;
 1019B;ROMAN CENTURIAL SIGN;So;0;ON;;;;;N;;;;;
+1019C;ASCIA SYMBOL;So;0;ON;;;;;N;;;;;
 101A0;GREEK SYMBOL TAU RHO;So;0;ON;;;;;N;;;;;
 101D0;PHAISTOS DISC SIGN PEDESTRIAN;So;0;L;;;;;N;;;;;
 101D1;PHAISTOS DISC SIGN PLUMED HEAD;So;0;L;;;;;N;;;;;
@@ -19057,6 +19093,53 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
 10E7C;RUMI FRACTION ONE QUARTER;No;0;AN;;;;1/4;N;;;;;
 10E7D;RUMI FRACTION ONE THIRD;No;0;AN;;;;1/3;N;;;;;
 10E7E;RUMI FRACTION TWO THIRDS;No;0;AN;;;;2/3;N;;;;;
+10E80;YEZIDI LETTER ELIF;Lo;0;R;;;;;N;;;;;
+10E81;YEZIDI LETTER BE;Lo;0;R;;;;;N;;;;;
+10E82;YEZIDI LETTER PE;Lo;0;R;;;;;N;;;;;
+10E83;YEZIDI LETTER PHE;Lo;0;R;;;;;N;;;;;
+10E84;YEZIDI LETTER THE;Lo;0;R;;;;;N;;;;;
+10E85;YEZIDI LETTER SE;Lo;0;R;;;;;N;;;;;
+10E86;YEZIDI LETTER CIM;Lo;0;R;;;;;N;;;;;
+10E87;YEZIDI LETTER CHIM;Lo;0;R;;;;;N;;;;;
+10E88;YEZIDI LETTER CHHIM;Lo;0;R;;;;;N;;;;;
+10E89;YEZIDI LETTER HHA;Lo;0;R;;;;;N;;;;;
+10E8A;YEZIDI LETTER XA;Lo;0;R;;;;;N;;;;;
+10E8B;YEZIDI LETTER DAL;Lo;0;R;;;;;N;;;;;
+10E8C;YEZIDI LETTER ZAL;Lo;0;R;;;;;N;;;;;
+10E8D;YEZIDI LETTER RA;Lo;0;R;;;;;N;;;;;
+10E8E;YEZIDI LETTER RHA;Lo;0;R;;;;;N;;;;;
+10E8F;YEZIDI LETTER ZA;Lo;0;R;;;;;N;;;;;
+10E90;YEZIDI LETTER JA;Lo;0;R;;;;;N;;;;;
+10E91;YEZIDI LETTER SIN;Lo;0;R;;;;;N;;;;;
+10E92;YEZIDI LETTER SHIN;Lo;0;R;;;;;N;;;;;
+10E93;YEZIDI LETTER SAD;Lo;0;R;;;;;N;;;;;
+10E94;YEZIDI LETTER DAD;Lo;0;R;;;;;N;;;;;
+10E95;YEZIDI LETTER TA;Lo;0;R;;;;;N;;;;;
+10E96;YEZIDI LETTER ZE;Lo;0;R;;;;;N;;;;;
+10E97;YEZIDI LETTER EYN;Lo;0;R;;;;;N;;;;;
+10E98;YEZIDI LETTER XHEYN;Lo;0;R;;;;;N;;;;;
+10E99;YEZIDI LETTER FA;Lo;0;R;;;;;N;;;;;
+10E9A;YEZIDI LETTER VA;Lo;0;R;;;;;N;;;;;
+10E9B;YEZIDI LETTER VA ALTERNATE FORM;Lo;0;R;;;;;N;;;;;
+10E9C;YEZIDI LETTER QAF;Lo;0;R;;;;;N;;;;;
+10E9D;YEZIDI LETTER KAF;Lo;0;R;;;;;N;;;;;
+10E9E;YEZIDI LETTER KHAF;Lo;0;R;;;;;N;;;;;
+10E9F;YEZIDI LETTER GAF;Lo;0;R;;;;;N;;;;;
+10EA0;YEZIDI LETTER LAM;Lo;0;R;;;;;N;;;;;
+10EA1;YEZIDI LETTER MIM;Lo;0;R;;;;;N;;;;;
+10EA2;YEZIDI LETTER NUN;Lo;0;R;;;;;N;;;;;
+10EA3;YEZIDI LETTER UM;Lo;0;R;;;;;N;;;;;
+10EA4;YEZIDI LETTER WAW;Lo;0;R;;;;;N;;;;;
+10EA5;YEZIDI LETTER OW;Lo;0;R;;;;;N;;;;;
+10EA6;YEZIDI LETTER EW;Lo;0;R;;;;;N;;;;;
+10EA7;YEZIDI LETTER HAY;Lo;0;R;;;;;N;;;;;
+10EA8;YEZIDI LETTER YOT;Lo;0;R;;;;;N;;;;;
+10EA9;YEZIDI LETTER ET;Lo;0;R;;;;;N;;;;;
+10EAB;YEZIDI COMBINING HAMZA MARK;Mn;230;NSM;;;;;N;;;;;
+10EAC;YEZIDI COMBINING MADDA MARK;Mn;230;NSM;;;;;N;;;;;
+10EAD;YEZIDI HYPHENATION MARK;Pd;0;R;;;;;N;;;;;
+10EB0;YEZIDI LETTER LAM WITH DOT ABOVE;Lo;0;R;;;;;N;;;;;
+10EB1;YEZIDI LETTER YOT WITH CIRCUMFLEX ABOVE;Lo;0;R;;;;;N;;;;;
 10F00;OLD SOGDIAN LETTER ALEPH;Lo;0;R;;;;;N;;;;;
 10F01;OLD SOGDIAN LETTER FINAL ALEPH;Lo;0;R;;;;;N;;;;;
 10F02;OLD SOGDIAN LETTER BETH;Lo;0;R;;;;;N;;;;;
@@ -19139,6 +19222,34 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
 10F57;SOGDIAN PUNCTUATION CIRCLE WITH DOT;Po;0;AL;;;;;N;;;;;
 10F58;SOGDIAN PUNCTUATION TWO CIRCLES WITH DOTS;Po;0;AL;;;;;N;;;;;
 10F59;SOGDIAN PUNCTUATION HALF CIRCLE WITH DOT;Po;0;AL;;;;;N;;;;;
+10FB0;CHORASMIAN LETTER ALEPH;Lo;0;R;;;;;N;;;;;
+10FB1;CHORASMIAN LETTER SMALL ALEPH;Lo;0;R;;;;;N;;;;;
+10FB2;CHORASMIAN LETTER BETH;Lo;0;R;;;;;N;;;;;
+10FB3;CHORASMIAN LETTER GIMEL;Lo;0;R;;;;;N;;;;;
+10FB4;CHORASMIAN LETTER DALETH;Lo;0;R;;;;;N;;;;;
+10FB5;CHORASMIAN LETTER HE;Lo;0;R;;;;;N;;;;;
+10FB6;CHORASMIAN LETTER WAW;Lo;0;R;;;;;N;;;;;
+10FB7;CHORASMIAN LETTER CURLED WAW;Lo;0;R;;;;;N;;;;;
+10FB8;CHORASMIAN LETTER ZAYIN;Lo;0;R;;;;;N;;;;;
+10FB9;CHORASMIAN LETTER HETH;Lo;0;R;;;;;N;;;;;
+10FBA;CHORASMIAN LETTER YODH;Lo;0;R;;;;;N;;;;;
+10FBB;CHORASMIAN LETTER KAPH;Lo;0;R;;;;;N;;;;;
+10FBC;CHORASMIAN LETTER LAMEDH;Lo;0;R;;;;;N;;;;;
+10FBD;CHORASMIAN LETTER MEM;Lo;0;R;;;;;N;;;;;
+10FBE;CHORASMIAN LETTER NUN;Lo;0;R;;;;;N;;;;;
+10FBF;CHORASMIAN LETTER SAMEKH;Lo;0;R;;;;;N;;;;;
+10FC0;CHORASMIAN LETTER AYIN;Lo;0;R;;;;;N;;;;;
+10FC1;CHORASMIAN LETTER PE;Lo;0;R;;;;;N;;;;;
+10FC2;CHORASMIAN LETTER RESH;Lo;0;R;;;;;N;;;;;
+10FC3;CHORASMIAN LETTER SHIN;Lo;0;R;;;;;N;;;;;
+10FC4;CHORASMIAN LETTER TAW;Lo;0;R;;;;;N;;;;;
+10FC5;CHORASMIAN NUMBER ONE;No;0;R;;;;1;N;;;;;
+10FC6;CHORASMIAN NUMBER TWO;No;0;R;;;;2;N;;;;;
+10FC7;CHORASMIAN NUMBER THREE;No;0;R;;;;3;N;;;;;
+10FC8;CHORASMIAN NUMBER FOUR;No;0;R;;;;4;N;;;;;
+10FC9;CHORASMIAN NUMBER TEN;No;0;R;;;;10;N;;;;;
+10FCA;CHORASMIAN NUMBER TWENTY;No;0;R;;;;20;N;;;;;
+10FCB;CHORASMIAN NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;;
 10FE0;ELYMAIC LETTER ALEPH;Lo;0;R;;;;;N;;;;;
 10FE1;ELYMAIC LETTER BETH;Lo;0;R;;;;;N;;;;;
 10FE2;ELYMAIC LETTER GIMEL;Lo;0;R;;;;;N;;;;;
@@ -19443,6 +19554,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
 11144;CHAKMA LETTER LHAA;Lo;0;L;;;;;N;;;;;
 11145;CHAKMA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
 11146;CHAKMA VOWEL SIGN EI;Mc;0;L;;;;;N;;;;;
+11147;CHAKMA LETTER VAA;Lo;0;L;;;;;N;;;;;
 11150;MAHAJANI LETTER A;Lo;0;L;;;;;N;;;;;
 11151;MAHAJANI LETTER I;Lo;0;L;;;;;N;;;;;
 11152;MAHAJANI LETTER U;Lo;0;L;;;;;N;;;;;
@@ -19560,6 +19672,8 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
 111CB;SHARADA VOWEL MODIFIER MARK;Mn;0;NSM;;;;;N;;;;;
 111CC;SHARADA EXTRA SHORT VOWEL MARK;Mn;0;NSM;;;;;N;;;;;
 111CD;SHARADA SUTRA MARK;Po;0;L;;;;;N;;;;;
+111CE;SHARADA VOWEL SIGN PRISHTHAMATRA E;Mc;0;L;;;;;N;;;;;
+111CF;SHARADA SIGN INVERTED CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
 111D0;SHARADA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
 111D1;SHARADA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
 111D2;SHARADA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
@@ -19941,10 +20055,13 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
 11457;NEWA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
 11458;NEWA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
 11459;NEWA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+1145A;NEWA DOUBLE COMMA;Po;0;L;;;;;N;;;;;
 1145B;NEWA PLACEHOLDER MARK;Po;0;L;;;;;N;;;;;
 1145D;NEWA INSERTION SIGN;Po;0;L;;;;;N;;;;;
 1145E;NEWA SANDHI MARK;Mn;230;NSM;;;;;N;;;;;
 1145F;NEWA LETTER VEDIC ANUSVARA;Lo;0;L;;;;;N;;;;;
+11460;NEWA SIGN JIHVAMULIYA;Lo;0;L;;;;;N;;;;;
+11461;NEWA SIGN UPADHMANIYA;Lo;0;L;;;;;N;;;;;
 11480;TIRHUTA ANJI;Lo;0;L;;;;;N;;;;;
 11481;TIRHUTA LETTER A;Lo;0;L;;;;;N;;;;;
 11482;TIRHUTA LETTER AA;Lo;0;L;;;;;N;;;;;
@@ -20480,6 +20597,78 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
 118F1;WARANG CITI NUMBER EIGHTY;No;0;L;;;;80;N;;;;;
 118F2;WARANG CITI NUMBER NINETY;No;0;L;;;;90;N;;;;;
 118FF;WARANG CITI OM;Lo;0;L;;;;;N;;;;;
+11900;DIVES AKURU LETTER A;Lo;0;L;;;;;N;;;;;
+11901;DIVES AKURU LETTER AA;Lo;0;L;;;;;N;;;;;
+11902;DIVES AKURU LETTER I;Lo;0;L;;;;;N;;;;;
+11903;DIVES AKURU LETTER II;Lo;0;L;;;;;N;;;;;
+11904;DIVES AKURU LETTER U;Lo;0;L;;;;;N;;;;;
+11905;DIVES AKURU LETTER UU;Lo;0;L;;;;;N;;;;;
+11906;DIVES AKURU LETTER E;Lo;0;L;;;;;N;;;;;
+11909;DIVES AKURU LETTER O;Lo;0;L;;;;;N;;;;;
+1190C;DIVES AKURU LETTER KA;Lo;0;L;;;;;N;;;;;
+1190D;DIVES AKURU LETTER KHA;Lo;0;L;;;;;N;;;;;
+1190E;DIVES AKURU LETTER GA;Lo;0;L;;;;;N;;;;;
+1190F;DIVES AKURU LETTER GHA;Lo;0;L;;;;;N;;;;;
+11910;DIVES AKURU LETTER NGA;Lo;0;L;;;;;N;;;;;
+11911;DIVES AKURU LETTER CA;Lo;0;L;;;;;N;;;;;
+11912;DIVES AKURU LETTER CHA;Lo;0;L;;;;;N;;;;;
+11913;DIVES AKURU LETTER JA;Lo;0;L;;;;;N;;;;;
+11915;DIVES AKURU LETTER NYA;Lo;0;L;;;;;N;;;;;
+11916;DIVES AKURU LETTER TTA;Lo;0;L;;;;;N;;;;;
+11918;DIVES AKURU LETTER DDA;Lo;0;L;;;;;N;;;;;
+11919;DIVES AKURU LETTER DDHA;Lo;0;L;;;;;N;;;;;
+1191A;DIVES AKURU LETTER NNA;Lo;0;L;;;;;N;;;;;
+1191B;DIVES AKURU LETTER TA;Lo;0;L;;;;;N;;;;;
+1191C;DIVES AKURU LETTER THA;Lo;0;L;;;;;N;;;;;
+1191D;DIVES AKURU LETTER DA;Lo;0;L;;;;;N;;;;;
+1191E;DIVES AKURU LETTER DHA;Lo;0;L;;;;;N;;;;;
+1191F;DIVES AKURU LETTER NA;Lo;0;L;;;;;N;;;;;
+11920;DIVES AKURU LETTER PA;Lo;0;L;;;;;N;;;;;
+11921;DIVES AKURU LETTER PHA;Lo;0;L;;;;;N;;;;;
+11922;DIVES AKURU LETTER BA;Lo;0;L;;;;;N;;;;;
+11923;DIVES AKURU LETTER BHA;Lo;0;L;;;;;N;;;;;
+11924;DIVES AKURU LETTER MA;Lo;0;L;;;;;N;;;;;
+11925;DIVES AKURU LETTER YA;Lo;0;L;;;;;N;;;;;
+11926;DIVES AKURU LETTER YYA;Lo;0;L;;;;;N;;;;;
+11927;DIVES AKURU LETTER RA;Lo;0;L;;;;;N;;;;;
+11928;DIVES AKURU LETTER LA;Lo;0;L;;;;;N;;;;;
+11929;DIVES AKURU LETTER VA;Lo;0;L;;;;;N;;;;;
+1192A;DIVES AKURU LETTER SHA;Lo;0;L;;;;;N;;;;;
+1192B;DIVES AKURU LETTER SSA;Lo;0;L;;;;;N;;;;;
+1192C;DIVES AKURU LETTER SA;Lo;0;L;;;;;N;;;;;
+1192D;DIVES AKURU LETTER HA;Lo;0;L;;;;;N;;;;;
+1192E;DIVES AKURU LETTER LLA;Lo;0;L;;;;;N;;;;;
+1192F;DIVES AKURU LETTER ZA;Lo;0;L;;;;;N;;;;;
+11930;DIVES AKURU VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+11931;DIVES AKURU VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+11932;DIVES AKURU VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+11933;DIVES AKURU VOWEL SIGN U;Mc;0;L;;;;;N;;;;;
+11934;DIVES AKURU VOWEL SIGN UU;Mc;0;L;;;;;N;;;;;
+11935;DIVES AKURU VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
+11937;DIVES AKURU VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;
+11938;DIVES AKURU VOWEL SIGN O;Mc;0;L;11935 11930;;;;N;;;;;
+1193B;DIVES AKURU SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+1193C;DIVES AKURU SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
+1193D;DIVES AKURU SIGN HALANTA;Mc;9;L;;;;;N;;;;;
+1193E;DIVES AKURU VIRAMA;Mn;9;NSM;;;;;N;;;;;
+1193F;DIVES AKURU PREFIXED NASAL SIGN;Lo;0;L;;;;;N;;;;;
+11940;DIVES AKURU MEDIAL YA;Mc;0;L;;;;;N;;;;;
+11941;DIVES AKURU INITIAL RA;Lo;0;L;;;;;N;;;;;
+11942;DIVES AKURU MEDIAL RA;Mc;0;L;;;;;N;;;;;
+11943;DIVES AKURU SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
+11944;DIVES AKURU DOUBLE DANDA;Po;0;L;;;;;N;;;;;
+11945;DIVES AKURU GAP FILLER;Po;0;L;;;;;N;;;;;
+11946;DIVES AKURU END OF TEXT MARK;Po;0;L;;;;;N;;;;;
+11950;DIVES AKURU DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+11951;DIVES AKURU DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+11952;DIVES AKURU DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+11953;DIVES AKURU DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+11954;DIVES AKURU DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+11955;DIVES AKURU DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+11956;DIVES AKURU DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+11957;DIVES AKURU DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+11958;DIVES AKURU DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+11959;DIVES AKURU DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
 119A0;NANDINAGARI LETTER A;Lo;0;L;;;;;N;;;;;
 119A1;NANDINAGARI LETTER AA;Lo;0;L;;;;;N;;;;;
 119A2;NANDINAGARI LETTER I;Lo;0;L;;;;;N;;;;;
@@ -21085,6 +21274,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
 11EF6;MAKASAR VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
 11EF7;MAKASAR PASSIMBANG;Po;0;L;;;;;N;;;;;
 11EF8;MAKASAR END OF SECTION;Po;0;L;;;;;N;;;;;
+11FB0;LISU LETTER YHA;Lo;0;L;;;;;N;;;;;
 11FC0;TAMIL FRACTION ONE THREE-HUNDRED-AND-TWENTIETH;No;0;L;;;;1/320;N;;;;;
 11FC1;TAMIL FRACTION ONE ONE-HUNDRED-AND-SIXTIETH;No;0;L;;;;1/160;N;;;;;
 11FC2;TAMIL FRACTION ONE EIGHTIETH;No;0;L;;;;1/80;N;;;;;
@@ -25052,6 +25242,9 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
 16FE1;NUSHU ITERATION MARK;Lm;0;L;;;;;N;;;;;
 16FE2;OLD CHINESE HOOK MARK;Po;0;ON;;;;;N;;;;;
 16FE3;OLD CHINESE ITERATION MARK;Lm;0;L;;;;;N;;;;;
+16FE4;KHITAN SMALL SCRIPT FILLER;Mn;0;NSM;;;;;N;;;;;
+16FF0;VIETNAMESE ALTERNATE READING MARK CA;Mc;6;L;;;;;N;;;;;
+16FF1;VIETNAMESE ALTERNATE READING MARK NHAY;Mc;6;L;;;;;N;;;;;
 17000;;Lo;0;L;;;;;N;;;;;
 187F7;;Lo;0;L;;;;;N;;;;;
 18800;TANGUT COMPONENT-001;Lo;0;L;;;;;N;;;;;
@@ -25809,6 +26002,491 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
 18AF0;TANGUT COMPONENT-753;Lo;0;L;;;;;N;;;;;
 18AF1;TANGUT COMPONENT-754;Lo;0;L;;;;;N;;;;;
 18AF2;TANGUT COMPONENT-755;Lo;0;L;;;;;N;;;;;
+18AF3;TANGUT COMPONENT-756;Lo;0;L;;;;;N;;;;;
+18AF4;TANGUT COMPONENT-757;Lo;0;L;;;;;N;;;;;
+18AF5;TANGUT COMPONENT-758;Lo;0;L;;;;;N;;;;;
+18AF6;TANGUT COMPONENT-759;Lo;0;L;;;;;N;;;;;
+18AF7;TANGUT COMPONENT-760;Lo;0;L;;;;;N;;;;;
+18AF8;TANGUT COMPONENT-761;Lo;0;L;;;;;N;;;;;
+18AF9;TANGUT COMPONENT-762;Lo;0;L;;;;;N;;;;;
+18AFA;TANGUT COMPONENT-763;Lo;0;L;;;;;N;;;;;
+18AFB;TANGUT COMPONENT-764;Lo;0;L;;;;;N;;;;;
+18AFC;TANGUT COMPONENT-765;Lo;0;L;;;;;N;;;;;
+18AFD;TANGUT COMPONENT-766;Lo;0;L;;;;;N;;;;;
+18AFE;TANGUT COMPONENT-767;Lo;0;L;;;;;N;;;;;
+18AFF;TANGUT COMPONENT-768;Lo;0;L;;;;;N;;;;;
+18B00;KHITAN SMALL SCRIPT CHARACTER-18B00;Lo;0;L;;;;;N;;;;;
+18B01;KHITAN SMALL SCRIPT CHARACTER-18B01;Lo;0;L;;;;;N;;;;;
+18B02;KHITAN SMALL SCRIPT CHARACTER-18B02;Lo;0;L;;;;;N;;;;;
+18B03;KHITAN SMALL SCRIPT CHARACTER-18B03;Lo;0;L;;;;;N;;;;;
+18B04;KHITAN SMALL SCRIPT CHARACTER-18B04;Lo;0;L;;;;;N;;;;;
+18B05;KHITAN SMALL SCRIPT CHARACTER-18B05;Lo;0;L;;;;;N;;;;;
+18B06;KHITAN SMALL SCRIPT CHARACTER-18B06;Lo;0;L;;;;;N;;;;;
+18B07;KHITAN SMALL SCRIPT CHARACTER-18B07;Lo;0;L;;;;;N;;;;;
+18B08;KHITAN SMALL SCRIPT CHARACTER-18B08;Lo;0;L;;;;;N;;;;;
+18B09;KHITAN SMALL SCRIPT CHARACTER-18B09;Lo;0;L;;;;;N;;;;;
+18B0A;KHITAN SMALL SCRIPT CHARACTER-18B0A;Lo;0;L;;;;;N;;;;;
+18B0B;KHITAN SMALL SCRIPT CHARACTER-18B0B;Lo;0;L;;;;;N;;;;;
+18B0C;KHITAN SMALL SCRIPT CHARACTER-18B0C;Lo;0;L;;;;;N;;;;;
+18B0D;KHITAN SMALL SCRIPT CHARACTER-18B0D;Lo;0;L;;;;;N;;;;;
+18B0E;KHITAN SMALL SCRIPT CHARACTER-18B0E;Lo;0;L;;;;;N;;;;;
+18B0F;KHITAN SMALL SCRIPT CHARACTER-18B0F;Lo;0;L;;;;;N;;;;;
+18B10;KHITAN SMALL SCRIPT CHARACTER-18B10;Lo;0;L;;;;;N;;;;;
+18B11;KHITAN SMALL SCRIPT CHARACTER-18B11;Lo;0;L;;;;;N;;;;;
+18B12;KHITAN SMALL SCRIPT CHARACTER-18B12;Lo;0;L;;;;;N;;;;;
+18B13;KHITAN SMALL SCRIPT CHARACTER-18B13;Lo;0;L;;;;;N;;;;;
+18B14;KHITAN SMALL SCRIPT CHARACTER-18B14;Lo;0;L;;;;;N;;;;;
+18B15;KHITAN SMALL SCRIPT CHARACTER-18B15;Lo;0;L;;;;;N;;;;;
+18B16;KHITAN SMALL SCRIPT CHARACTER-18B16;Lo;0;L;;;;;N;;;;;
+18B17;KHITAN SMALL SCRIPT CHARACTER-18B17;Lo;0;L;;;;;N;;;;;
+18B18;KHITAN SMALL SCRIPT CHARACTER-18B18;Lo;0;L;;;;;N;;;;;
+18B19;KHITAN SMALL SCRIPT CHARACTER-18B19;Lo;0;L;;;;;N;;;;;
+18B1A;KHITAN SMALL SCRIPT CHARACTER-18B1A;Lo;0;L;;;;;N;;;;;
+18B1B;KHITAN SMALL SCRIPT CHARACTER-18B1B;Lo;0;L;;;;;N;;;;;
+18B1C;KHITAN SMALL SCRIPT CHARACTER-18B1C;Lo;0;L;;;;;N;;;;;
+18B1D;KHITAN SMALL SCRIPT CHARACTER-18B1D;Lo;0;L;;;;;N;;;;;
+18B1E;KHITAN SMALL SCRIPT CHARACTER-18B1E;Lo;0;L;;;;;N;;;;;
+18B1F;KHITAN SMALL SCRIPT CHARACTER-18B1F;Lo;0;L;;;;;N;;;;;
+18B20;KHITAN SMALL SCRIPT CHARACTER-18B20;Lo;0;L;;;;;N;;;;;
+18B21;KHITAN SMALL SCRIPT CHARACTER-18B21;Lo;0;L;;;;;N;;;;;
+18B22;KHITAN SMALL SCRIPT CHARACTER-18B22;Lo;0;L;;;;;N;;;;;
+18B23;KHITAN SMALL SCRIPT CHARACTER-18B23;Lo;0;L;;;;;N;;;;;
+18B24;KHITAN SMALL SCRIPT CHARACTER-18B24;Lo;0;L;;;;;N;;;;;
+18B25;KHITAN SMALL SCRIPT CHARACTER-18B25;Lo;0;L;;;;;N;;;;;
+18B26;KHITAN SMALL SCRIPT CHARACTER-18B26;Lo;0;L;;;;;N;;;;;
+18B27;KHITAN SMALL SCRIPT CHARACTER-18B27;Lo;0;L;;;;;N;;;;;
+18B28;KHITAN SMALL SCRIPT CHARACTER-18B28;Lo;0;L;;;;;N;;;;;
+18B29;KHITAN SMALL SCRIPT CHARACTER-18B29;Lo;0;L;;;;;N;;;;;
+18B2A;KHITAN SMALL SCRIPT CHARACTER-18B2A;Lo;0;L;;;;;N;;;;;
+18B2B;KHITAN SMALL SCRIPT CHARACTER-18B2B;Lo;0;L;;;;;N;;;;;
+18B2C;KHITAN SMALL SCRIPT CHARACTER-18B2C;Lo;0;L;;;;;N;;;;;
+18B2D;KHITAN SMALL SCRIPT CHARACTER-18B2D;Lo;0;L;;;;;N;;;;;
+18B2E;KHITAN SMALL SCRIPT CHARACTER-18B2E;Lo;0;L;;;;;N;;;;;
+18B2F;KHITAN SMALL SCRIPT CHARACTER-18B2F;Lo;0;L;;;;;N;;;;;
+18B30;KHITAN SMALL SCRIPT CHARACTER-18B30;Lo;0;L;;;;;N;;;;;
+18B31;KHITAN SMALL SCRIPT CHARACTER-18B31;Lo;0;L;;;;;N;;;;;
+18B32;KHITAN SMALL SCRIPT CHARACTER-18B32;Lo;0;L;;;;;N;;;;;
+18B33;KHITAN SMALL SCRIPT CHARACTER-18B33;Lo;0;L;;;;;N;;;;;
+18B34;KHITAN SMALL SCRIPT CHARACTER-18B34;Lo;0;L;;;;;N;;;;;
+18B35;KHITAN SMALL SCRIPT CHARACTER-18B35;Lo;0;L;;;;;N;;;;;
+18B36;KHITAN SMALL SCRIPT CHARACTER-18B36;Lo;0;L;;;;;N;;;;;
+18B37;KHITAN SMALL SCRIPT CHARACTER-18B37;Lo;0;L;;;;;N;;;;;
+18B38;KHITAN SMALL SCRIPT CHARACTER-18B38;Lo;0;L;;;;;N;;;;;
+18B39;KHITAN SMALL SCRIPT CHARACTER-18B39;Lo;0;L;;;;;N;;;;;
+18B3A;KHITAN SMALL SCRIPT CHARACTER-18B3A;Lo;0;L;;;;;N;;;;;
+18B3B;KHITAN SMALL SCRIPT CHARACTER-18B3B;Lo;0;L;;;;;N;;;;;
+18B3C;KHITAN SMALL SCRIPT CHARACTER-18B3C;Lo;0;L;;;;;N;;;;;
+18B3D;KHITAN SMALL SCRIPT CHARACTER-18B3D;Lo;0;L;;;;;N;;;;;
+18B3E;KHITAN SMALL SCRIPT CHARACTER-18B3E;Lo;0;L;;;;;N;;;;;
+18B3F;KHITAN SMALL SCRIPT CHARACTER-18B3F;Lo;0;L;;;;;N;;;;;
+18B40;KHITAN SMALL SCRIPT CHARACTER-18B40;Lo;0;L;;;;;N;;;;;
+18B41;KHITAN SMALL SCRIPT CHARACTER-18B41;Lo;0;L;;;;;N;;;;;
+18B42;KHITAN SMALL SCRIPT CHARACTER-18B42;Lo;0;L;;;;;N;;;;;
+18B43;KHITAN SMALL SCRIPT CHARACTER-18B43;Lo;0;L;;;;;N;;;;;
+18B44;KHITAN SMALL SCRIPT CHARACTER-18B44;Lo;0;L;;;;;N;;;;;
+18B45;KHITAN SMALL SCRIPT CHARACTER-18B45;Lo;0;L;;;;;N;;;;;
+18B46;KHITAN SMALL SCRIPT CHARACTER-18B46;Lo;0;L;;;;;N;;;;;
+18B47;KHITAN SMALL SCRIPT CHARACTER-18B47;Lo;0;L;;;;;N;;;;;
+18B48;KHITAN SMALL SCRIPT CHARACTER-18B48;Lo;0;L;;;;;N;;;;;
+18B49;KHITAN SMALL SCRIPT CHARACTER-18B49;Lo;0;L;;;;;N;;;;;
+18B4A;KHITAN SMALL SCRIPT CHARACTER-18B4A;Lo;0;L;;;;;N;;;;;
+18B4B;KHITAN SMALL SCRIPT CHARACTER-18B4B;Lo;0;L;;;;;N;;;;;
+18B4C;KHITAN SMALL SCRIPT CHARACTER-18B4C;Lo;0;L;;;;;N;;;;;
+18B4D;KHITAN SMALL SCRIPT CHARACTER-18B4D;Lo;0;L;;;;;N;;;;;
+18B4E;KHITAN SMALL SCRIPT CHARACTER-18B4E;Lo;0;L;;;;;N;;;;;
+18B4F;KHITAN SMALL SCRIPT CHARACTER-18B4F;Lo;0;L;;;;;N;;;;;
+18B50;KHITAN SMALL SCRIPT CHARACTER-18B50;Lo;0;L;;;;;N;;;;;
+18B51;KHITAN SMALL SCRIPT CHARACTER-18B51;Lo;0;L;;;;;N;;;;;
+18B52;KHITAN SMALL SCRIPT CHARACTER-18B52;Lo;0;L;;;;;N;;;;;
+18B53;KHITAN SMALL SCRIPT CHARACTER-18B53;Lo;0;L;;;;;N;;;;;
+18B54;KHITAN SMALL SCRIPT CHARACTER-18B54;Lo;0;L;;;;;N;;;;;
+18B55;KHITAN SMALL SCRIPT CHARACTER-18B55;Lo;0;L;;;;;N;;;;;
+18B56;KHITAN SMALL SCRIPT CHARACTER-18B56;Lo;0;L;;;;;N;;;;;
+18B57;KHITAN SMALL SCRIPT CHARACTER-18B57;Lo;0;L;;;;;N;;;;;
+18B58;KHITAN SMALL SCRIPT CHARACTER-18B58;Lo;0;L;;;;;N;;;;;
+18B59;KHITAN SMALL SCRIPT CHARACTER-18B59;Lo;0;L;;;;;N;;;;;
+18B5A;KHITAN SMALL SCRIPT CHARACTER-18B5A;Lo;0;L;;;;;N;;;;;
+18B5B;KHITAN SMALL SCRIPT CHARACTER-18B5B;Lo;0;L;;;;;N;;;;;
+18B5C;KHITAN SMALL SCRIPT CHARACTER-18B5C;Lo;0;L;;;;;N;;;;;
+18B5D;KHITAN SMALL SCRIPT CHARACTER-18B5D;Lo;0;L;;;;;N;;;;;
+18B5E;KHITAN SMALL SCRIPT CHARACTER-18B5E;Lo;0;L;;;;;N;;;;;
+18B5F;KHITAN SMALL SCRIPT CHARACTER-18B5F;Lo;0;L;;;;;N;;;;;
+18B60;KHITAN SMALL SCRIPT CHARACTER-18B60;Lo;0;L;;;;;N;;;;;
+18B61;KHITAN SMALL SCRIPT CHARACTER-18B61;Lo;0;L;;;;;N;;;;;
+18B62;KHITAN SMALL SCRIPT CHARACTER-18B62;Lo;0;L;;;;;N;;;;;
+18B63;KHITAN SMALL SCRIPT CHARACTER-18B63;Lo;0;L;;;;;N;;;;;
+18B64;KHITAN SMALL SCRIPT CHARACTER-18B64;Lo;0;L;;;;;N;;;;;
+18B65;KHITAN SMALL SCRIPT CHARACTER-18B65;Lo;0;L;;;;;N;;;;;
+18B66;KHITAN SMALL SCRIPT CHARACTER-18B66;Lo;0;L;;;;;N;;;;;
+18B67;KHITAN SMALL SCRIPT CHARACTER-18B67;Lo;0;L;;;;;N;;;;;
+18B68;KHITAN SMALL SCRIPT CHARACTER-18B68;Lo;0;L;;;;;N;;;;;
+18B69;KHITAN SMALL SCRIPT CHARACTER-18B69;Lo;0;L;;;;;N;;;;;
+18B6A;KHITAN SMALL SCRIPT CHARACTER-18B6A;Lo;0;L;;;;;N;;;;;
+18B6B;KHITAN SMALL SCRIPT CHARACTER-18B6B;Lo;0;L;;;;;N;;;;;
+18B6C;KHITAN SMALL SCRIPT CHARACTER-18B6C;Lo;0;L;;;;;N;;;;;
+18B6D;KHITAN SMALL SCRIPT CHARACTER-18B6D;Lo;0;L;;;;;N;;;;;
+18B6E;KHITAN SMALL SCRIPT CHARACTER-18B6E;Lo;0;L;;;;;N;;;;;
+18B6F;KHITAN SMALL SCRIPT CHARACTER-18B6F;Lo;0;L;;;;;N;;;;;
+18B70;KHITAN SMALL SCRIPT CHARACTER-18B70;Lo;0;L;;;;;N;;;;;
+18B71;KHITAN SMALL SCRIPT CHARACTER-18B71;Lo;0;L;;;;;N;;;;;
+18B72;KHITAN SMALL SCRIPT CHARACTER-18B72;Lo;0;L;;;;;N;;;;;
+18B73;KHITAN SMALL SCRIPT CHARACTER-18B73;Lo;0;L;;;;;N;;;;;
+18B74;KHITAN SMALL SCRIPT CHARACTER-18B74;Lo;0;L;;;;;N;;;;;
+18B75;KHITAN SMALL SCRIPT CHARACTER-18B75;Lo;0;L;;;;;N;;;;;
+18B76;KHITAN SMALL SCRIPT CHARACTER-18B76;Lo;0;L;;;;;N;;;;;
+18B77;KHITAN SMALL SCRIPT CHARACTER-18B77;Lo;0;L;;;;;N;;;;;
+18B78;KHITAN SMALL SCRIPT CHARACTER-18B78;Lo;0;L;;;;;N;;;;;
+18B79;KHITAN SMALL SCRIPT CHARACTER-18B79;Lo;0;L;;;;;N;;;;;
+18B7A;KHITAN SMALL SCRIPT CHARACTER-18B7A;Lo;0;L;;;;;N;;;;;
+18B7B;KHITAN SMALL SCRIPT CHARACTER-18B7B;Lo;0;L;;;;;N;;;;;
+18B7C;KHITAN SMALL SCRIPT CHARACTER-18B7C;Lo;0;L;;;;;N;;;;;
+18B7D;KHITAN SMALL SCRIPT CHARACTER-18B7D;Lo;0;L;;;;;N;;;;;
+18B7E;KHITAN SMALL SCRIPT CHARACTER-18B7E;Lo;0;L;;;;;N;;;;;
+18B7F;KHITAN SMALL SCRIPT CHARACTER-18B7F;Lo;0;L;;;;;N;;;;;
+18B80;KHITAN SMALL SCRIPT CHARACTER-18B80;Lo;0;L;;;;;N;;;;;
+18B81;KHITAN SMALL SCRIPT CHARACTER-18B81;Lo;0;L;;;;;N;;;;;
+18B82;KHITAN SMALL SCRIPT CHARACTER-18B82;Lo;0;L;;;;;N;;;;;
+18B83;KHITAN SMALL SCRIPT CHARACTER-18B83;Lo;0;L;;;;;N;;;;;
+18B84;KHITAN SMALL SCRIPT CHARACTER-18B84;Lo;0;L;;;;;N;;;;;
+18B85;KHITAN SMALL SCRIPT CHARACTER-18B85;Lo;0;L;;;;;N;;;;;
+18B86;KHITAN SMALL SCRIPT CHARACTER-18B86;Lo;0;L;;;;;N;;;;;
+18B87;KHITAN SMALL SCRIPT CHARACTER-18B87;Lo;0;L;;;;;N;;;;;
+18B88;KHITAN SMALL SCRIPT CHARACTER-18B88;Lo;0;L;;;;;N;;;;;
+18B89;KHITAN SMALL SCRIPT CHARACTER-18B89;Lo;0;L;;;;;N;;;;;
+18B8A;KHITAN SMALL SCRIPT CHARACTER-18B8A;Lo;0;L;;;;;N;;;;;
+18B8B;KHITAN SMALL SCRIPT CHARACTER-18B8B;Lo;0;L;;;;;N;;;;;
+18B8C;KHITAN SMALL SCRIPT CHARACTER-18B8C;Lo;0;L;;;;;N;;;;;
+18B8D;KHITAN SMALL SCRIPT CHARACTER-18B8D;Lo;0;L;;;;;N;;;;;
+18B8E;KHITAN SMALL SCRIPT CHARACTER-18B8E;Lo;0;L;;;;;N;;;;;
+18B8F;KHITAN SMALL SCRIPT CHARACTER-18B8F;Lo;0;L;;;;;N;;;;;
+18B90;KHITAN SMALL SCRIPT CHARACTER-18B90;Lo;0;L;;;;;N;;;;;
+18B91;KHITAN SMALL SCRIPT CHARACTER-18B91;Lo;0;L;;;;;N;;;;;
+18B92;KHITAN SMALL SCRIPT CHARACTER-18B92;Lo;0;L;;;;;N;;;;;
+18B93;KHITAN SMALL SCRIPT CHARACTER-18B93;Lo;0;L;;;;;N;;;;;
+18B94;KHITAN SMALL SCRIPT CHARACTER-18B94;Lo;0;L;;;;;N;;;;;
+18B95;KHITAN SMALL SCRIPT CHARACTER-18B95;Lo;0;L;;;;;N;;;;;
+18B96;KHITAN SMALL SCRIPT CHARACTER-18B96;Lo;0;L;;;;;N;;;;;
+18B97;KHITAN SMALL SCRIPT CHARACTER-18B97;Lo;0;L;;;;;N;;;;;
+18B98;KHITAN SMALL SCRIPT CHARACTER-18B98;Lo;0;L;;;;;N;;;;;
+18B99;KHITAN SMALL SCRIPT CHARACTER-18B99;Lo;0;L;;;;;N;;;;;
+18B9A;KHITAN SMALL SCRIPT CHARACTER-18B9A;Lo;0;L;;;;;N;;;;;
+18B9B;KHITAN SMALL SCRIPT CHARACTER-18B9B;Lo;0;L;;;;;N;;;;;
+18B9C;KHITAN SMALL SCRIPT CHARACTER-18B9C;Lo;0;L;;;;;N;;;;;
+18B9D;KHITAN SMALL SCRIPT CHARACTER-18B9D;Lo;0;L;;;;;N;;;;;
+18B9E;KHITAN SMALL SCRIPT CHARACTER-18B9E;Lo;0;L;;;;;N;;;;;
+18B9F;KHITAN SMALL SCRIPT CHARACTER-18B9F;Lo;0;L;;;;;N;;;;;
+18BA0;KHITAN SMALL SCRIPT CHARACTER-18BA0;Lo;0;L;;;;;N;;;;;
+18BA1;KHITAN SMALL SCRIPT CHARACTER-18BA1;Lo;0;L;;;;;N;;;;;
+18BA2;KHITAN SMALL SCRIPT CHARACTER-18BA2;Lo;0;L;;;;;N;;;;;
+18BA3;KHITAN SMALL SCRIPT CHARACTER-18BA3;Lo;0;L;;;;;N;;;;;
+18BA4;KHITAN SMALL SCRIPT CHARACTER-18BA4;Lo;0;L;;;;;N;;;;;
+18BA5;KHITAN SMALL SCRIPT CHARACTER-18BA5;Lo;0;L;;;;;N;;;;;
+18BA6;KHITAN SMALL SCRIPT CHARACTER-18BA6;Lo;0;L;;;;;N;;;;;
+18BA7;KHITAN SMALL SCRIPT CHARACTER-18BA7;Lo;0;L;;;;;N;;;;;
+18BA8;KHITAN SMALL SCRIPT CHARACTER-18BA8;Lo;0;L;;;;;N;;;;;
+18BA9;KHITAN SMALL SCRIPT CHARACTER-18BA9;Lo;0;L;;;;;N;;;;;
+18BAA;KHITAN SMALL SCRIPT CHARACTER-18BAA;Lo;0;L;;;;;N;;;;;
+18BAB;KHITAN SMALL SCRIPT CHARACTER-18BAB;Lo;0;L;;;;;N;;;;;
+18BAC;KHITAN SMALL SCRIPT CHARACTER-18BAC;Lo;0;L;;;;;N;;;;;
+18BAD;KHITAN SMALL SCRIPT CHARACTER-18BAD;Lo;0;L;;;;;N;;;;;
+18BAE;KHITAN SMALL SCRIPT CHARACTER-18BAE;Lo;0;L;;;;;N;;;;;
+18BAF;KHITAN SMALL SCRIPT CHARACTER-18BAF;Lo;0;L;;;;;N;;;;;
+18BB0;KHITAN SMALL SCRIPT CHARACTER-18BB0;Lo;0;L;;;;;N;;;;;
+18BB1;KHITAN SMALL SCRIPT CHARACTER-18BB1;Lo;0;L;;;;;N;;;;;
+18BB2;KHITAN SMALL SCRIPT CHARACTER-18BB2;Lo;0;L;;;;;N;;;;;
+18BB3;KHITAN SMALL SCRIPT CHARACTER-18BB3;Lo;0;L;;;;;N;;;;;
+18BB4;KHITAN SMALL SCRIPT CHARACTER-18BB4;Lo;0;L;;;;;N;;;;;
+18BB5;KHITAN SMALL SCRIPT CHARACTER-18BB5;Lo;0;L;;;;;N;;;;;
+18BB6;KHITAN SMALL SCRIPT CHARACTER-18BB6;Lo;0;L;;;;;N;;;;;
+18BB7;KHITAN SMALL SCRIPT CHARACTER-18BB7;Lo;0;L;;;;;N;;;;;
+18BB8;KHITAN SMALL SCRIPT CHARACTER-18BB8;Lo;0;L;;;;;N;;;;;
+18BB9;KHITAN SMALL SCRIPT CHARACTER-18BB9;Lo;0;L;;;;;N;;;;;
+18BBA;KHITAN SMALL SCRIPT CHARACTER-18BBA;Lo;0;L;;;;;N;;;;;
+18BBB;KHITAN SMALL SCRIPT CHARACTER-18BBB;Lo;0;L;;;;;N;;;;;
+18BBC;KHITAN SMALL SCRIPT CHARACTER-18BBC;Lo;0;L;;;;;N;;;;;
+18BBD;KHITAN SMALL SCRIPT CHARACTER-18BBD;Lo;0;L;;;;;N;;;;;
+18BBE;KHITAN SMALL SCRIPT CHARACTER-18BBE;Lo;0;L;;;;;N;;;;;
+18BBF;KHITAN SMALL SCRIPT CHARACTER-18BBF;Lo;0;L;;;;;N;;;;;
+18BC0;KHITAN SMALL SCRIPT CHARACTER-18BC0;Lo;0;L;;;;;N;;;;;
+18BC1;KHITAN SMALL SCRIPT CHARACTER-18BC1;Lo;0;L;;;;;N;;;;;
+18BC2;KHITAN SMALL SCRIPT CHARACTER-18BC2;Lo;0;L;;;;;N;;;;;
+18BC3;KHITAN SMALL SCRIPT CHARACTER-18BC3;Lo;0;L;;;;;N;;;;;
+18BC4;KHITAN SMALL SCRIPT CHARACTER-18BC4;Lo;0;L;;;;;N;;;;;
+18BC5;KHITAN SMALL SCRIPT CHARACTER-18BC5;Lo;0;L;;;;;N;;;;;
+18BC6;KHITAN SMALL SCRIPT CHARACTER-18BC6;Lo;0;L;;;;;N;;;;;
+18BC7;KHITAN SMALL SCRIPT CHARACTER-18BC7;Lo;0;L;;;;;N;;;;;
+18BC8;KHITAN SMALL SCRIPT CHARACTER-18BC8;Lo;0;L;;;;;N;;;;;
+18BC9;KHITAN SMALL SCRIPT CHARACTER-18BC9;Lo;0;L;;;;;N;;;;;
+18BCA;KHITAN SMALL SCRIPT CHARACTER-18BCA;Lo;0;L;;;;;N;;;;;
+18BCB;KHITAN SMALL SCRIPT CHARACTER-18BCB;Lo;0;L;;;;;N;;;;;
+18BCC;KHITAN SMALL SCRIPT CHARACTER-18BCC;Lo;0;L;;;;;N;;;;;
+18BCD;KHITAN SMALL SCRIPT CHARACTER-18BCD;Lo;0;L;;;;;N;;;;;
+18BCE;KHITAN SMALL SCRIPT CHARACTER-18BCE;Lo;0;L;;;;;N;;;;;
+18BCF;KHITAN SMALL SCRIPT CHARACTER-18BCF;Lo;0;L;;;;;N;;;;;
+18BD0;KHITAN SMALL SCRIPT CHARACTER-18BD0;Lo;0;L;;;;;N;;;;;
+18BD1;KHITAN SMALL SCRIPT CHARACTER-18BD1;Lo;0;L;;;;;N;;;;;
+18BD2;KHITAN SMALL SCRIPT CHARACTER-18BD2;Lo;0;L;;;;;N;;;;;
+18BD3;KHITAN SMALL SCRIPT CHARACTER-18BD3;Lo;0;L;;;;;N;;;;;
+18BD4;KHITAN SMALL SCRIPT CHARACTER-18BD4;Lo;0;L;;;;;N;;;;;
+18BD5;KHITAN SMALL SCRIPT CHARACTER-18BD5;Lo;0;L;;;;;N;;;;;
+18BD6;KHITAN SMALL SCRIPT CHARACTER-18BD6;Lo;0;L;;;;;N;;;;;
+18BD7;KHITAN SMALL SCRIPT CHARACTER-18BD7;Lo;0;L;;;;;N;;;;;
+18BD8;KHITAN SMALL SCRIPT CHARACTER-18BD8;Lo;0;L;;;;;N;;;;;
+18BD9;KHITAN SMALL SCRIPT CHARACTER-18BD9;Lo;0;L;;;;;N;;;;;
+18BDA;KHITAN SMALL SCRIPT CHARACTER-18BDA;Lo;0;L;;;;;N;;;;;
+18BDB;KHITAN SMALL SCRIPT CHARACTER-18BDB;Lo;0;L;;;;;N;;;;;
+18BDC;KHITAN SMALL SCRIPT CHARACTER-18BDC;Lo;0;L;;;;;N;;;;;
+18BDD;KHITAN SMALL SCRIPT CHARACTER-18BDD;Lo;0;L;;;;;N;;;;;
+18BDE;KHITAN SMALL SCRIPT CHARACTER-18BDE;Lo;0;L;;;;;N;;;;;
+18BDF;KHITAN SMALL SCRIPT CHARACTER-18BDF;Lo;0;L;;;;;N;;;;;
+18BE0;KHITAN SMALL SCRIPT CHARACTER-18BE0;Lo;0;L;;;;;N;;;;;
+18BE1;KHITAN SMALL SCRIPT CHARACTER-18BE1;Lo;0;L;;;;;N;;;;;
+18BE2;KHITAN SMALL SCRIPT CHARACTER-18BE2;Lo;0;L;;;;;N;;;;;
+18BE3;KHITAN SMALL SCRIPT CHARACTER-18BE3;Lo;0;L;;;;;N;;;;;
+18BE4;KHITAN SMALL SCRIPT CHARACTER-18BE4;Lo;0;L;;;;;N;;;;;
+18BE5;KHITAN SMALL SCRIPT CHARACTER-18BE5;Lo;0;L;;;;;N;;;;;
+18BE6;KHITAN SMALL SCRIPT CHARACTER-18BE6;Lo;0;L;;;;;N;;;;;
+18BE7;KHITAN SMALL SCRIPT CHARACTER-18BE7;Lo;0;L;;;;;N;;;;;
+18BE8;KHITAN SMALL SCRIPT CHARACTER-18BE8;Lo;0;L;;;;;N;;;;;
+18BE9;KHITAN SMALL SCRIPT CHARACTER-18BE9;Lo;0;L;;;;;N;;;;;
+18BEA;KHITAN SMALL SCRIPT CHARACTER-18BEA;Lo;0;L;;;;;N;;;;;
+18BEB;KHITAN SMALL SCRIPT CHARACTER-18BEB;Lo;0;L;;;;;N;;;;;
+18BEC;KHITAN SMALL SCRIPT CHARACTER-18BEC;Lo;0;L;;;;;N;;;;;
+18BED;KHITAN SMALL SCRIPT CHARACTER-18BED;Lo;0;L;;;;;N;;;;;
+18BEE;KHITAN SMALL SCRIPT CHARACTER-18BEE;Lo;0;L;;;;;N;;;;;
+18BEF;KHITAN SMALL SCRIPT CHARACTER-18BEF;Lo;0;L;;;;;N;;;;;
+18BF0;KHITAN SMALL SCRIPT CHARACTER-18BF0;Lo;0;L;;;;;N;;;;;
+18BF1;KHITAN SMALL SCRIPT CHARACTER-18BF1;Lo;0;L;;;;;N;;;;;
+18BF2;KHITAN SMALL SCRIPT CHARACTER-18BF2;Lo;0;L;;;;;N;;;;;
+18BF3;KHITAN SMALL SCRIPT CHARACTER-18BF3;Lo;0;L;;;;;N;;;;;
+18BF4;KHITAN SMALL SCRIPT CHARACTER-18BF4;Lo;0;L;;;;;N;;;;;
+18BF5;KHITAN SMALL SCRIPT CHARACTER-18BF5;Lo;0;L;;;;;N;;;;;
+18BF6;KHITAN SMALL SCRIPT CHARACTER-18BF6;Lo;0;L;;;;;N;;;;;
+18BF7;KHITAN SMALL SCRIPT CHARACTER-18BF7;Lo;0;L;;;;;N;;;;;
+18BF8;KHITAN SMALL SCRIPT CHARACTER-18BF8;Lo;0;L;;;;;N;;;;;
+18BF9;KHITAN SMALL SCRIPT CHARACTER-18BF9;Lo;0;L;;;;;N;;;;;
+18BFA;KHITAN SMALL SCRIPT CHARACTER-18BFA;Lo;0;L;;;;;N;;;;;
+18BFB;KHITAN SMALL SCRIPT CHARACTER-18BFB;Lo;0;L;;;;;N;;;;;
+18BFC;KHITAN SMALL SCRIPT CHARACTER-18BFC;Lo;0;L;;;;;N;;;;;
+18BFD;KHITAN SMALL SCRIPT CHARACTER-18BFD;Lo;0;L;;;;;N;;;;;
+18BFE;KHITAN SMALL SCRIPT CHARACTER-18BFE;Lo;0;L;;;;;N;;;;;
+18BFF;KHITAN SMALL SCRIPT CHARACTER-18BFF;Lo;0;L;;;;;N;;;;;
+18C00;KHITAN SMALL SCRIPT CHARACTER-18C00;Lo;0;L;;;;;N;;;;;
+18C01;KHITAN SMALL SCRIPT CHARACTER-18C01;Lo;0;L;;;;;N;;;;;
+18C02;KHITAN SMALL SCRIPT CHARACTER-18C02;Lo;0;L;;;;;N;;;;;
+18C03;KHITAN SMALL SCRIPT CHARACTER-18C03;Lo;0;L;;;;;N;;;;;
+18C04;KHITAN SMALL SCRIPT CHARACTER-18C04;Lo;0;L;;;;;N;;;;;
+18C05;KHITAN SMALL SCRIPT CHARACTER-18C05;Lo;0;L;;;;;N;;;;;
+18C06;KHITAN SMALL SCRIPT CHARACTER-18C06;Lo;0;L;;;;;N;;;;;
+18C07;KHITAN SMALL SCRIPT CHARACTER-18C07;Lo;0;L;;;;;N;;;;;
+18C08;KHITAN SMALL SCRIPT CHARACTER-18C08;Lo;0;L;;;;;N;;;;;
+18C09;KHITAN SMALL SCRIPT CHARACTER-18C09;Lo;0;L;;;;;N;;;;;
+18C0A;KHITAN SMALL SCRIPT CHARACTER-18C0A;Lo;0;L;;;;;N;;;;;
+18C0B;KHITAN SMALL SCRIPT CHARACTER-18C0B;Lo;0;L;;;;;N;;;;;
+18C0C;KHITAN SMALL SCRIPT CHARACTER-18C0C;Lo;0;L;;;;;N;;;;;
+18C0D;KHITAN SMALL SCRIPT CHARACTER-18C0D;Lo;0;L;;;;;N;;;;;
+18C0E;KHITAN SMALL SCRIPT CHARACTER-18C0E;Lo;0;L;;;;;N;;;;;
+18C0F;KHITAN SMALL SCRIPT CHARACTER-18C0F;Lo;0;L;;;;;N;;;;;
+18C10;KHITAN SMALL SCRIPT CHARACTER-18C10;Lo;0;L;;;;;N;;;;;
+18C11;KHITAN SMALL SCRIPT CHARACTER-18C11;Lo;0;L;;;;;N;;;;;
+18C12;KHITAN SMALL SCRIPT CHARACTER-18C12;Lo;0;L;;;;;N;;;;;
+18C13;KHITAN SMALL SCRIPT CHARACTER-18C13;Lo;0;L;;;;;N;;;;;
+18C14;KHITAN SMALL SCRIPT CHARACTER-18C14;Lo;0;L;;;;;N;;;;;
+18C15;KHITAN SMALL SCRIPT CHARACTER-18C15;Lo;0;L;;;;;N;;;;;
+18C16;KHITAN SMALL SCRIPT CHARACTER-18C16;Lo;0;L;;;;;N;;;;;
+18C17;KHITAN SMALL SCRIPT CHARACTER-18C17;Lo;0;L;;;;;N;;;;;
+18C18;KHITAN SMALL SCRIPT CHARACTER-18C18;Lo;0;L;;;;;N;;;;;
+18C19;KHITAN SMALL SCRIPT CHARACTER-18C19;Lo;0;L;;;;;N;;;;;
+18C1A;KHITAN SMALL SCRIPT CHARACTER-18C1A;Lo;0;L;;;;;N;;;;;
+18C1B;KHITAN SMALL SCRIPT CHARACTER-18C1B;Lo;0;L;;;;;N;;;;;
+18C1C;KHITAN SMALL SCRIPT CHARACTER-18C1C;Lo;0;L;;;;;N;;;;;
+18C1D;KHITAN SMALL SCRIPT CHARACTER-18C1D;Lo;0;L;;;;;N;;;;;
+18C1E;KHITAN SMALL SCRIPT CHARACTER-18C1E;Lo;0;L;;;;;N;;;;;
+18C1F;KHITAN SMALL SCRIPT CHARACTER-18C1F;Lo;0;L;;;;;N;;;;;
+18C20;KHITAN SMALL SCRIPT CHARACTER-18C20;Lo;0;L;;;;;N;;;;;
+18C21;KHITAN SMALL SCRIPT CHARACTER-18C21;Lo;0;L;;;;;N;;;;;
+18C22;KHITAN SMALL SCRIPT CHARACTER-18C22;Lo;0;L;;;;;N;;;;;
+18C23;KHITAN SMALL SCRIPT CHARACTER-18C23;Lo;0;L;;;;;N;;;;;
+18C24;KHITAN SMALL SCRIPT CHARACTER-18C24;Lo;0;L;;;;;N;;;;;
+18C25;KHITAN SMALL SCRIPT CHARACTER-18C25;Lo;0;L;;;;;N;;;;;
+18C26;KHITAN SMALL SCRIPT CHARACTER-18C26;Lo;0;L;;;;;N;;;;;
+18C27;KHITAN SMALL SCRIPT CHARACTER-18C27;Lo;0;L;;;;;N;;;;;
+18C28;KHITAN SMALL SCRIPT CHARACTER-18C28;Lo;0;L;;;;;N;;;;;
+18C29;KHITAN SMALL SCRIPT CHARACTER-18C29;Lo;0;L;;;;;N;;;;;
+18C2A;KHITAN SMALL SCRIPT CHARACTER-18C2A;Lo;0;L;;;;;N;;;;;
+18C2B;KHITAN SMALL SCRIPT CHARACTER-18C2B;Lo;0;L;;;;;N;;;;;
+18C2C;KHITAN SMALL SCRIPT CHARACTER-18C2C;Lo;0;L;;;;;N;;;;;
+18C2D;KHITAN SMALL SCRIPT CHARACTER-18C2D;Lo;0;L;;;;;N;;;;;
+18C2E;KHITAN SMALL SCRIPT CHARACTER-18C2E;Lo;0;L;;;;;N;;;;;
+18C2F;KHITAN SMALL SCRIPT CHARACTER-18C2F;Lo;0;L;;;;;N;;;;;
+18C30;KHITAN SMALL SCRIPT CHARACTER-18C30;Lo;0;L;;;;;N;;;;;
+18C31;KHITAN SMALL SCRIPT CHARACTER-18C31;Lo;0;L;;;;;N;;;;;
+18C32;KHITAN SMALL SCRIPT CHARACTER-18C32;Lo;0;L;;;;;N;;;;;
+18C33;KHITAN SMALL SCRIPT CHARACTER-18C33;Lo;0;L;;;;;N;;;;;
+18C34;KHITAN SMALL SCRIPT CHARACTER-18C34;Lo;0;L;;;;;N;;;;;
+18C35;KHITAN SMALL SCRIPT CHARACTER-18C35;Lo;0;L;;;;;N;;;;;
+18C36;KHITAN SMALL SCRIPT CHARACTER-18C36;Lo;0;L;;;;;N;;;;;
+18C37;KHITAN SMALL SCRIPT CHARACTER-18C37;Lo;0;L;;;;;N;;;;;
+18C38;KHITAN SMALL SCRIPT CHARACTER-18C38;Lo;0;L;;;;;N;;;;;
+18C39;KHITAN SMALL SCRIPT CHARACTER-18C39;Lo;0;L;;;;;N;;;;;
+18C3A;KHITAN SMALL SCRIPT CHARACTER-18C3A;Lo;0;L;;;;;N;;;;;
+18C3B;KHITAN SMALL SCRIPT CHARACTER-18C3B;Lo;0;L;;;;;N;;;;;
+18C3C;KHITAN SMALL SCRIPT CHARACTER-18C3C;Lo;0;L;;;;;N;;;;;
+18C3D;KHITAN SMALL SCRIPT CHARACTER-18C3D;Lo;0;L;;;;;N;;;;;
+18C3E;KHITAN SMALL SCRIPT CHARACTER-18C3E;Lo;0;L;;;;;N;;;;;
+18C3F;KHITAN SMALL SCRIPT CHARACTER-18C3F;Lo;0;L;;;;;N;;;;;
+18C40;KHITAN SMALL SCRIPT CHARACTER-18C40;Lo;0;L;;;;;N;;;;;
+18C41;KHITAN SMALL SCRIPT CHARACTER-18C41;Lo;0;L;;;;;N;;;;;
+18C42;KHITAN SMALL SCRIPT CHARACTER-18C42;Lo;0;L;;;;;N;;;;;
+18C43;KHITAN SMALL SCRIPT CHARACTER-18C43;Lo;0;L;;;;;N;;;;;
+18C44;KHITAN SMALL SCRIPT CHARACTER-18C44;Lo;0;L;;;;;N;;;;;
+18C45;KHITAN SMALL SCRIPT CHARACTER-18C45;Lo;0;L;;;;;N;;;;;
+18C46;KHITAN SMALL SCRIPT CHARACTER-18C46;Lo;0;L;;;;;N;;;;;
+18C47;KHITAN SMALL SCRIPT CHARACTER-18C47;Lo;0;L;;;;;N;;;;;
+18C48;KHITAN SMALL SCRIPT CHARACTER-18C48;Lo;0;L;;;;;N;;;;;
+18C49;KHITAN SMALL SCRIPT CHARACTER-18C49;Lo;0;L;;;;;N;;;;;
+18C4A;KHITAN SMALL SCRIPT CHARACTER-18C4A;Lo;0;L;;;;;N;;;;;
+18C4B;KHITAN SMALL SCRIPT CHARACTER-18C4B;Lo;0;L;;;;;N;;;;;
+18C4C;KHITAN SMALL SCRIPT CHARACTER-18C4C;Lo;0;L;;;;;N;;;;;
+18C4D;KHITAN SMALL SCRIPT CHARACTER-18C4D;Lo;0;L;;;;;N;;;;;
+18C4E;KHITAN SMALL SCRIPT CHARACTER-18C4E;Lo;0;L;;;;;N;;;;;
+18C4F;KHITAN SMALL SCRIPT CHARACTER-18C4F;Lo;0;L;;;;;N;;;;;
+18C50;KHITAN SMALL SCRIPT CHARACTER-18C50;Lo;0;L;;;;;N;;;;;
+18C51;KHITAN SMALL SCRIPT CHARACTER-18C51;Lo;0;L;;;;;N;;;;;
+18C52;KHITAN SMALL SCRIPT CHARACTER-18C52;Lo;0;L;;;;;N;;;;;
+18C53;KHITAN SMALL SCRIPT CHARACTER-18C53;Lo;0;L;;;;;N;;;;;
+18C54;KHITAN SMALL SCRIPT CHARACTER-18C54;Lo;0;L;;;;;N;;;;;
+18C55;KHITAN SMALL SCRIPT CHARACTER-18C55;Lo;0;L;;;;;N;;;;;
+18C56;KHITAN SMALL SCRIPT CHARACTER-18C56;Lo;0;L;;;;;N;;;;;
+18C57;KHITAN SMALL SCRIPT CHARACTER-18C57;Lo;0;L;;;;;N;;;;;
+18C58;KHITAN SMALL SCRIPT CHARACTER-18C58;Lo;0;L;;;;;N;;;;;
+18C59;KHITAN SMALL SCRIPT CHARACTER-18C59;Lo;0;L;;;;;N;;;;;
+18C5A;KHITAN SMALL SCRIPT CHARACTER-18C5A;Lo;0;L;;;;;N;;;;;
+18C5B;KHITAN SMALL SCRIPT CHARACTER-18C5B;Lo;0;L;;;;;N;;;;;
+18C5C;KHITAN SMALL SCRIPT CHARACTER-18C5C;Lo;0;L;;;;;N;;;;;
+18C5D;KHITAN SMALL SCRIPT CHARACTER-18C5D;Lo;0;L;;;;;N;;;;;
+18C5E;KHITAN SMALL SCRIPT CHARACTER-18C5E;Lo;0;L;;;;;N;;;;;
+18C5F;KHITAN SMALL SCRIPT CHARACTER-18C5F;Lo;0;L;;;;;N;;;;;
+18C60;KHITAN SMALL SCRIPT CHARACTER-18C60;Lo;0;L;;;;;N;;;;;
+18C61;KHITAN SMALL SCRIPT CHARACTER-18C61;Lo;0;L;;;;;N;;;;;
+18C62;KHITAN SMALL SCRIPT CHARACTER-18C62;Lo;0;L;;;;;N;;;;;
+18C63;KHITAN SMALL SCRIPT CHARACTER-18C63;Lo;0;L;;;;;N;;;;;
+18C64;KHITAN SMALL SCRIPT CHARACTER-18C64;Lo;0;L;;;;;N;;;;;
+18C65;KHITAN SMALL SCRIPT CHARACTER-18C65;Lo;0;L;;;;;N;;;;;
+18C66;KHITAN SMALL SCRIPT CHARACTER-18C66;Lo;0;L;;;;;N;;;;;
+18C67;KHITAN SMALL SCRIPT CHARACTER-18C67;Lo;0;L;;;;;N;;;;;
+18C68;KHITAN SMALL SCRIPT CHARACTER-18C68;Lo;0;L;;;;;N;;;;;
+18C69;KHITAN SMALL SCRIPT CHARACTER-18C69;Lo;0;L;;;;;N;;;;;
+18C6A;KHITAN SMALL SCRIPT CHARACTER-18C6A;Lo;0;L;;;;;N;;;;;
+18C6B;KHITAN SMALL SCRIPT CHARACTER-18C6B;Lo;0;L;;;;;N;;;;;
+18C6C;KHITAN SMALL SCRIPT CHARACTER-18C6C;Lo;0;L;;;;;N;;;;;
+18C6D;KHITAN SMALL SCRIPT CHARACTER-18C6D;Lo;0;L;;;;;N;;;;;
+18C6E;KHITAN SMALL SCRIPT CHARACTER-18C6E;Lo;0;L;;;;;N;;;;;
+18C6F;KHITAN SMALL SCRIPT CHARACTER-18C6F;Lo;0;L;;;;;N;;;;;
+18C70;KHITAN SMALL SCRIPT CHARACTER-18C70;Lo;0;L;;;;;N;;;;;
+18C71;KHITAN SMALL SCRIPT CHARACTER-18C71;Lo;0;L;;;;;N;;;;;
+18C72;KHITAN SMALL SCRIPT CHARACTER-18C72;Lo;0;L;;;;;N;;;;;
+18C73;KHITAN SMALL SCRIPT CHARACTER-18C73;Lo;0;L;;;;;N;;;;;
+18C74;KHITAN SMALL SCRIPT CHARACTER-18C74;Lo;0;L;;;;;N;;;;;
+18C75;KHITAN SMALL SCRIPT CHARACTER-18C75;Lo;0;L;;;;;N;;;;;
+18C76;KHITAN SMALL SCRIPT CHARACTER-18C76;Lo;0;L;;;;;N;;;;;
+18C77;KHITAN SMALL SCRIPT CHARACTER-18C77;Lo;0;L;;;;;N;;;;;
+18C78;KHITAN SMALL SCRIPT CHARACTER-18C78;Lo;0;L;;;;;N;;;;;
+18C79;KHITAN SMALL SCRIPT CHARACTER-18C79;Lo;0;L;;;;;N;;;;;
+18C7A;KHITAN SMALL SCRIPT CHARACTER-18C7A;Lo;0;L;;;;;N;;;;;
+18C7B;KHITAN SMALL SCRIPT CHARACTER-18C7B;Lo;0;L;;;;;N;;;;;
+18C7C;KHITAN SMALL SCRIPT CHARACTER-18C7C;Lo;0;L;;;;;N;;;;;
+18C7D;KHITAN SMALL SCRIPT CHARACTER-18C7D;Lo;0;L;;;;;N;;;;;
+18C7E;KHITAN SMALL SCRIPT CHARACTER-18C7E;Lo;0;L;;;;;N;;;;;
+18C7F;KHITAN SMALL SCRIPT CHARACTER-18C7F;Lo;0;L;;;;;N;;;;;
+18C80;KHITAN SMALL SCRIPT CHARACTER-18C80;Lo;0;L;;;;;N;;;;;
+18C81;KHITAN SMALL SCRIPT CHARACTER-18C81;Lo;0;L;;;;;N;;;;;
+18C82;KHITAN SMALL SCRIPT CHARACTER-18C82;Lo;0;L;;;;;N;;;;;
+18C83;KHITAN SMALL SCRIPT CHARACTER-18C83;Lo;0;L;;;;;N;;;;;
+18C84;KHITAN SMALL SCRIPT CHARACTER-18C84;Lo;0;L;;;;;N;;;;;
+18C85;KHITAN SMALL SCRIPT CHARACTER-18C85;Lo;0;L;;;;;N;;;;;
+18C86;KHITAN SMALL SCRIPT CHARACTER-18C86;Lo;0;L;;;;;N;;;;;
+18C87;KHITAN SMALL SCRIPT CHARACTER-18C87;Lo;0;L;;;;;N;;;;;
+18C88;KHITAN SMALL SCRIPT CHARACTER-18C88;Lo;0;L;;;;;N;;;;;
+18C89;KHITAN SMALL SCRIPT CHARACTER-18C89;Lo;0;L;;;;;N;;;;;
+18C8A;KHITAN SMALL SCRIPT CHARACTER-18C8A;Lo;0;L;;;;;N;;;;;
+18C8B;KHITAN SMALL SCRIPT CHARACTER-18C8B;Lo;0;L;;;;;N;;;;;
+18C8C;KHITAN SMALL SCRIPT CHARACTER-18C8C;Lo;0;L;;;;;N;;;;;
+18C8D;KHITAN SMALL SCRIPT CHARACTER-18C8D;Lo;0;L;;;;;N;;;;;
+18C8E;KHITAN SMALL SCRIPT CHARACTER-18C8E;Lo;0;L;;;;;N;;;;;
+18C8F;KHITAN SMALL SCRIPT CHARACTER-18C8F;Lo;0;L;;;;;N;;;;;
+18C90;KHITAN SMALL SCRIPT CHARACTER-18C90;Lo;0;L;;;;;N;;;;;
+18C91;KHITAN SMALL SCRIPT CHARACTER-18C91;Lo;0;L;;;;;N;;;;;
+18C92;KHITAN SMALL SCRIPT CHARACTER-18C92;Lo;0;L;;;;;N;;;;;
+18C93;KHITAN SMALL SCRIPT CHARACTER-18C93;Lo;0;L;;;;;N;;;;;
+18C94;KHITAN SMALL SCRIPT CHARACTER-18C94;Lo;0;L;;;;;N;;;;;
+18C95;KHITAN SMALL SCRIPT CHARACTER-18C95;Lo;0;L;;;;;N;;;;;
+18C96;KHITAN SMALL SCRIPT CHARACTER-18C96;Lo;0;L;;;;;N;;;;;
+18C97;KHITAN SMALL SCRIPT CHARACTER-18C97;Lo;0;L;;;;;N;;;;;
+18C98;KHITAN SMALL SCRIPT CHARACTER-18C98;Lo;0;L;;;;;N;;;;;
+18C99;KHITAN SMALL SCRIPT CHARACTER-18C99;Lo;0;L;;;;;N;;;;;
+18C9A;KHITAN SMALL SCRIPT CHARACTER-18C9A;Lo;0;L;;;;;N;;;;;
+18C9B;KHITAN SMALL SCRIPT CHARACTER-18C9B;Lo;0;L;;;;;N;;;;;
+18C9C;KHITAN SMALL SCRIPT CHARACTER-18C9C;Lo;0;L;;;;;N;;;;;
+18C9D;KHITAN SMALL SCRIPT CHARACTER-18C9D;Lo;0;L;;;;;N;;;;;
+18C9E;KHITAN SMALL SCRIPT CHARACTER-18C9E;Lo;0;L;;;;;N;;;;;
+18C9F;KHITAN SMALL SCRIPT CHARACTER-18C9F;Lo;0;L;;;;;N;;;;;
+18CA0;KHITAN SMALL SCRIPT CHARACTER-18CA0;Lo;0;L;;;;;N;;;;;
+18CA1;KHITAN SMALL SCRIPT CHARACTER-18CA1;Lo;0;L;;;;;N;;;;;
+18CA2;KHITAN SMALL SCRIPT CHARACTER-18CA2;Lo;0;L;;;;;N;;;;;
+18CA3;KHITAN SMALL SCRIPT CHARACTER-18CA3;Lo;0;L;;;;;N;;;;;
+18CA4;KHITAN SMALL SCRIPT CHARACTER-18CA4;Lo;0;L;;;;;N;;;;;
+18CA5;KHITAN SMALL SCRIPT CHARACTER-18CA5;Lo;0;L;;;;;N;;;;;
+18CA6;KHITAN SMALL SCRIPT CHARACTER-18CA6;Lo;0;L;;;;;N;;;;;
+18CA7;KHITAN SMALL SCRIPT CHARACTER-18CA7;Lo;0;L;;;;;N;;;;;
+18CA8;KHITAN SMALL SCRIPT CHARACTER-18CA8;Lo;0;L;;;;;N;;;;;
+18CA9;KHITAN SMALL SCRIPT CHARACTER-18CA9;Lo;0;L;;;;;N;;;;;
+18CAA;KHITAN SMALL SCRIPT CHARACTER-18CAA;Lo;0;L;;;;;N;;;;;
+18CAB;KHITAN SMALL SCRIPT CHARACTER-18CAB;Lo;0;L;;;;;N;;;;;
+18CAC;KHITAN SMALL SCRIPT CHARACTER-18CAC;Lo;0;L;;;;;N;;;;;
+18CAD;KHITAN SMALL SCRIPT CHARACTER-18CAD;Lo;0;L;;;;;N;;;;;
+18CAE;KHITAN SMALL SCRIPT CHARACTER-18CAE;Lo;0;L;;;;;N;;;;;
+18CAF;KHITAN SMALL SCRIPT CHARACTER-18CAF;Lo;0;L;;;;;N;;;;;
+18CB0;KHITAN SMALL SCRIPT CHARACTER-18CB0;Lo;0;L;;;;;N;;;;;
+18CB1;KHITAN SMALL SCRIPT CHARACTER-18CB1;Lo;0;L;;;;;N;;;;;
+18CB2;KHITAN SMALL SCRIPT CHARACTER-18CB2;Lo;0;L;;;;;N;;;;;
+18CB3;KHITAN SMALL SCRIPT CHARACTER-18CB3;Lo;0;L;;;;;N;;;;;
+18CB4;KHITAN SMALL SCRIPT CHARACTER-18CB4;Lo;0;L;;;;;N;;;;;
+18CB5;KHITAN SMALL SCRIPT CHARACTER-18CB5;Lo;0;L;;;;;N;;;;;
+18CB6;KHITAN SMALL SCRIPT CHARACTER-18CB6;Lo;0;L;;;;;N;;;;;
+18CB7;KHITAN SMALL SCRIPT CHARACTER-18CB7;Lo;0;L;;;;;N;;;;;
+18CB8;KHITAN SMALL SCRIPT CHARACTER-18CB8;Lo;0;L;;;;;N;;;;;
+18CB9;KHITAN SMALL SCRIPT CHARACTER-18CB9;Lo;0;L;;;;;N;;;;;
+18CBA;KHITAN SMALL SCRIPT CHARACTER-18CBA;Lo;0;L;;;;;N;;;;;
+18CBB;KHITAN SMALL SCRIPT CHARACTER-18CBB;Lo;0;L;;;;;N;;;;;
+18CBC;KHITAN SMALL SCRIPT CHARACTER-18CBC;Lo;0;L;;;;;N;;;;;
+18CBD;KHITAN SMALL SCRIPT CHARACTER-18CBD;Lo;0;L;;;;;N;;;;;
+18CBE;KHITAN SMALL SCRIPT CHARACTER-18CBE;Lo;0;L;;;;;N;;;;;
+18CBF;KHITAN SMALL SCRIPT CHARACTER-18CBF;Lo;0;L;;;;;N;;;;;
+18CC0;KHITAN SMALL SCRIPT CHARACTER-18CC0;Lo;0;L;;;;;N;;;;;
+18CC1;KHITAN SMALL SCRIPT CHARACTER-18CC1;Lo;0;L;;;;;N;;;;;
+18CC2;KHITAN SMALL SCRIPT CHARACTER-18CC2;Lo;0;L;;;;;N;;;;;
+18CC3;KHITAN SMALL SCRIPT CHARACTER-18CC3;Lo;0;L;;;;;N;;;;;
+18CC4;KHITAN SMALL SCRIPT CHARACTER-18CC4;Lo;0;L;;;;;N;;;;;
+18CC5;KHITAN SMALL SCRIPT CHARACTER-18CC5;Lo;0;L;;;;;N;;;;;
+18CC6;KHITAN SMALL SCRIPT CHARACTER-18CC6;Lo;0;L;;;;;N;;;;;
+18CC7;KHITAN SMALL SCRIPT CHARACTER-18CC7;Lo;0;L;;;;;N;;;;;
+18CC8;KHITAN SMALL SCRIPT CHARACTER-18CC8;Lo;0;L;;;;;N;;;;;
+18CC9;KHITAN SMALL SCRIPT CHARACTER-18CC9;Lo;0;L;;;;;N;;;;;
+18CCA;KHITAN SMALL SCRIPT CHARACTER-18CCA;Lo;0;L;;;;;N;;;;;
+18CCB;KHITAN SMALL SCRIPT CHARACTER-18CCB;Lo;0;L;;;;;N;;;;;
+18CCC;KHITAN SMALL SCRIPT CHARACTER-18CCC;Lo;0;L;;;;;N;;;;;
+18CCD;KHITAN SMALL SCRIPT CHARACTER-18CCD;Lo;0;L;;;;;N;;;;;
+18CCE;KHITAN SMALL SCRIPT CHARACTER-18CCE;Lo;0;L;;;;;N;;;;;
+18CCF;KHITAN SMALL SCRIPT CHARACTER-18CCF;Lo;0;L;;;;;N;;;;;
+18CD0;KHITAN SMALL SCRIPT CHARACTER-18CD0;Lo;0;L;;;;;N;;;;;
+18CD1;KHITAN SMALL SCRIPT CHARACTER-18CD1;Lo;0;L;;;;;N;;;;;
+18CD2;KHITAN SMALL SCRIPT CHARACTER-18CD2;Lo;0;L;;;;;N;;;;;
+18CD3;KHITAN SMALL SCRIPT CHARACTER-18CD3;Lo;0;L;;;;;N;;;;;
+18CD4;KHITAN SMALL SCRIPT CHARACTER-18CD4;Lo;0;L;;;;;N;;;;;
+18CD5;KHITAN SMALL SCRIPT CHARACTER-18CD5;Lo;0;L;;;;;N;;;;;
+18D00;;Lo;0;L;;;;;N;;;;;
+18D08;;Lo;0;L;;;;;N;;;;;
 1B000;KATAKANA LETTER ARCHAIC E;Lo;0;L;;;;;N;;;;;
 1B001;HIRAGANA LETTER ARCHAIC YE;Lo;0;L;;;;;N;;;;;
 1B002;HENTAIGANA LETTER A-1;Lo;0;L;;;;;N;;;;;
@@ -29973,6 +30651,9 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
 1F10A;DIGIT NINE COMMA;No;0;EN; 0039 002C;;9;9;N;;;;;
 1F10B;DINGBAT CIRCLED SANS-SERIF DIGIT ZERO;No;0;ON;;;;0;N;;;;;
 1F10C;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ZERO;No;0;ON;;;;0;N;;;;;
+1F10D;CIRCLED ZERO WITH SLASH;So;0;ON;;;;;N;;;;;
+1F10E;CIRCLED ANTICLOCKWISE ARROW;So;0;ON;;;;;N;;;;;
+1F10F;CIRCLED DOLLAR SIGN WITH OVERLAID BACKSLASH;So;0;ON;;;;;N;;;;;
 1F110;PARENTHESIZED LATIN CAPITAL LETTER A;So;0;L; 0028 0041 0029;;;;N;;;;;
 1F111;PARENTHESIZED LATIN CAPITAL LETTER B;So;0;L; 0028 0042 0029;;;;N;;;;;
 1F112;PARENTHESIZED LATIN CAPITAL LETTER C;So;0;L; 0028 0043 0029;;;;N;;;;;
@@ -30066,6 +30747,9 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
 1F16A;RAISED MC SIGN;So;0;ON; 004D 0043;;;;N;;;;;
 1F16B;RAISED MD SIGN;So;0;ON; 004D 0044;;;;N;;;;;
 1F16C;RAISED MR SIGN;So;0;ON; 004D 0052;;;;N;;;;;
+1F16D;CIRCLED CC;So;0;ON;;;;;N;;;;;
+1F16E;CIRCLED C WITH OVERLAID BACKSLASH;So;0;ON;;;;;N;;;;;
+1F16F;CIRCLED HUMAN FIGURE;So;0;ON;;;;;N;;;;;
 1F170;NEGATIVE SQUARED LATIN CAPITAL LETTER A;So;0;L;;;;;N;;;;;
 1F171;NEGATIVE SQUARED LATIN CAPITAL LETTER B;So;0;L;;;;;N;;;;;
 1F172;NEGATIVE SQUARED LATIN CAPITAL LETTER C;So;0;L;;;;;N;;;;;
@@ -30127,6 +30811,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
 1F1AA;SQUARED SHV;So;0;L;;;;;N;;;;;
 1F1AB;SQUARED UHD;So;0;L;;;;;N;;;;;
 1F1AC;SQUARED VOD;So;0;L;;;;;N;;;;;
+1F1AD;MASK WORK SYMBOL;So;0;ON;;;;;N;;;;;
 1F1E6;REGIONAL INDICATOR SYMBOL LETTER A;So;0;L;;;;;N;;;;;
 1F1E7;REGIONAL INDICATOR SYMBOL LETTER B;So;0;L;;;;;N;;;;;
 1F1E8;REGIONAL INDICATOR SYMBOL LETTER C;So;0;L;;;;;N;;;;;
@@ -31199,6 +31884,8 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
 1F6D3;STUPA;So;0;ON;;;;;N;;;;;
 1F6D4;PAGODA;So;0;ON;;;;;N;;;;;
 1F6D5;HINDU TEMPLE;So;0;ON;;;;;N;;;;;
+1F6D6;HUT;So;0;ON;;;;;N;;;;;
+1F6D7;ELEVATOR;So;0;ON;;;;;N;;;;;
 1F6E0;HAMMER AND WRENCH;So;0;ON;;;;;N;;;;;
 1F6E1;SHIELD;So;0;ON;;;;;N;;;;;
 1F6E2;OIL DRUM;So;0;ON;;;;;N;;;;;
@@ -31223,6 +31910,8 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
 1F6F8;FLYING SAUCER;So;0;ON;;;;;N;;;;;
 1F6F9;SKATEBOARD;So;0;ON;;;;;N;;;;;
 1F6FA;AUTO RICKSHAW;So;0;ON;;;;;N;;;;;
+1F6FB;PICKUP TRUCK;So;0;ON;;;;;N;;;;;
+1F6FC;ROLLER SKATE;So;0;ON;;;;;N;;;;;
 1F700;ALCHEMICAL SYMBOL FOR QUINTESSENCE;So;0;ON;;;;;N;;;;;
 1F701;ALCHEMICAL SYMBOL FOR AIR;So;0;ON;;;;;N;;;;;
 1F702;ALCHEMICAL SYMBOL FOR FIRE;So;0;ON;;;;;N;;;;;
@@ -31588,6 +32277,8 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
 1F8AB;RIGHTWARDS FRONT-TILTED SHADOWED WHITE ARROW;So;0;ON;;;;;N;;;;;
 1F8AC;WHITE ARROW SHAFT WIDTH ONE;So;0;ON;;;;;N;;;;;
 1F8AD;WHITE ARROW SHAFT WIDTH TWO THIRDS;So;0;ON;;;;;N;;;;;
+1F8B0;ARROW POINTING UPWARDS THEN NORTH WEST;So;0;ON;;;;;N;;;;;
+1F8B1;ARROW POINTING RIGHTWARDS THEN CURVING SOUTH WEST;So;0;ON;;;;;N;;;;;
 1F900;CIRCLED CROSS FORMEE WITH FOUR DOTS;So;0;ON;;;;;N;;;;;
 1F901;CIRCLED CROSS FORMEE WITH TWO DOTS;So;0;ON;;;;;N;;;;;
 1F902;CIRCLED CROSS FORMEE;So;0;ON;;;;;N;;;;;
@@ -31600,6 +32291,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
 1F909;DOWNWARD FACING NOTCHED HOOK;So;0;ON;;;;;N;;;;;
 1F90A;DOWNWARD FACING HOOK WITH DOT;So;0;ON;;;;;N;;;;;
 1F90B;DOWNWARD FACING NOTCHED HOOK WITH DOT;So;0;ON;;;;;N;;;;;
+1F90C;PINCHED FINGERS;So;0;ON;;;;;N;;;;;
 1F90D;WHITE HEART;So;0;ON;;;;;N;;;;;
 1F90E;BROWN HEART;So;0;ON;;;;;N;;;;;
 1F90F;PINCHING HAND;So;0;ON;;;;;N;;;;;
@@ -31701,10 +32393,13 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
 1F96F;BAGEL;So;0;ON;;;;;N;;;;;
 1F970;SMILING FACE WITH SMILING EYES AND THREE HEARTS;So;0;ON;;;;;N;;;;;
 1F971;YAWNING FACE;So;0;ON;;;;;N;;;;;
+1F972;SMILING FACE WITH TEAR;So;0;ON;;;;;N;;;;;
 1F973;FACE WITH PARTY HORN AND PARTY HAT;So;0;ON;;;;;N;;;;;
 1F974;FACE WITH UNEVEN EYES AND WAVY MOUTH;So;0;ON;;;;;N;;;;;
 1F975;OVERHEATED FACE;So;0;ON;;;;;N;;;;;
 1F976;FREEZING FACE;So;0;ON;;;;;N;;;;;
+1F977;NINJA;So;0;ON;;;;;N;;;;;
+1F978;DISGUISED FACE;So;0;ON;;;;;N;;;;;
 1F97A;FACE WITH PLEADING EYES;So;0;ON;;;;;N;;;;;
 1F97B;SARI;So;0;ON;;;;;N;;;;;
 1F97C;LAB COAT;So;0;ON;;;;;N;;;;;
@@ -31746,12 +32441,17 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
 1F9A0;MICROBE;So;0;ON;;;;;N;;;;;
 1F9A1;BADGER;So;0;ON;;;;;N;;;;;
 1F9A2;SWAN;So;0;ON;;;;;N;;;;;
+1F9A3;MAMMOTH;So;0;ON;;;;;N;;;;;
+1F9A4;DODO;So;0;ON;;;;;N;;;;;
 1F9A5;SLOTH;So;0;ON;;;;;N;;;;;
 1F9A6;OTTER;So;0;ON;;;;;N;;;;;
 1F9A7;ORANGUTAN;So;0;ON;;;;;N;;;;;
 1F9A8;SKUNK;So;0;ON;;;;;N;;;;;
 1F9A9;FLAMINGO;So;0;ON;;;;;N;;;;;
 1F9AA;OYSTER;So;0;ON;;;;;N;;;;;
+1F9AB;BEAVER;So;0;ON;;;;;N;;;;;
+1F9AC;BISON;So;0;ON;;;;;N;;;;;
+1F9AD;SEAL;So;0;ON;;;;;N;;;;;
 1F9AE;GUIDE DOG;So;0;ON;;;;;N;;;;;
 1F9AF;PROBING CANE;So;0;ON;;;;;N;;;;;
 1F9B0;EMOJI COMPONENT RED HAIR;So;0;ON;;;;;N;;;;;
@@ -31781,6 +32481,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
 1F9C8;BUTTER;So;0;ON;;;;;N;;;;;
 1F9C9;MATE DRINK;So;0;ON;;;;;N;;;;;
 1F9CA;ICE CUBE;So;0;ON;;;;;N;;;;;
+1F9CB;BUBBLE TEA;So;0;ON;;;;;N;;;;;
 1F9CD;STANDING PERSON;So;0;ON;;;;;N;;;;;
 1F9CE;KNEELING PERSON;So;0;ON;;;;;N;;;;;
 1F9CF;DEAF PERSON;So;0;ON;;;;;N;;;;;
@@ -31934,20 +32635,273 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
 1FA71;ONE-PIECE SWIMSUIT;So;0;ON;;;;;N;;;;;
 1FA72;BRIEFS;So;0;ON;;;;;N;;;;;
 1FA73;SHORTS;So;0;ON;;;;;N;;;;;
+1FA74;THONG SANDAL;So;0;ON;;;;;N;;;;;
 1FA78;DROP OF BLOOD;So;0;ON;;;;;N;;;;;
 1FA79;ADHESIVE BANDAGE;So;0;ON;;;;;N;;;;;
 1FA7A;STETHOSCOPE;So;0;ON;;;;;N;;;;;
 1FA80;YO-YO;So;0;ON;;;;;N;;;;;
 1FA81;KITE;So;0;ON;;;;;N;;;;;
 1FA82;PARACHUTE;So;0;ON;;;;;N;;;;;
+1FA83;BOOMERANG;So;0;ON;;;;;N;;;;;
+1FA84;MAGIC WAND;So;0;ON;;;;;N;;;;;
+1FA85;PINATA;So;0;ON;;;;;N;;;;;
+1FA86;NESTING DOLLS;So;0;ON;;;;;N;;;;;
 1FA90;RINGED PLANET;So;0;ON;;;;;N;;;;;
 1FA91;CHAIR;So;0;ON;;;;;N;;;;;
 1FA92;RAZOR;So;0;ON;;;;;N;;;;;
 1FA93;AXE;So;0;ON;;;;;N;;;;;
 1FA94;DIYA LAMP;So;0;ON;;;;;N;;;;;
 1FA95;BANJO;So;0;ON;;;;;N;;;;;
+1FA96;MILITARY HELMET;So;0;ON;;;;;N;;;;;
+1FA97;ACCORDION;So;0;ON;;;;;N;;;;;
+1FA98;LONG DRUM;So;0;ON;;;;;N;;;;;
+1FA99;COIN;So;0;ON;;;;;N;;;;;
+1FA9A;CARPENTRY SAW;So;0;ON;;;;;N;;;;;
+1FA9B;SCREWDRIVER;So;0;ON;;;;;N;;;;;
+1FA9C;LADDER;So;0;ON;;;;;N;;;;;
+1FA9D;HOOK;So;0;ON;;;;;N;;;;;
+1FA9E;MIRROR;So;0;ON;;;;;N;;;;;
+1FA9F;WINDOW;So;0;ON;;;;;N;;;;;
+1FAA0;PLUNGER;So;0;ON;;;;;N;;;;;
+1FAA1;SEWING NEEDLE;So;0;ON;;;;;N;;;;;
+1FAA2;KNOT;So;0;ON;;;;;N;;;;;
+1FAA3;BUCKET;So;0;ON;;;;;N;;;;;
+1FAA4;MOUSE TRAP;So;0;ON;;;;;N;;;;;
+1FAA5;TOOTHBRUSH;So;0;ON;;;;;N;;;;;
+1FAA6;HEADSTONE;So;0;ON;;;;;N;;;;;
+1FAA7;PLACARD;So;0;ON;;;;;N;;;;;
+1FAA8;ROCK;So;0;ON;;;;;N;;;;;
+1FAB0;FLY;So;0;ON;;;;;N;;;;;
+1FAB1;WORM;So;0;ON;;;;;N;;;;;
+1FAB2;BEETLE;So;0;ON;;;;;N;;;;;
+1FAB3;COCKROACH;So;0;ON;;;;;N;;;;;
+1FAB4;POTTED PLANT;So;0;ON;;;;;N;;;;;
+1FAB5;WOOD;So;0;ON;;;;;N;;;;;
+1FAB6;FEATHER;So;0;ON;;;;;N;;;;;
+1FAC0;ANATOMICAL HEART;So;0;ON;;;;;N;;;;;
+1FAC1;LUNGS;So;0;ON;;;;;N;;;;;
+1FAC2;PEOPLE HUGGING;So;0;ON;;;;;N;;;;;
+1FAD0;BLUEBERRIES;So;0;ON;;;;;N;;;;;
+1FAD1;BELL PEPPER;So;0;ON;;;;;N;;;;;
+1FAD2;OLIVE;So;0;ON;;;;;N;;;;;
+1FAD3;FLATBREAD;So;0;ON;;;;;N;;;;;
+1FAD4;TAMALE;So;0;ON;;;;;N;;;;;
+1FAD5;FONDUE;So;0;ON;;;;;N;;;;;
+1FAD6;TEAPOT;So;0;ON;;;;;N;;;;;
+1FB00;BLOCK SEXTANT-1;So;0;ON;;;;;N;;;;;
+1FB01;BLOCK SEXTANT-2;So;0;ON;;;;;N;;;;;
+1FB02;BLOCK SEXTANT-12;So;0;ON;;;;;N;;;;;
+1FB03;BLOCK SEXTANT-3;So;0;ON;;;;;N;;;;;
+1FB04;BLOCK SEXTANT-13;So;0;ON;;;;;N;;;;;
+1FB05;BLOCK SEXTANT-23;So;0;ON;;;;;N;;;;;
+1FB06;BLOCK SEXTANT-123;So;0;ON;;;;;N;;;;;
+1FB07;BLOCK SEXTANT-4;So;0;ON;;;;;N;;;;;
+1FB08;BLOCK SEXTANT-14;So;0;ON;;;;;N;;;;;
+1FB09;BLOCK SEXTANT-24;So;0;ON;;;;;N;;;;;
+1FB0A;BLOCK SEXTANT-124;So;0;ON;;;;;N;;;;;
+1FB0B;BLOCK SEXTANT-34;So;0;ON;;;;;N;;;;;
+1FB0C;BLOCK SEXTANT-134;So;0;ON;;;;;N;;;;;
+1FB0D;BLOCK SEXTANT-234;So;0;ON;;;;;N;;;;;
+1FB0E;BLOCK SEXTANT-1234;So;0;ON;;;;;N;;;;;
+1FB0F;BLOCK SEXTANT-5;So;0;ON;;;;;N;;;;;
+1FB10;BLOCK SEXTANT-15;So;0;ON;;;;;N;;;;;
+1FB11;BLOCK SEXTANT-25;So;0;ON;;;;;N;;;;;
+1FB12;BLOCK SEXTANT-125;So;0;ON;;;;;N;;;;;
+1FB13;BLOCK SEXTANT-35;So;0;ON;;;;;N;;;;;
+1FB14;BLOCK SEXTANT-235;So;0;ON;;;;;N;;;;;
+1FB15;BLOCK SEXTANT-1235;So;0;ON;;;;;N;;;;;
+1FB16;BLOCK SEXTANT-45;So;0;ON;;;;;N;;;;;
+1FB17;BLOCK SEXTANT-145;So;0;ON;;;;;N;;;;;
+1FB18;BLOCK SEXTANT-245;So;0;ON;;;;;N;;;;;
+1FB19;BLOCK SEXTANT-1245;So;0;ON;;;;;N;;;;;
+1FB1A;BLOCK SEXTANT-345;So;0;ON;;;;;N;;;;;
+1FB1B;BLOCK SEXTANT-1345;So;0;ON;;;;;N;;;;;
+1FB1C;BLOCK SEXTANT-2345;So;0;ON;;;;;N;;;;;
+1FB1D;BLOCK SEXTANT-12345;So;0;ON;;;;;N;;;;;
+1FB1E;BLOCK SEXTANT-6;So;0;ON;;;;;N;;;;;
+1FB1F;BLOCK SEXTANT-16;So;0;ON;;;;;N;;;;;
+1FB20;BLOCK SEXTANT-26;So;0;ON;;;;;N;;;;;
+1FB21;BLOCK SEXTANT-126;So;0;ON;;;;;N;;;;;
+1FB22;BLOCK SEXTANT-36;So;0;ON;;;;;N;;;;;
+1FB23;BLOCK SEXTANT-136;So;0;ON;;;;;N;;;;;
+1FB24;BLOCK SEXTANT-236;So;0;ON;;;;;N;;;;;
+1FB25;BLOCK SEXTANT-1236;So;0;ON;;;;;N;;;;;
+1FB26;BLOCK SEXTANT-46;So;0;ON;;;;;N;;;;;
+1FB27;BLOCK SEXTANT-146;So;0;ON;;;;;N;;;;;
+1FB28;BLOCK SEXTANT-1246;So;0;ON;;;;;N;;;;;
+1FB29;BLOCK SEXTANT-346;So;0;ON;;;;;N;;;;;
+1FB2A;BLOCK SEXTANT-1346;So;0;ON;;;;;N;;;;;
+1FB2B;BLOCK SEXTANT-2346;So;0;ON;;;;;N;;;;;
+1FB2C;BLOCK SEXTANT-12346;So;0;ON;;;;;N;;;;;
+1FB2D;BLOCK SEXTANT-56;So;0;ON;;;;;N;;;;;
+1FB2E;BLOCK SEXTANT-156;So;0;ON;;;;;N;;;;;
+1FB2F;BLOCK SEXTANT-256;So;0;ON;;;;;N;;;;;
+1FB30;BLOCK SEXTANT-1256;So;0;ON;;;;;N;;;;;
+1FB31;BLOCK SEXTANT-356;So;0;ON;;;;;N;;;;;
+1FB32;BLOCK SEXTANT-1356;So;0;ON;;;;;N;;;;;
+1FB33;BLOCK SEXTANT-2356;So;0;ON;;;;;N;;;;;
+1FB34;BLOCK SEXTANT-12356;So;0;ON;;;;;N;;;;;
+1FB35;BLOCK SEXTANT-456;So;0;ON;;;;;N;;;;;
+1FB36;BLOCK SEXTANT-1456;So;0;ON;;;;;N;;;;;
+1FB37;BLOCK SEXTANT-2456;So;0;ON;;;;;N;;;;;
+1FB38;BLOCK SEXTANT-12456;So;0;ON;;;;;N;;;;;
+1FB39;BLOCK SEXTANT-3456;So;0;ON;;;;;N;;;;;
+1FB3A;BLOCK SEXTANT-13456;So;0;ON;;;;;N;;;;;
+1FB3B;BLOCK SEXTANT-23456;So;0;ON;;;;;N;;;;;
+1FB3C;LOWER LEFT BLOCK DIAGONAL LOWER MIDDLE LEFT TO LOWER CENTRE;So;0;ON;;;;;N;;;;;
+1FB3D;LOWER LEFT BLOCK DIAGONAL LOWER MIDDLE LEFT TO LOWER RIGHT;So;0;ON;;;;;N;;;;;
+1FB3E;LOWER LEFT BLOCK DIAGONAL UPPER MIDDLE LEFT TO LOWER CENTRE;So;0;ON;;;;;N;;;;;
+1FB3F;LOWER LEFT BLOCK DIAGONAL UPPER MIDDLE LEFT TO LOWER RIGHT;So;0;ON;;;;;N;;;;;
+1FB40;LOWER LEFT BLOCK DIAGONAL UPPER LEFT TO LOWER CENTRE;So;0;ON;;;;;N;;;;;
+1FB41;LOWER RIGHT BLOCK DIAGONAL UPPER MIDDLE LEFT TO UPPER CENTRE;So;0;ON;;;;;N;;;;;
+1FB42;LOWER RIGHT BLOCK DIAGONAL UPPER MIDDLE LEFT TO UPPER RIGHT;So;0;ON;;;;;N;;;;;
+1FB43;LOWER RIGHT BLOCK DIAGONAL LOWER MIDDLE LEFT TO UPPER CENTRE;So;0;ON;;;;;N;;;;;
+1FB44;LOWER RIGHT BLOCK DIAGONAL LOWER MIDDLE LEFT TO UPPER RIGHT;So;0;ON;;;;;N;;;;;
+1FB45;LOWER RIGHT BLOCK DIAGONAL LOWER LEFT TO UPPER CENTRE;So;0;ON;;;;;N;;;;;
+1FB46;LOWER RIGHT BLOCK DIAGONAL LOWER MIDDLE LEFT TO UPPER MIDDLE RIGHT;So;0;ON;;;;;N;;;;;
+1FB47;LOWER RIGHT BLOCK DIAGONAL LOWER CENTRE TO LOWER MIDDLE RIGHT;So;0;ON;;;;;N;;;;;
+1FB48;LOWER RIGHT BLOCK DIAGONAL LOWER LEFT TO LOWER MIDDLE RIGHT;So;0;ON;;;;;N;;;;;
+1FB49;LOWER RIGHT BLOCK DIAGONAL LOWER CENTRE TO UPPER MIDDLE RIGHT;So;0;ON;;;;;N;;;;;
+1FB4A;LOWER RIGHT BLOCK DIAGONAL LOWER LEFT TO UPPER MIDDLE RIGHT;So;0;ON;;;;;N;;;;;
+1FB4B;LOWER RIGHT BLOCK DIAGONAL LOWER CENTRE TO UPPER RIGHT;So;0;ON;;;;;N;;;;;
+1FB4C;LOWER LEFT BLOCK DIAGONAL UPPER CENTRE TO UPPER MIDDLE RIGHT;So;0;ON;;;;;N;;;;;
+1FB4D;LOWER LEFT BLOCK DIAGONAL UPPER LEFT TO UPPER MIDDLE RIGHT;So;0;ON;;;;;N;;;;;
+1FB4E;LOWER LEFT BLOCK DIAGONAL UPPER CENTRE TO LOWER MIDDLE RIGHT;So;0;ON;;;;;N;;;;;
+1FB4F;LOWER LEFT BLOCK DIAGONAL UPPER LEFT TO LOWER MIDDLE RIGHT;So;0;ON;;;;;N;;;;;
+1FB50;LOWER LEFT BLOCK DIAGONAL UPPER CENTRE TO LOWER RIGHT;So;0;ON;;;;;N;;;;;
+1FB51;LOWER LEFT BLOCK DIAGONAL UPPER MIDDLE LEFT TO LOWER MIDDLE RIGHT;So;0;ON;;;;;N;;;;;
+1FB52;UPPER RIGHT BLOCK DIAGONAL LOWER MIDDLE LEFT TO LOWER CENTRE;So;0;ON;;;;;N;;;;;
+1FB53;UPPER RIGHT BLOCK DIAGONAL LOWER MIDDLE LEFT TO LOWER RIGHT;So;0;ON;;;;;N;;;;;
+1FB54;UPPER RIGHT BLOCK DIAGONAL UPPER MIDDLE LEFT TO LOWER CENTRE;So;0;ON;;;;;N;;;;;
+1FB55;UPPER RIGHT BLOCK DIAGONAL UPPER MIDDLE LEFT TO LOWER RIGHT;So;0;ON;;;;;N;;;;;
+1FB56;UPPER RIGHT BLOCK DIAGONAL UPPER LEFT TO LOWER CENTRE;So;0;ON;;;;;N;;;;;
+1FB57;UPPER LEFT BLOCK DIAGONAL UPPER MIDDLE LEFT TO UPPER CENTRE;So;0;ON;;;;;N;;;;;
+1FB58;UPPER LEFT BLOCK DIAGONAL UPPER MIDDLE LEFT TO UPPER RIGHT;So;0;ON;;;;;N;;;;;
+1FB59;UPPER LEFT BLOCK DIAGONAL LOWER MIDDLE LEFT TO UPPER CENTRE;So;0;ON;;;;;N;;;;;
+1FB5A;UPPER LEFT BLOCK DIAGONAL LOWER MIDDLE LEFT TO UPPER RIGHT;So;0;ON;;;;;N;;;;;
+1FB5B;UPPER LEFT BLOCK DIAGONAL LOWER LEFT TO UPPER CENTRE;So;0;ON;;;;;N;;;;;
+1FB5C;UPPER LEFT BLOCK DIAGONAL LOWER MIDDLE LEFT TO UPPER MIDDLE RIGHT;So;0;ON;;;;;N;;;;;
+1FB5D;UPPER LEFT BLOCK DIAGONAL LOWER CENTRE TO LOWER MIDDLE RIGHT;So;0;ON;;;;;N;;;;;
+1FB5E;UPPER LEFT BLOCK DIAGONAL LOWER LEFT TO LOWER MIDDLE RIGHT;So;0;ON;;;;;N;;;;;
+1FB5F;UPPER LEFT BLOCK DIAGONAL LOWER CENTRE TO UPPER MIDDLE RIGHT;So;0;ON;;;;;N;;;;;
+1FB60;UPPER LEFT BLOCK DIAGONAL LOWER LEFT TO UPPER MIDDLE RIGHT;So;0;ON;;;;;N;;;;;
+1FB61;UPPER LEFT BLOCK DIAGONAL LOWER CENTRE TO UPPER RIGHT;So;0;ON;;;;;N;;;;;
+1FB62;UPPER RIGHT BLOCK DIAGONAL UPPER CENTRE TO UPPER MIDDLE RIGHT;So;0;ON;;;;;N;;;;;
+1FB63;UPPER RIGHT BLOCK DIAGONAL UPPER LEFT TO UPPER MIDDLE RIGHT;So;0;ON;;;;;N;;;;;
+1FB64;UPPER RIGHT BLOCK DIAGONAL UPPER CENTRE TO LOWER MIDDLE RIGHT;So;0;ON;;;;;N;;;;;
+1FB65;UPPER RIGHT BLOCK DIAGONAL UPPER LEFT TO LOWER MIDDLE RIGHT;So;0;ON;;;;;N;;;;;
+1FB66;UPPER RIGHT BLOCK DIAGONAL UPPER CENTRE TO LOWER RIGHT;So;0;ON;;;;;N;;;;;
+1FB67;UPPER RIGHT BLOCK DIAGONAL UPPER MIDDLE LEFT TO LOWER MIDDLE RIGHT;So;0;ON;;;;;N;;;;;
+1FB68;UPPER AND RIGHT AND LOWER TRIANGULAR THREE QUARTERS BLOCK;So;0;ON;;;;;N;;;;;
+1FB69;LEFT AND LOWER AND RIGHT TRIANGULAR THREE QUARTERS BLOCK;So;0;ON;;;;;N;;;;;
+1FB6A;UPPER AND LEFT AND LOWER TRIANGULAR THREE QUARTERS BLOCK;So;0;ON;;;;;N;;;;;
+1FB6B;LEFT AND UPPER AND RIGHT TRIANGULAR THREE QUARTERS BLOCK;So;0;ON;;;;;N;;;;;
+1FB6C;LEFT TRIANGULAR ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;;
+1FB6D;UPPER TRIANGULAR ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;;
+1FB6E;RIGHT TRIANGULAR ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;;
+1FB6F;LOWER TRIANGULAR ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;;
+1FB70;VERTICAL ONE EIGHTH BLOCK-2;So;0;ON;;;;;N;;;;;
+1FB71;VERTICAL ONE EIGHTH BLOCK-3;So;0;ON;;;;;N;;;;;
+1FB72;VERTICAL ONE EIGHTH BLOCK-4;So;0;ON;;;;;N;;;;;
+1FB73;VERTICAL ONE EIGHTH BLOCK-5;So;0;ON;;;;;N;;;;;
+1FB74;VERTICAL ONE EIGHTH BLOCK-6;So;0;ON;;;;;N;;;;;
+1FB75;VERTICAL ONE EIGHTH BLOCK-7;So;0;ON;;;;;N;;;;;
+1FB76;HORIZONTAL ONE EIGHTH BLOCK-2;So;0;ON;;;;;N;;;;;
+1FB77;HORIZONTAL ONE EIGHTH BLOCK-3;So;0;ON;;;;;N;;;;;
+1FB78;HORIZONTAL ONE EIGHTH BLOCK-4;So;0;ON;;;;;N;;;;;
+1FB79;HORIZONTAL ONE EIGHTH BLOCK-5;So;0;ON;;;;;N;;;;;
+1FB7A;HORIZONTAL ONE EIGHTH BLOCK-6;So;0;ON;;;;;N;;;;;
+1FB7B;HORIZONTAL ONE EIGHTH BLOCK-7;So;0;ON;;;;;N;;;;;
+1FB7C;LEFT AND LOWER ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;;
+1FB7D;LEFT AND UPPER ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;;
+1FB7E;RIGHT AND UPPER ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;;
+1FB7F;RIGHT AND LOWER ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;;
+1FB80;UPPER AND LOWER ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;;
+1FB81;HORIZONTAL ONE EIGHTH BLOCK-1358;So;0;ON;;;;;N;;;;;
+1FB82;UPPER ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;;
+1FB83;UPPER THREE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;;
+1FB84;UPPER FIVE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;;
+1FB85;UPPER THREE QUARTERS BLOCK;So;0;ON;;;;;N;;;;;
+1FB86;UPPER SEVEN EIGHTHS BLOCK;So;0;ON;;;;;N;;;;;
+1FB87;RIGHT ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;;
+1FB88;RIGHT THREE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;;
+1FB89;RIGHT FIVE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;;
+1FB8A;RIGHT THREE QUARTERS BLOCK;So;0;ON;;;;;N;;;;;
+1FB8B;RIGHT SEVEN EIGHTHS BLOCK;So;0;ON;;;;;N;;;;;
+1FB8C;LEFT HALF MEDIUM SHADE;So;0;ON;;;;;N;;;;;
+1FB8D;RIGHT HALF MEDIUM SHADE;So;0;ON;;;;;N;;;;;
+1FB8E;UPPER HALF MEDIUM SHADE;So;0;ON;;;;;N;;;;;
+1FB8F;LOWER HALF MEDIUM SHADE;So;0;ON;;;;;N;;;;;
+1FB90;INVERSE MEDIUM SHADE;So;0;ON;;;;;N;;;;;
+1FB91;UPPER HALF BLOCK AND LOWER HALF INVERSE MEDIUM SHADE;So;0;ON;;;;;N;;;;;
+1FB92;UPPER HALF INVERSE MEDIUM SHADE AND LOWER HALF BLOCK;So;0;ON;;;;;N;;;;;
+1FB94;LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK;So;0;ON;;;;;N;;;;;
+1FB95;CHECKER BOARD FILL;So;0;ON;;;;;N;;;;;
+1FB96;INVERSE CHECKER BOARD FILL;So;0;ON;;;;;N;;;;;
+1FB97;HEAVY HORIZONTAL FILL;So;0;ON;;;;;N;;;;;
+1FB98;UPPER LEFT TO LOWER RIGHT FILL;So;0;ON;;;;;N;;;;;
+1FB99;UPPER RIGHT TO LOWER LEFT FILL;So;0;ON;;;;;N;;;;;
+1FB9A;UPPER AND LOWER TRIANGULAR HALF BLOCK;So;0;ON;;;;;N;;;;;
+1FB9B;LEFT AND RIGHT TRIANGULAR HALF BLOCK;So;0;ON;;;;;N;;;;;
+1FB9C;UPPER LEFT TRIANGULAR MEDIUM SHADE;So;0;ON;;;;;N;;;;;
+1FB9D;UPPER RIGHT TRIANGULAR MEDIUM SHADE;So;0;ON;;;;;N;;;;;
+1FB9E;LOWER RIGHT TRIANGULAR MEDIUM SHADE;So;0;ON;;;;;N;;;;;
+1FB9F;LOWER LEFT TRIANGULAR MEDIUM SHADE;So;0;ON;;;;;N;;;;;
+1FBA0;BOX DRAWINGS LIGHT DIAGONAL UPPER CENTRE TO MIDDLE LEFT;So;0;ON;;;;;N;;;;;
+1FBA1;BOX DRAWINGS LIGHT DIAGONAL UPPER CENTRE TO MIDDLE RIGHT;So;0;ON;;;;;N;;;;;
+1FBA2;BOX DRAWINGS LIGHT DIAGONAL MIDDLE LEFT TO LOWER CENTRE;So;0;ON;;;;;N;;;;;
+1FBA3;BOX DRAWINGS LIGHT DIAGONAL MIDDLE RIGHT TO LOWER CENTRE;So;0;ON;;;;;N;;;;;
+1FBA4;BOX DRAWINGS LIGHT DIAGONAL UPPER CENTRE TO MIDDLE LEFT TO LOWER CENTRE;So;0;ON;;;;;N;;;;;
+1FBA5;BOX DRAWINGS LIGHT DIAGONAL UPPER CENTRE TO MIDDLE RIGHT TO LOWER CENTRE;So;0;ON;;;;;N;;;;;
+1FBA6;BOX DRAWINGS LIGHT DIAGONAL MIDDLE LEFT TO LOWER CENTRE TO MIDDLE RIGHT;So;0;ON;;;;;N;;;;;
+1FBA7;BOX DRAWINGS LIGHT DIAGONAL MIDDLE LEFT TO UPPER CENTRE TO MIDDLE RIGHT;So;0;ON;;;;;N;;;;;
+1FBA8;BOX DRAWINGS LIGHT DIAGONAL UPPER CENTRE TO MIDDLE LEFT AND MIDDLE RIGHT TO LOWER CENTRE;So;0;ON;;;;;N;;;;;
+1FBA9;BOX DRAWINGS LIGHT DIAGONAL UPPER CENTRE TO MIDDLE RIGHT AND MIDDLE LEFT TO LOWER CENTRE;So;0;ON;;;;;N;;;;;
+1FBAA;BOX DRAWINGS LIGHT DIAGONAL UPPER CENTRE TO MIDDLE RIGHT TO LOWER CENTRE TO MIDDLE LEFT;So;0;ON;;;;;N;;;;;
+1FBAB;BOX DRAWINGS LIGHT DIAGONAL UPPER CENTRE TO MIDDLE LEFT TO LOWER CENTRE TO MIDDLE RIGHT;So;0;ON;;;;;N;;;;;
+1FBAC;BOX DRAWINGS LIGHT DIAGONAL MIDDLE LEFT TO UPPER CENTRE TO MIDDLE RIGHT TO LOWER CENTRE;So;0;ON;;;;;N;;;;;
+1FBAD;BOX DRAWINGS LIGHT DIAGONAL MIDDLE RIGHT TO UPPER CENTRE TO MIDDLE LEFT TO LOWER CENTRE;So;0;ON;;;;;N;;;;;
+1FBAE;BOX DRAWINGS LIGHT DIAGONAL DIAMOND;So;0;ON;;;;;N;;;;;
+1FBAF;BOX DRAWINGS LIGHT HORIZONTAL WITH VERTICAL STROKE;So;0;ON;;;;;N;;;;;
+1FBB0;ARROWHEAD-SHAPED POINTER;So;0;ON;;;;;N;;;;;
+1FBB1;INVERSE CHECK MARK;So;0;ON;;;;;N;;;;;
+1FBB2;LEFT HALF RUNNING MAN;So;0;ON;;;;;N;;;;;
+1FBB3;RIGHT HALF RUNNING MAN;So;0;ON;;;;;N;;;;;
+1FBB4;INVERSE DOWNWARDS ARROW WITH TIP LEFTWARDS;So;0;ON;;;;;N;;;;;
+1FBB5;LEFTWARDS ARROW AND UPPER AND LOWER ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;;
+1FBB6;RIGHTWARDS ARROW AND UPPER AND LOWER ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;;
+1FBB7;DOWNWARDS ARROW AND RIGHT ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;;
+1FBB8;UPWARDS ARROW AND RIGHT ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;;
+1FBB9;LEFT HALF FOLDER;So;0;ON;;;;;N;;;;;
+1FBBA;RIGHT HALF FOLDER;So;0;ON;;;;;N;;;;;
+1FBBB;VOIDED GREEK CROSS;So;0;ON;;;;;N;;;;;
+1FBBC;RIGHT OPEN SQUARED DOT;So;0;ON;;;;;N;;;;;
+1FBBD;NEGATIVE DIAGONAL CROSS;So;0;ON;;;;;N;;;;;
+1FBBE;NEGATIVE DIAGONAL MIDDLE RIGHT TO LOWER CENTRE;So;0;ON;;;;;N;;;;;
+1FBBF;NEGATIVE DIAGONAL DIAMOND;So;0;ON;;;;;N;;;;;
+1FBC0;WHITE HEAVY SALTIRE WITH ROUNDED CORNERS;So;0;ON;;;;;N;;;;;
+1FBC1;LEFT THIRD WHITE RIGHT POINTING INDEX;So;0;ON;;;;;N;;;;;
+1FBC2;MIDDLE THIRD WHITE RIGHT POINTING INDEX;So;0;ON;;;;;N;;;;;
+1FBC3;RIGHT THIRD WHITE RIGHT POINTING INDEX;So;0;ON;;;;;N;;;;;
+1FBC4;NEGATIVE SQUARED QUESTION MARK;So;0;ON;;;;;N;;;;;
+1FBC5;STICK FIGURE;So;0;ON;;;;;N;;;;;
+1FBC6;STICK FIGURE WITH ARMS RAISED;So;0;ON;;;;;N;;;;;
+1FBC7;STICK FIGURE LEANING LEFT;So;0;ON;;;;;N;;;;;
+1FBC8;STICK FIGURE LEANING RIGHT;So;0;ON;;;;;N;;;;;
+1FBC9;STICK FIGURE WITH DRESS;So;0;ON;;;;;N;;;;;
+1FBCA;WHITE UP-POINTING CHEVRON;So;0;ON;;;;;N;;;;;
+1FBF0;SEGMENTED DIGIT ZERO;Nd;0;EN; 0030;0;0;0;N;;;;;
+1FBF1;SEGMENTED DIGIT ONE;Nd;0;EN; 0031;1;1;1;N;;;;;
+1FBF2;SEGMENTED DIGIT TWO;Nd;0;EN; 0032;2;2;2;N;;;;;
+1FBF3;SEGMENTED DIGIT THREE;Nd;0;EN; 0033;3;3;3;N;;;;;
+1FBF4;SEGMENTED DIGIT FOUR;Nd;0;EN; 0034;4;4;4;N;;;;;
+1FBF5;SEGMENTED DIGIT FIVE;Nd;0;EN; 0035;5;5;5;N;;;;;
+1FBF6;SEGMENTED DIGIT SIX;Nd;0;EN; 0036;6;6;6;N;;;;;
+1FBF7;SEGMENTED DIGIT SEVEN;Nd;0;EN; 0037;7;7;7;N;;;;;
+1FBF8;SEGMENTED DIGIT EIGHT;Nd;0;EN; 0038;8;8;8;N;;;;;
+1FBF9;SEGMENTED DIGIT NINE;Nd;0;EN; 0039;9;9;9;N;;;;;
 20000;;Lo;0;L;;;;;N;;;;;
-2A6D6;;Lo;0;L;;;;;N;;;;;
+2A6DD;;Lo;0;L;;;;;N;;;;;
 2A700;;Lo;0;L;;;;;N;;;;;
 2B734;;Lo;0;L;;;;;N;;;;;
 2B740;;Lo;0;L;;;;;N;;;;;
@@ -32498,6 +33452,8 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
 2FA1B;CJK COMPATIBILITY IDEOGRAPH-2FA1B;Lo;0;L;9F16;;;;N;;;;;
 2FA1C;CJK COMPATIBILITY IDEOGRAPH-2FA1C;Lo;0;L;9F3B;;;;N;;;;;
 2FA1D;CJK COMPATIBILITY IDEOGRAPH-2FA1D;Lo;0;L;2A600;;;;N;;;;;
+30000;;Lo;0;L;;;;;N;;;;;
+3134A;;Lo;0;L;;;;;N;;;;;
 E0001;LANGUAGE TAG;Cf;0;BN;;;;;N;;;;;
 E0020;TAG SPACE;Cf;0;BN;;;;;N;;;;;
 E0021;TAG EXCLAMATION MARK;Cf;0;BN;;;;;N;;;;;
diff --git a/make/data/unicodedata/VERSION b/make/data/unicodedata/VERSION
index 77903b35f3a..02161ca86e5 100644
--- a/make/data/unicodedata/VERSION
+++ b/make/data/unicodedata/VERSION
@@ -1 +1 @@
-12.1.0
+13.0.0
diff --git a/make/data/unicodedata/auxiliary/GraphemeBreakProperty.txt b/make/data/unicodedata/auxiliary/GraphemeBreakProperty.txt
index 40faaf82979..504c7082802 100644
--- a/make/data/unicodedata/auxiliary/GraphemeBreakProperty.txt
+++ b/make/data/unicodedata/auxiliary/GraphemeBreakProperty.txt
@@ -1,5 +1,5 @@
-# GraphemeBreakProperty-12.1.0.txt
-# Date: 2019-03-10, 10:53:12 GMT
+# GraphemeBreakProperty-13.0.0.txt
+# Date: 2019-10-21, 14:30:35 GMT
 # Copyright (c) 2019 Unicode, Inc.
 # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
 # For terms of use, see http://www.unicode.org/terms_of_use.html
@@ -26,11 +26,13 @@
 110BD         ; Prepend # Cf       KAITHI NUMBER SIGN
 110CD         ; Prepend # Cf       KAITHI NUMBER SIGN ABOVE
 111C2..111C3  ; Prepend # Lo   [2] SHARADA SIGN JIHVAMULIYA..SHARADA SIGN UPADHMANIYA
+1193F         ; Prepend # Lo       DIVES AKURU PREFIXED NASAL SIGN
+11941         ; Prepend # Lo       DIVES AKURU INITIAL RA
 11A3A         ; Prepend # Lo       ZANABAZAR SQUARE CLUSTER-INITIAL LETTER RA
 11A84..11A89  ; Prepend # Lo   [6] SOYOMBO SIGN JIHVAMULIYA..SOYOMBO CLUSTER-INITIAL LETTER SA
 11D46         ; Prepend # Lo       MASARAM GONDI REPHA
 
-# Total code points: 22
+# Total code points: 24
 
 # ================================================
 
@@ -139,7 +141,7 @@ E01F0..E0FFF  ; Control # Cn [3600] ..
 0B3F          ; Extend # Mn       ORIYA VOWEL SIGN I
 0B41..0B44    ; Extend # Mn   [4] ORIYA VOWEL SIGN U..ORIYA VOWEL SIGN VOCALIC RR
 0B4D          ; Extend # Mn       ORIYA SIGN VIRAMA
-0B56          ; Extend # Mn       ORIYA AI LENGTH MARK
+0B55..0B56    ; Extend # Mn   [2] ORIYA SIGN OVERLINE..ORIYA AI LENGTH MARK
 0B57          ; Extend # Mc       ORIYA AU LENGTH MARK
 0B62..0B63    ; Extend # Mn   [2] ORIYA VOWEL SIGN VOCALIC L..ORIYA VOWEL SIGN VOCALIC LL
 0B82          ; Extend # Mn       TAMIL SIGN ANUSVARA
@@ -169,6 +171,7 @@ E01F0..E0FFF  ; Control # Cn [3600] ..
 0D4D          ; Extend # Mn       MALAYALAM SIGN VIRAMA
 0D57          ; Extend # Mc       MALAYALAM AU LENGTH MARK
 0D62..0D63    ; Extend # Mn   [2] MALAYALAM VOWEL SIGN VOCALIC L..MALAYALAM VOWEL SIGN VOCALIC LL
+0D81          ; Extend # Mn       SINHALA SIGN CANDRABINDU
 0DCA          ; Extend # Mn       SINHALA SIGN AL-LAKUNA
 0DCF          ; Extend # Mc       SINHALA VOWEL SIGN AELA-PILLA
 0DD2..0DD4    ; Extend # Mn   [3] SINHALA VOWEL SIGN KETTI IS-PILLA..SINHALA VOWEL SIGN KETTI PAA-PILLA
@@ -229,6 +232,7 @@ E01F0..E0FFF  ; Control # Cn [3600] ..
 1A7F          ; Extend # Mn       TAI THAM COMBINING CRYPTOGRAMMIC DOT
 1AB0..1ABD    ; Extend # Mn  [14] COMBINING DOUBLED CIRCUMFLEX ACCENT..COMBINING PARENTHESES BELOW
 1ABE          ; Extend # Me       COMBINING PARENTHESES OVERLAY
+1ABF..1AC0    ; Extend # Mn   [2] COMBINING LATIN SMALL LETTER W BELOW..COMBINING LATIN SMALL LETTER TURNED W BELOW
 1B00..1B03    ; Extend # Mn   [4] BALINESE SIGN ULU RICEM..BALINESE SIGN SURANG
 1B34          ; Extend # Mn       BALINESE SIGN REREKAN
 1B35          ; Extend # Mc       BALINESE VOWEL SIGN TEDUNG
@@ -275,6 +279,7 @@ A802          ; Extend # Mn       SYLOTI NAGRI SIGN DVISVARA
 A806          ; Extend # Mn       SYLOTI NAGRI SIGN HASANTA
 A80B          ; Extend # Mn       SYLOTI NAGRI SIGN ANUSVARA
 A825..A826    ; Extend # Mn   [2] SYLOTI NAGRI VOWEL SIGN U..SYLOTI NAGRI VOWEL SIGN E
+A82C          ; Extend # Mn       SYLOTI NAGRI SIGN ALTERNATE HASANTA
 A8C4..A8C5    ; Extend # Mn   [2] SAURASHTRA SIGN VIRAMA..SAURASHTRA SIGN CANDRABINDU
 A8E0..A8F1    ; Extend # Mn  [18] COMBINING DEVANAGARI DIGIT ZERO..COMBINING DEVANAGARI SIGN AVAGRAHA
 A8FF          ; Extend # Mn       DEVANAGARI VOWEL SIGN AY
@@ -315,6 +320,7 @@ FF9E..FF9F    ; Extend # Lm   [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDT
 10A3F         ; Extend # Mn       KHAROSHTHI VIRAMA
 10AE5..10AE6  ; Extend # Mn   [2] MANICHAEAN ABBREVIATION MARK ABOVE..MANICHAEAN ABBREVIATION MARK BELOW
 10D24..10D27  ; Extend # Mn   [4] HANIFI ROHINGYA SIGN HARBAHAY..HANIFI ROHINGYA SIGN TASSI
+10EAB..10EAC  ; Extend # Mn   [2] YEZIDI COMBINING HAMZA MARK..YEZIDI COMBINING MADDA MARK
 10F46..10F50  ; Extend # Mn  [11] SOGDIAN COMBINING DOT BELOW..SOGDIAN COMBINING STROKE BELOW
 11001         ; Extend # Mn       BRAHMI SIGN ANUSVARA
 11038..11046  ; Extend # Mn  [15] BRAHMI VOWEL SIGN AA..BRAHMI VIRAMA
@@ -328,6 +334,7 @@ FF9E..FF9F    ; Extend # Lm   [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDT
 11180..11181  ; Extend # Mn   [2] SHARADA SIGN CANDRABINDU..SHARADA SIGN ANUSVARA
 111B6..111BE  ; Extend # Mn   [9] SHARADA VOWEL SIGN U..SHARADA VOWEL SIGN O
 111C9..111CC  ; Extend # Mn   [4] SHARADA SANDHI MARK..SHARADA EXTRA SHORT VOWEL MARK
+111CF         ; Extend # Mn       SHARADA SIGN INVERTED CANDRABINDU
 1122F..11231  ; Extend # Mn   [3] KHOJKI VOWEL SIGN U..KHOJKI VOWEL SIGN AI
 11234         ; Extend # Mn       KHOJKI SIGN ANUSVARA
 11236..11237  ; Extend # Mn   [2] KHOJKI SIGN NUKTA..KHOJKI SIGN SHADDA
@@ -368,6 +375,10 @@ FF9E..FF9F    ; Extend # Lm   [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDT
 11727..1172B  ; Extend # Mn   [5] AHOM VOWEL SIGN AW..AHOM SIGN KILLER
 1182F..11837  ; Extend # Mn   [9] DOGRA VOWEL SIGN U..DOGRA SIGN ANUSVARA
 11839..1183A  ; Extend # Mn   [2] DOGRA SIGN VIRAMA..DOGRA SIGN NUKTA
+11930         ; Extend # Mc       DIVES AKURU VOWEL SIGN AA
+1193B..1193C  ; Extend # Mn   [2] DIVES AKURU SIGN ANUSVARA..DIVES AKURU SIGN CANDRABINDU
+1193E         ; Extend # Mn       DIVES AKURU VIRAMA
+11943         ; Extend # Mn       DIVES AKURU SIGN NUKTA
 119D4..119D7  ; Extend # Mn   [4] NANDINAGARI VOWEL SIGN U..NANDINAGARI VOWEL SIGN VOCALIC RR
 119DA..119DB  ; Extend # Mn   [2] NANDINAGARI VOWEL SIGN E..NANDINAGARI VOWEL SIGN AI
 119E0         ; Extend # Mn       NANDINAGARI SIGN VIRAMA
@@ -399,6 +410,7 @@ FF9E..FF9F    ; Extend # Lm   [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDT
 16B30..16B36  ; Extend # Mn   [7] PAHAWH HMONG MARK CIM TUB..PAHAWH HMONG MARK CIM TAUM
 16F4F         ; Extend # Mn       MIAO SIGN CONSONANT MODIFIER BAR
 16F8F..16F92  ; Extend # Mn   [4] MIAO TONE RIGHT..MIAO TONE BELOW
+16FE4         ; Extend # Mn       KHITAN SMALL SCRIPT FILLER
 1BC9D..1BC9E  ; Extend # Mn   [2] DUPLOYAN THICK LETTER SELECTOR..DUPLOYAN DOUBLE MARK
 1D165         ; Extend # Mc       MUSICAL SYMBOL COMBINING STEM
 1D167..1D169  ; Extend # Mn   [3] MUSICAL SYMBOL COMBINING TREMOLO-1..MUSICAL SYMBOL COMBINING TREMOLO-3
@@ -426,7 +438,7 @@ FF9E..FF9F    ; Extend # Lm   [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDT
 E0020..E007F  ; Extend # Cf  [96] TAG SPACE..CANCEL TAG
 E0100..E01EF  ; Extend # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256
 
-# Total code points: 1970
+# Total code points: 1984
 
 # ================================================
 
@@ -539,6 +551,7 @@ ABEC          ; SpacingMark # Mc       MEETEI MAYEK LUM IYEK
 11182         ; SpacingMark # Mc       SHARADA SIGN VISARGA
 111B3..111B5  ; SpacingMark # Mc   [3] SHARADA VOWEL SIGN AA..SHARADA VOWEL SIGN II
 111BF..111C0  ; SpacingMark # Mc   [2] SHARADA VOWEL SIGN AU..SHARADA SIGN VIRAMA
+111CE         ; SpacingMark # Mc       SHARADA VOWEL SIGN PRISHTHAMATRA E
 1122C..1122E  ; SpacingMark # Mc   [3] KHOJKI VOWEL SIGN AA..KHOJKI VOWEL SIGN II
 11232..11233  ; SpacingMark # Mc   [2] KHOJKI VOWEL SIGN O..KHOJKI VOWEL SIGN AU
 11235         ; SpacingMark # Mc       KHOJKI SIGN VIRAMA
@@ -570,6 +583,11 @@ ABEC          ; SpacingMark # Mc       MEETEI MAYEK LUM IYEK
 11726         ; SpacingMark # Mc       AHOM VOWEL SIGN E
 1182C..1182E  ; SpacingMark # Mc   [3] DOGRA VOWEL SIGN AA..DOGRA VOWEL SIGN II
 11838         ; SpacingMark # Mc       DOGRA SIGN VISARGA
+11931..11935  ; SpacingMark # Mc   [5] DIVES AKURU VOWEL SIGN I..DIVES AKURU VOWEL SIGN E
+11937..11938  ; SpacingMark # Mc   [2] DIVES AKURU VOWEL SIGN AI..DIVES AKURU VOWEL SIGN O
+1193D         ; SpacingMark # Mc       DIVES AKURU SIGN HALANTA
+11940         ; SpacingMark # Mc       DIVES AKURU MEDIAL YA
+11942         ; SpacingMark # Mc       DIVES AKURU MEDIAL RA
 119D1..119D3  ; SpacingMark # Mc   [3] NANDINAGARI VOWEL SIGN AA..NANDINAGARI VOWEL SIGN II
 119DC..119DF  ; SpacingMark # Mc   [4] NANDINAGARI VOWEL SIGN O..NANDINAGARI SIGN VISARGA
 119E4         ; SpacingMark # Mc       NANDINAGARI VOWEL SIGN PRISHTHAMATRA E
@@ -586,10 +604,11 @@ ABEC          ; SpacingMark # Mc       MEETEI MAYEK LUM IYEK
 11D96         ; SpacingMark # Mc       GUNJALA GONDI SIGN VISARGA
 11EF5..11EF6  ; SpacingMark # Mc   [2] MAKASAR VOWEL SIGN E..MAKASAR VOWEL SIGN O
 16F51..16F87  ; SpacingMark # Mc  [55] MIAO SIGN ASPIRATION..MIAO VOWEL SIGN UI
+16FF0..16FF1  ; SpacingMark # Mc   [2] VIETNAMESE ALTERNATE READING MARK CA..VIETNAMESE ALTERNATE READING MARK NHAY
 1D166         ; SpacingMark # Mc       MUSICAL SYMBOL COMBINING SPRECHGESANG STEM
 1D16D         ; SpacingMark # Mc       MUSICAL SYMBOL COMBINING AUGMENTATION DOT
 
-# Total code points: 375
+# Total code points: 388
 
 # ================================================
 
diff --git a/make/data/unicodedata/auxiliary/GraphemeBreakTest.txt b/make/data/unicodedata/auxiliary/GraphemeBreakTest.txt
index bfcec61fa1e..e3cd8806ceb 100644
--- a/make/data/unicodedata/auxiliary/GraphemeBreakTest.txt
+++ b/make/data/unicodedata/auxiliary/GraphemeBreakTest.txt
@@ -1,5 +1,5 @@
-# GraphemeBreakTest-12.1.0.txt
-# Date: 2019-03-10, 10:53:12 GMT
+# GraphemeBreakTest-13.0.0.txt
+# Date: 2019-11-15, 19:49:10 GMT
 # Copyright (c) 2019 Unicode, Inc.
 # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
 # For terms of use, see http://www.unicode.org/terms_of_use.html
diff --git a/make/data/unicodedata/emoji-data.txt b/make/data/unicodedata/emoji-data.txt
deleted file mode 100644
index e134206e3a6..00000000000
--- a/make/data/unicodedata/emoji-data.txt
+++ /dev/null
@@ -1,769 +0,0 @@
-# emoji-data.txt
-# Date: 2019-01-15, 12:10:05 GMT
-# Copyright (c) 2019 Unicode, Inc.
-# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
-# For terms of use, see http://www.unicode.org/terms_of_use.html
-#
-# Emoji Data for UTS #51
-# Version: 12.0
-#
-# For documentation and usage, see http://www.unicode.org/reports/tr51
-#
-# Format:
-#  ;  # 
-# Note: there is no guarantee as to the structure of whitespace or comments
-#
-# Characters and sequences are listed in code point order. Users should be shown a more natural order.
-# See the CLDR collation order for Emoji.
-
-
-# ================================================
-
-# All omitted code points have Emoji=No
-# @missing: 0000..10FFFF  ; Emoji ; No
-
-0023          ; Emoji                #  1.1  [1] (#️)       number sign
-002A          ; Emoji                #  1.1  [1] (*️)       asterisk
-0030..0039    ; Emoji                #  1.1 [10] (0️..9️)    digit zero..digit nine
-00A9          ; Emoji                #  1.1  [1] (©️)       copyright
-00AE          ; Emoji                #  1.1  [1] (®️)       registered
-203C          ; Emoji                #  1.1  [1] (‼️)       double exclamation mark
-2049          ; Emoji                #  3.0  [1] (⁉️)       exclamation question mark
-2122          ; Emoji                #  1.1  [1] (™️)       trade mark
-2139          ; Emoji                #  3.0  [1] (ℹ️)       information
-2194..2199    ; Emoji                #  1.1  [6] (↔️..↙️)    left-right arrow..down-left arrow
-21A9..21AA    ; Emoji                #  1.1  [2] (↩️..↪️)    right arrow curving left..left arrow curving right
-231A..231B    ; Emoji                #  1.1  [2] (⌚..⌛)    watch..hourglass done
-2328          ; Emoji                #  1.1  [1] (⌨️)       keyboard
-23CF          ; Emoji                #  4.0  [1] (⏏️)       eject button
-23E9..23F3    ; Emoji                #  6.0 [11] (⏩..⏳)    fast-forward button..hourglass not done
-23F8..23FA    ; Emoji                #  7.0  [3] (⏸️..⏺️)    pause button..record button
-24C2          ; Emoji                #  1.1  [1] (Ⓜ️)       circled M
-25AA..25AB    ; Emoji                #  1.1  [2] (▪️..▫️)    black small square..white small square
-25B6          ; Emoji                #  1.1  [1] (▶️)       play button
-25C0          ; Emoji                #  1.1  [1] (◀️)       reverse button
-25FB..25FE    ; Emoji                #  3.2  [4] (◻️..◾)    white medium square..black medium-small square
-2600..2604    ; Emoji                #  1.1  [5] (☀️..☄️)    sun..comet
-260E          ; Emoji                #  1.1  [1] (☎️)       telephone
-2611          ; Emoji                #  1.1  [1] (☑️)       check box with check
-2614..2615    ; Emoji                #  4.0  [2] (☔..☕)    umbrella with rain drops..hot beverage
-2618          ; Emoji                #  4.1  [1] (☘️)       shamrock
-261D          ; Emoji                #  1.1  [1] (☝️)       index pointing up
-2620          ; Emoji                #  1.1  [1] (☠️)       skull and crossbones
-2622..2623    ; Emoji                #  1.1  [2] (☢️..☣️)    radioactive..biohazard
-2626          ; Emoji                #  1.1  [1] (☦️)       orthodox cross
-262A          ; Emoji                #  1.1  [1] (☪️)       star and crescent
-262E..262F    ; Emoji                #  1.1  [2] (☮️..☯️)    peace symbol..yin yang
-2638..263A    ; Emoji                #  1.1  [3] (☸️..☺️)    wheel of dharma..smiling face
-2640          ; Emoji                #  1.1  [1] (♀️)       female sign
-2642          ; Emoji                #  1.1  [1] (♂️)       male sign
-2648..2653    ; Emoji                #  1.1 [12] (♈..♓)    Aries..Pisces
-265F..2660    ; Emoji                #  1.1  [2] (♟️..♠️)    chess pawn..spade suit
-2663          ; Emoji                #  1.1  [1] (♣️)       club suit
-2665..2666    ; Emoji                #  1.1  [2] (♥️..♦️)    heart suit..diamond suit
-2668          ; Emoji                #  1.1  [1] (♨️)       hot springs
-267B          ; Emoji                #  3.2  [1] (♻️)       recycling symbol
-267E..267F    ; Emoji                #  4.1  [2] (♾️..♿)    infinity..wheelchair symbol
-2692..2697    ; Emoji                #  4.1  [6] (⚒️..⚗️)    hammer and pick..alembic
-2699          ; Emoji                #  4.1  [1] (⚙️)       gear
-269B..269C    ; Emoji                #  4.1  [2] (⚛️..⚜️)    atom symbol..fleur-de-lis
-26A0..26A1    ; Emoji                #  4.0  [2] (⚠️..⚡)    warning..high voltage
-26AA..26AB    ; Emoji                #  4.1  [2] (⚪..⚫)    white circle..black circle
-26B0..26B1    ; Emoji                #  4.1  [2] (⚰️..⚱️)    coffin..funeral urn
-26BD..26BE    ; Emoji                #  5.2  [2] (⚽..⚾)    soccer ball..baseball
-26C4..26C5    ; Emoji                #  5.2  [2] (⛄..⛅)    snowman without snow..sun behind cloud
-26C8          ; Emoji                #  5.2  [1] (⛈️)       cloud with lightning and rain
-26CE          ; Emoji                #  6.0  [1] (⛎)       Ophiuchus
-26CF          ; Emoji                #  5.2  [1] (⛏️)       pick
-26D1          ; Emoji                #  5.2  [1] (⛑️)       rescue worker’s helmet
-26D3..26D4    ; Emoji                #  5.2  [2] (⛓️..⛔)    chains..no entry
-26E9..26EA    ; Emoji                #  5.2  [2] (⛩️..⛪)    shinto shrine..church
-26F0..26F5    ; Emoji                #  5.2  [6] (⛰️..⛵)    mountain..sailboat
-26F7..26FA    ; Emoji                #  5.2  [4] (⛷️..⛺)    skier..tent
-26FD          ; Emoji                #  5.2  [1] (⛽)       fuel pump
-2702          ; Emoji                #  1.1  [1] (✂️)       scissors
-2705          ; Emoji                #  6.0  [1] (✅)       check mark button
-2708..2709    ; Emoji                #  1.1  [2] (✈️..✉️)    airplane..envelope
-270A..270B    ; Emoji                #  6.0  [2] (✊..✋)    raised fist..raised hand
-270C..270D    ; Emoji                #  1.1  [2] (✌️..✍️)    victory hand..writing hand
-270F          ; Emoji                #  1.1  [1] (✏️)       pencil
-2712          ; Emoji                #  1.1  [1] (✒️)       black nib
-2714          ; Emoji                #  1.1  [1] (✔️)       check mark
-2716          ; Emoji                #  1.1  [1] (✖️)       multiplication sign
-271D          ; Emoji                #  1.1  [1] (✝️)       latin cross
-2721          ; Emoji                #  1.1  [1] (✡️)       star of David
-2728          ; Emoji                #  6.0  [1] (✨)       sparkles
-2733..2734    ; Emoji                #  1.1  [2] (✳️..✴️)    eight-spoked asterisk..eight-pointed star
-2744          ; Emoji                #  1.1  [1] (❄️)       snowflake
-2747          ; Emoji                #  1.1  [1] (❇️)       sparkle
-274C          ; Emoji                #  6.0  [1] (❌)       cross mark
-274E          ; Emoji                #  6.0  [1] (❎)       cross mark button
-2753..2755    ; Emoji                #  6.0  [3] (❓..❕)    question mark..white exclamation mark
-2757          ; Emoji                #  5.2  [1] (❗)       exclamation mark
-2763..2764    ; Emoji                #  1.1  [2] (❣️..❤️)    heart exclamation..red heart
-2795..2797    ; Emoji                #  6.0  [3] (➕..➗)    plus sign..division sign
-27A1          ; Emoji                #  1.1  [1] (➡️)       right arrow
-27B0          ; Emoji                #  6.0  [1] (➰)       curly loop
-27BF          ; Emoji                #  6.0  [1] (➿)       double curly loop
-2934..2935    ; Emoji                #  3.2  [2] (⤴️..⤵️)    right arrow curving up..right arrow curving down
-2B05..2B07    ; Emoji                #  4.0  [3] (⬅️..⬇️)    left arrow..down arrow
-2B1B..2B1C    ; Emoji                #  5.1  [2] (⬛..⬜)    black large square..white large square
-2B50          ; Emoji                #  5.1  [1] (⭐)       star
-2B55          ; Emoji                #  5.2  [1] (⭕)       hollow red circle
-3030          ; Emoji                #  1.1  [1] (〰️)       wavy dash
-303D          ; Emoji                #  3.2  [1] (〽️)       part alternation mark
-3297          ; Emoji                #  1.1  [1] (㊗️)       Japanese “congratulations” button
-3299          ; Emoji                #  1.1  [1] (㊙️)       Japanese “secret” button
-1F004         ; Emoji                #  5.1  [1] (🀄)       mahjong red dragon
-1F0CF         ; Emoji                #  6.0  [1] (🃏)       joker
-1F170..1F171  ; Emoji                #  6.0  [2] (🅰️..🅱️)    A button (blood type)..B button (blood type)
-1F17E         ; Emoji                #  6.0  [1] (🅾️)       O button (blood type)
-1F17F         ; Emoji                #  5.2  [1] (🅿️)       P button
-1F18E         ; Emoji                #  6.0  [1] (🆎)       AB button (blood type)
-1F191..1F19A  ; Emoji                #  6.0 [10] (🆑..🆚)    CL button..VS button
-1F1E6..1F1FF  ; Emoji                #  6.0 [26] (🇦..🇿)    regional indicator symbol letter a..regional indicator symbol letter z
-1F201..1F202  ; Emoji                #  6.0  [2] (🈁..🈂️)    Japanese “here” button..Japanese “service charge” button
-1F21A         ; Emoji                #  5.2  [1] (🈚)       Japanese “free of charge” button
-1F22F         ; Emoji                #  5.2  [1] (🈯)       Japanese “reserved” button
-1F232..1F23A  ; Emoji                #  6.0  [9] (🈲..🈺)    Japanese “prohibited” button..Japanese “open for business” button
-1F250..1F251  ; Emoji                #  6.0  [2] (🉐..🉑)    Japanese “bargain” button..Japanese “acceptable” button
-1F300..1F320  ; Emoji                #  6.0 [33] (🌀..🌠)    cyclone..shooting star
-1F321         ; Emoji                #  7.0  [1] (🌡️)       thermometer
-1F324..1F32C  ; Emoji                #  7.0  [9] (🌤️..🌬️)    sun behind small cloud..wind face
-1F32D..1F32F  ; Emoji                #  8.0  [3] (🌭..🌯)    hot dog..burrito
-1F330..1F335  ; Emoji                #  6.0  [6] (🌰..🌵)    chestnut..cactus
-1F336         ; Emoji                #  7.0  [1] (🌶️)       hot pepper
-1F337..1F37C  ; Emoji                #  6.0 [70] (🌷..🍼)    tulip..baby bottle
-1F37D         ; Emoji                #  7.0  [1] (🍽️)       fork and knife with plate
-1F37E..1F37F  ; Emoji                #  8.0  [2] (🍾..🍿)    bottle with popping cork..popcorn
-1F380..1F393  ; Emoji                #  6.0 [20] (🎀..🎓)    ribbon..graduation cap
-1F396..1F397  ; Emoji                #  7.0  [2] (🎖️..🎗️)    military medal..reminder ribbon
-1F399..1F39B  ; Emoji                #  7.0  [3] (🎙️..🎛️)    studio microphone..control knobs
-1F39E..1F39F  ; Emoji                #  7.0  [2] (🎞️..🎟️)    film frames..admission tickets
-1F3A0..1F3C4  ; Emoji                #  6.0 [37] (🎠..🏄)    carousel horse..person surfing
-1F3C5         ; Emoji                #  7.0  [1] (🏅)       sports medal
-1F3C6..1F3CA  ; Emoji                #  6.0  [5] (🏆..🏊)    trophy..person swimming
-1F3CB..1F3CE  ; Emoji                #  7.0  [4] (🏋️..🏎️)    person lifting weights..racing car
-1F3CF..1F3D3  ; Emoji                #  8.0  [5] (🏏..🏓)    cricket game..ping pong
-1F3D4..1F3DF  ; Emoji                #  7.0 [12] (🏔️..🏟️)    snow-capped mountain..stadium
-1F3E0..1F3F0  ; Emoji                #  6.0 [17] (🏠..🏰)    house..castle
-1F3F3..1F3F5  ; Emoji                #  7.0  [3] (🏳️..🏵️)    white flag..rosette
-1F3F7         ; Emoji                #  7.0  [1] (🏷️)       label
-1F3F8..1F3FF  ; Emoji                #  8.0  [8] (🏸..🏿)    badminton..dark skin tone
-1F400..1F43E  ; Emoji                #  6.0 [63] (🐀..🐾)    rat..paw prints
-1F43F         ; Emoji                #  7.0  [1] (🐿️)       chipmunk
-1F440         ; Emoji                #  6.0  [1] (👀)       eyes
-1F441         ; Emoji                #  7.0  [1] (👁️)       eye
-1F442..1F4F7  ; Emoji                #  6.0[182] (👂..📷)    ear..camera
-1F4F8         ; Emoji                #  7.0  [1] (📸)       camera with flash
-1F4F9..1F4FC  ; Emoji                #  6.0  [4] (📹..📼)    video camera..videocassette
-1F4FD         ; Emoji                #  7.0  [1] (📽️)       film projector
-1F4FF         ; Emoji                #  8.0  [1] (📿)       prayer beads
-1F500..1F53D  ; Emoji                #  6.0 [62] (🔀..🔽)    shuffle tracks button..downwards button
-1F549..1F54A  ; Emoji                #  7.0  [2] (🕉️..🕊️)    om..dove
-1F54B..1F54E  ; Emoji                #  8.0  [4] (🕋..🕎)    kaaba..menorah
-1F550..1F567  ; Emoji                #  6.0 [24] (🕐..🕧)    one o’clock..twelve-thirty
-1F56F..1F570  ; Emoji                #  7.0  [2] (🕯️..🕰️)    candle..mantelpiece clock
-1F573..1F579  ; Emoji                #  7.0  [7] (🕳️..🕹️)    hole..joystick
-1F57A         ; Emoji                #  9.0  [1] (🕺)       man dancing
-1F587         ; Emoji                #  7.0  [1] (🖇️)       linked paperclips
-1F58A..1F58D  ; Emoji                #  7.0  [4] (🖊️..🖍️)    pen..crayon
-1F590         ; Emoji                #  7.0  [1] (🖐️)       hand with fingers splayed
-1F595..1F596  ; Emoji                #  7.0  [2] (🖕..🖖)    middle finger..vulcan salute
-1F5A4         ; Emoji                #  9.0  [1] (🖤)       black heart
-1F5A5         ; Emoji                #  7.0  [1] (🖥️)       desktop computer
-1F5A8         ; Emoji                #  7.0  [1] (🖨️)       printer
-1F5B1..1F5B2  ; Emoji                #  7.0  [2] (🖱️..🖲️)    computer mouse..trackball
-1F5BC         ; Emoji                #  7.0  [1] (🖼️)       framed picture
-1F5C2..1F5C4  ; Emoji                #  7.0  [3] (🗂️..🗄️)    card index dividers..file cabinet
-1F5D1..1F5D3  ; Emoji                #  7.0  [3] (🗑️..🗓️)    wastebasket..spiral calendar
-1F5DC..1F5DE  ; Emoji                #  7.0  [3] (🗜️..🗞️)    clamp..rolled-up newspaper
-1F5E1         ; Emoji                #  7.0  [1] (🗡️)       dagger
-1F5E3         ; Emoji                #  7.0  [1] (🗣️)       speaking head
-1F5E8         ; Emoji                #  7.0  [1] (🗨️)       left speech bubble
-1F5EF         ; Emoji                #  7.0  [1] (🗯️)       right anger bubble
-1F5F3         ; Emoji                #  7.0  [1] (🗳️)       ballot box with ballot
-1F5FA         ; Emoji                #  7.0  [1] (🗺️)       world map
-1F5FB..1F5FF  ; Emoji                #  6.0  [5] (🗻..🗿)    mount fuji..moai
-1F600         ; Emoji                #  6.1  [1] (😀)       grinning face
-1F601..1F610  ; Emoji                #  6.0 [16] (😁..😐)    beaming face with smiling eyes..neutral face
-1F611         ; Emoji                #  6.1  [1] (😑)       expressionless face
-1F612..1F614  ; Emoji                #  6.0  [3] (😒..😔)    unamused face..pensive face
-1F615         ; Emoji                #  6.1  [1] (😕)       confused face
-1F616         ; Emoji                #  6.0  [1] (😖)       confounded face
-1F617         ; Emoji                #  6.1  [1] (😗)       kissing face
-1F618         ; Emoji                #  6.0  [1] (😘)       face blowing a kiss
-1F619         ; Emoji                #  6.1  [1] (😙)       kissing face with smiling eyes
-1F61A         ; Emoji                #  6.0  [1] (😚)       kissing face with closed eyes
-1F61B         ; Emoji                #  6.1  [1] (😛)       face with tongue
-1F61C..1F61E  ; Emoji                #  6.0  [3] (😜..😞)    winking face with tongue..disappointed face
-1F61F         ; Emoji                #  6.1  [1] (😟)       worried face
-1F620..1F625  ; Emoji                #  6.0  [6] (😠..😥)    angry face..sad but relieved face
-1F626..1F627  ; Emoji                #  6.1  [2] (😦..😧)    frowning face with open mouth..anguished face
-1F628..1F62B  ; Emoji                #  6.0  [4] (😨..😫)    fearful face..tired face
-1F62C         ; Emoji                #  6.1  [1] (😬)       grimacing face
-1F62D         ; Emoji                #  6.0  [1] (😭)       loudly crying face
-1F62E..1F62F  ; Emoji                #  6.1  [2] (😮..😯)    face with open mouth..hushed face
-1F630..1F633  ; Emoji                #  6.0  [4] (😰..😳)    anxious face with sweat..flushed face
-1F634         ; Emoji                #  6.1  [1] (😴)       sleeping face
-1F635..1F640  ; Emoji                #  6.0 [12] (😵..🙀)    dizzy face..weary cat
-1F641..1F642  ; Emoji                #  7.0  [2] (🙁..🙂)    slightly frowning face..slightly smiling face
-1F643..1F644  ; Emoji                #  8.0  [2] (🙃..🙄)    upside-down face..face with rolling eyes
-1F645..1F64F  ; Emoji                #  6.0 [11] (🙅..🙏)    person gesturing NO..folded hands
-1F680..1F6C5  ; Emoji                #  6.0 [70] (🚀..🛅)    rocket..left luggage
-1F6CB..1F6CF  ; Emoji                #  7.0  [5] (🛋️..🛏️)    couch and lamp..bed
-1F6D0         ; Emoji                #  8.0  [1] (🛐)       place of worship
-1F6D1..1F6D2  ; Emoji                #  9.0  [2] (🛑..🛒)    stop sign..shopping cart
-1F6D5         ; Emoji                # 12.0  [1] (🛕)       hindu temple
-1F6E0..1F6E5  ; Emoji                #  7.0  [6] (🛠️..🛥️)    hammer and wrench..motor boat
-1F6E9         ; Emoji                #  7.0  [1] (🛩️)       small airplane
-1F6EB..1F6EC  ; Emoji                #  7.0  [2] (🛫..🛬)    airplane departure..airplane arrival
-1F6F0         ; Emoji                #  7.0  [1] (🛰️)       satellite
-1F6F3         ; Emoji                #  7.0  [1] (🛳️)       passenger ship
-1F6F4..1F6F6  ; Emoji                #  9.0  [3] (🛴..🛶)    kick scooter..canoe
-1F6F7..1F6F8  ; Emoji                # 10.0  [2] (🛷..🛸)    sled..flying saucer
-1F6F9         ; Emoji                # 11.0  [1] (🛹)       skateboard
-1F6FA         ; Emoji                # 12.0  [1] (🛺)       auto rickshaw
-1F7E0..1F7EB  ; Emoji                # 12.0 [12] (🟠..🟫)    orange circle..brown square
-1F90D..1F90F  ; Emoji                # 12.0  [3] (🤍..🤏)    white heart..pinching hand
-1F910..1F918  ; Emoji                #  8.0  [9] (🤐..🤘)    zipper-mouth face..sign of the horns
-1F919..1F91E  ; Emoji                #  9.0  [6] (🤙..🤞)    call me hand..crossed fingers
-1F91F         ; Emoji                # 10.0  [1] (🤟)       love-you gesture
-1F920..1F927  ; Emoji                #  9.0  [8] (🤠..🤧)    cowboy hat face..sneezing face
-1F928..1F92F  ; Emoji                # 10.0  [8] (🤨..🤯)    face with raised eyebrow..exploding head
-1F930         ; Emoji                #  9.0  [1] (🤰)       pregnant woman
-1F931..1F932  ; Emoji                # 10.0  [2] (🤱..🤲)    breast-feeding..palms up together
-1F933..1F93A  ; Emoji                #  9.0  [8] (🤳..🤺)    selfie..person fencing
-1F93C..1F93E  ; Emoji                #  9.0  [3] (🤼..🤾)    people wrestling..person playing handball
-1F93F         ; Emoji                # 12.0  [1] (🤿)       diving mask
-1F940..1F945  ; Emoji                #  9.0  [6] (🥀..🥅)    wilted flower..goal net
-1F947..1F94B  ; Emoji                #  9.0  [5] (🥇..🥋)    1st place medal..martial arts uniform
-1F94C         ; Emoji                # 10.0  [1] (🥌)       curling stone
-1F94D..1F94F  ; Emoji                # 11.0  [3] (🥍..🥏)    lacrosse..flying disc
-1F950..1F95E  ; Emoji                #  9.0 [15] (🥐..🥞)    croissant..pancakes
-1F95F..1F96B  ; Emoji                # 10.0 [13] (🥟..🥫)    dumpling..canned food
-1F96C..1F970  ; Emoji                # 11.0  [5] (🥬..🥰)    leafy green..smiling face with hearts
-1F971         ; Emoji                # 12.0  [1] (🥱)       yawning face
-1F973..1F976  ; Emoji                # 11.0  [4] (🥳..🥶)    partying face..cold face
-1F97A         ; Emoji                # 11.0  [1] (🥺)       pleading face
-1F97B         ; Emoji                # 12.0  [1] (🥻)       sari
-1F97C..1F97F  ; Emoji                # 11.0  [4] (🥼..🥿)    lab coat..flat shoe
-1F980..1F984  ; Emoji                #  8.0  [5] (🦀..🦄)    crab..unicorn
-1F985..1F991  ; Emoji                #  9.0 [13] (🦅..🦑)    eagle..squid
-1F992..1F997  ; Emoji                # 10.0  [6] (🦒..🦗)    giraffe..cricket
-1F998..1F9A2  ; Emoji                # 11.0 [11] (🦘..🦢)    kangaroo..swan
-1F9A5..1F9AA  ; Emoji                # 12.0  [6] (🦥..🦪)    sloth..oyster
-1F9AE..1F9AF  ; Emoji                # 12.0  [2] (🦮..🦯)    guide dog..probing cane
-1F9B0..1F9B9  ; Emoji                # 11.0 [10] (🦰..🦹)    red hair..supervillain
-1F9BA..1F9BF  ; Emoji                # 12.0  [6] (🦺..🦿)    safety vest..mechanical leg
-1F9C0         ; Emoji                #  8.0  [1] (🧀)       cheese wedge
-1F9C1..1F9C2  ; Emoji                # 11.0  [2] (🧁..🧂)    cupcake..salt
-1F9C3..1F9CA  ; Emoji                # 12.0  [8] (🧃..🧊)    beverage box..ice cube
-1F9CD..1F9CF  ; Emoji                # 12.0  [3] (🧍..🧏)    person standing..deaf person
-1F9D0..1F9E6  ; Emoji                # 10.0 [23] (🧐..🧦)    face with monocle..socks
-1F9E7..1F9FF  ; Emoji                # 11.0 [25] (🧧..🧿)    red envelope..nazar amulet
-1FA70..1FA73  ; Emoji                # 12.0  [4] (🩰..🩳)    ballet shoes..shorts
-1FA78..1FA7A  ; Emoji                # 12.0  [3] (🩸..🩺)    drop of blood..stethoscope
-1FA80..1FA82  ; Emoji                # 12.0  [3] (🪀..🪂)    yo-yo..parachute
-1FA90..1FA95  ; Emoji                # 12.0  [6] (🪐..🪕)    ringed planet..banjo
-
-# Total elements: 1311
-
-# ================================================
-
-# All omitted code points have Emoji_Presentation=No
-# @missing: 0000..10FFFF  ; Emoji_Presentation ; No
-
-231A..231B    ; Emoji_Presentation   #  1.1  [2] (⌚..⌛)    watch..hourglass done
-23E9..23EC    ; Emoji_Presentation   #  6.0  [4] (⏩..⏬)    fast-forward button..fast down button
-23F0          ; Emoji_Presentation   #  6.0  [1] (⏰)       alarm clock
-23F3          ; Emoji_Presentation   #  6.0  [1] (⏳)       hourglass not done
-25FD..25FE    ; Emoji_Presentation   #  3.2  [2] (◽..◾)    white medium-small square..black medium-small square
-2614..2615    ; Emoji_Presentation   #  4.0  [2] (☔..☕)    umbrella with rain drops..hot beverage
-2648..2653    ; Emoji_Presentation   #  1.1 [12] (♈..♓)    Aries..Pisces
-267F          ; Emoji_Presentation   #  4.1  [1] (♿)       wheelchair symbol
-2693          ; Emoji_Presentation   #  4.1  [1] (⚓)       anchor
-26A1          ; Emoji_Presentation   #  4.0  [1] (⚡)       high voltage
-26AA..26AB    ; Emoji_Presentation   #  4.1  [2] (⚪..⚫)    white circle..black circle
-26BD..26BE    ; Emoji_Presentation   #  5.2  [2] (⚽..⚾)    soccer ball..baseball
-26C4..26C5    ; Emoji_Presentation   #  5.2  [2] (⛄..⛅)    snowman without snow..sun behind cloud
-26CE          ; Emoji_Presentation   #  6.0  [1] (⛎)       Ophiuchus
-26D4          ; Emoji_Presentation   #  5.2  [1] (⛔)       no entry
-26EA          ; Emoji_Presentation   #  5.2  [1] (⛪)       church
-26F2..26F3    ; Emoji_Presentation   #  5.2  [2] (⛲..⛳)    fountain..flag in hole
-26F5          ; Emoji_Presentation   #  5.2  [1] (⛵)       sailboat
-26FA          ; Emoji_Presentation   #  5.2  [1] (⛺)       tent
-26FD          ; Emoji_Presentation   #  5.2  [1] (⛽)       fuel pump
-2705          ; Emoji_Presentation   #  6.0  [1] (✅)       check mark button
-270A..270B    ; Emoji_Presentation   #  6.0  [2] (✊..✋)    raised fist..raised hand
-2728          ; Emoji_Presentation   #  6.0  [1] (✨)       sparkles
-274C          ; Emoji_Presentation   #  6.0  [1] (❌)       cross mark
-274E          ; Emoji_Presentation   #  6.0  [1] (❎)       cross mark button
-2753..2755    ; Emoji_Presentation   #  6.0  [3] (❓..❕)    question mark..white exclamation mark
-2757          ; Emoji_Presentation   #  5.2  [1] (❗)       exclamation mark
-2795..2797    ; Emoji_Presentation   #  6.0  [3] (➕..➗)    plus sign..division sign
-27B0          ; Emoji_Presentation   #  6.0  [1] (➰)       curly loop
-27BF          ; Emoji_Presentation   #  6.0  [1] (➿)       double curly loop
-2B1B..2B1C    ; Emoji_Presentation   #  5.1  [2] (⬛..⬜)    black large square..white large square
-2B50          ; Emoji_Presentation   #  5.1  [1] (⭐)       star
-2B55          ; Emoji_Presentation   #  5.2  [1] (⭕)       hollow red circle
-1F004         ; Emoji_Presentation   #  5.1  [1] (🀄)       mahjong red dragon
-1F0CF         ; Emoji_Presentation   #  6.0  [1] (🃏)       joker
-1F18E         ; Emoji_Presentation   #  6.0  [1] (🆎)       AB button (blood type)
-1F191..1F19A  ; Emoji_Presentation   #  6.0 [10] (🆑..🆚)    CL button..VS button
-1F1E6..1F1FF  ; Emoji_Presentation   #  6.0 [26] (🇦..🇿)    regional indicator symbol letter a..regional indicator symbol letter z
-1F201         ; Emoji_Presentation   #  6.0  [1] (🈁)       Japanese “here” button
-1F21A         ; Emoji_Presentation   #  5.2  [1] (🈚)       Japanese “free of charge” button
-1F22F         ; Emoji_Presentation   #  5.2  [1] (🈯)       Japanese “reserved” button
-1F232..1F236  ; Emoji_Presentation   #  6.0  [5] (🈲..🈶)    Japanese “prohibited” button..Japanese “not free of charge” button
-1F238..1F23A  ; Emoji_Presentation   #  6.0  [3] (🈸..🈺)    Japanese “application” button..Japanese “open for business” button
-1F250..1F251  ; Emoji_Presentation   #  6.0  [2] (🉐..🉑)    Japanese “bargain” button..Japanese “acceptable” button
-1F300..1F320  ; Emoji_Presentation   #  6.0 [33] (🌀..🌠)    cyclone..shooting star
-1F32D..1F32F  ; Emoji_Presentation   #  8.0  [3] (🌭..🌯)    hot dog..burrito
-1F330..1F335  ; Emoji_Presentation   #  6.0  [6] (🌰..🌵)    chestnut..cactus
-1F337..1F37C  ; Emoji_Presentation   #  6.0 [70] (🌷..🍼)    tulip..baby bottle
-1F37E..1F37F  ; Emoji_Presentation   #  8.0  [2] (🍾..🍿)    bottle with popping cork..popcorn
-1F380..1F393  ; Emoji_Presentation   #  6.0 [20] (🎀..🎓)    ribbon..graduation cap
-1F3A0..1F3C4  ; Emoji_Presentation   #  6.0 [37] (🎠..🏄)    carousel horse..person surfing
-1F3C5         ; Emoji_Presentation   #  7.0  [1] (🏅)       sports medal
-1F3C6..1F3CA  ; Emoji_Presentation   #  6.0  [5] (🏆..🏊)    trophy..person swimming
-1F3CF..1F3D3  ; Emoji_Presentation   #  8.0  [5] (🏏..🏓)    cricket game..ping pong
-1F3E0..1F3F0  ; Emoji_Presentation   #  6.0 [17] (🏠..🏰)    house..castle
-1F3F4         ; Emoji_Presentation   #  7.0  [1] (🏴)       black flag
-1F3F8..1F3FF  ; Emoji_Presentation   #  8.0  [8] (🏸..🏿)    badminton..dark skin tone
-1F400..1F43E  ; Emoji_Presentation   #  6.0 [63] (🐀..🐾)    rat..paw prints
-1F440         ; Emoji_Presentation   #  6.0  [1] (👀)       eyes
-1F442..1F4F7  ; Emoji_Presentation   #  6.0[182] (👂..📷)    ear..camera
-1F4F8         ; Emoji_Presentation   #  7.0  [1] (📸)       camera with flash
-1F4F9..1F4FC  ; Emoji_Presentation   #  6.0  [4] (📹..📼)    video camera..videocassette
-1F4FF         ; Emoji_Presentation   #  8.0  [1] (📿)       prayer beads
-1F500..1F53D  ; Emoji_Presentation   #  6.0 [62] (🔀..🔽)    shuffle tracks button..downwards button
-1F54B..1F54E  ; Emoji_Presentation   #  8.0  [4] (🕋..🕎)    kaaba..menorah
-1F550..1F567  ; Emoji_Presentation   #  6.0 [24] (🕐..🕧)    one o’clock..twelve-thirty
-1F57A         ; Emoji_Presentation   #  9.0  [1] (🕺)       man dancing
-1F595..1F596  ; Emoji_Presentation   #  7.0  [2] (🖕..🖖)    middle finger..vulcan salute
-1F5A4         ; Emoji_Presentation   #  9.0  [1] (🖤)       black heart
-1F5FB..1F5FF  ; Emoji_Presentation   #  6.0  [5] (🗻..🗿)    mount fuji..moai
-1F600         ; Emoji_Presentation   #  6.1  [1] (😀)       grinning face
-1F601..1F610  ; Emoji_Presentation   #  6.0 [16] (😁..😐)    beaming face with smiling eyes..neutral face
-1F611         ; Emoji_Presentation   #  6.1  [1] (😑)       expressionless face
-1F612..1F614  ; Emoji_Presentation   #  6.0  [3] (😒..😔)    unamused face..pensive face
-1F615         ; Emoji_Presentation   #  6.1  [1] (😕)       confused face
-1F616         ; Emoji_Presentation   #  6.0  [1] (😖)       confounded face
-1F617         ; Emoji_Presentation   #  6.1  [1] (😗)       kissing face
-1F618         ; Emoji_Presentation   #  6.0  [1] (😘)       face blowing a kiss
-1F619         ; Emoji_Presentation   #  6.1  [1] (😙)       kissing face with smiling eyes
-1F61A         ; Emoji_Presentation   #  6.0  [1] (😚)       kissing face with closed eyes
-1F61B         ; Emoji_Presentation   #  6.1  [1] (😛)       face with tongue
-1F61C..1F61E  ; Emoji_Presentation   #  6.0  [3] (😜..😞)    winking face with tongue..disappointed face
-1F61F         ; Emoji_Presentation   #  6.1  [1] (😟)       worried face
-1F620..1F625  ; Emoji_Presentation   #  6.0  [6] (😠..😥)    angry face..sad but relieved face
-1F626..1F627  ; Emoji_Presentation   #  6.1  [2] (😦..😧)    frowning face with open mouth..anguished face
-1F628..1F62B  ; Emoji_Presentation   #  6.0  [4] (😨..😫)    fearful face..tired face
-1F62C         ; Emoji_Presentation   #  6.1  [1] (😬)       grimacing face
-1F62D         ; Emoji_Presentation   #  6.0  [1] (😭)       loudly crying face
-1F62E..1F62F  ; Emoji_Presentation   #  6.1  [2] (😮..😯)    face with open mouth..hushed face
-1F630..1F633  ; Emoji_Presentation   #  6.0  [4] (😰..😳)    anxious face with sweat..flushed face
-1F634         ; Emoji_Presentation   #  6.1  [1] (😴)       sleeping face
-1F635..1F640  ; Emoji_Presentation   #  6.0 [12] (😵..🙀)    dizzy face..weary cat
-1F641..1F642  ; Emoji_Presentation   #  7.0  [2] (🙁..🙂)    slightly frowning face..slightly smiling face
-1F643..1F644  ; Emoji_Presentation   #  8.0  [2] (🙃..🙄)    upside-down face..face with rolling eyes
-1F645..1F64F  ; Emoji_Presentation   #  6.0 [11] (🙅..🙏)    person gesturing NO..folded hands
-1F680..1F6C5  ; Emoji_Presentation   #  6.0 [70] (🚀..🛅)    rocket..left luggage
-1F6CC         ; Emoji_Presentation   #  7.0  [1] (🛌)       person in bed
-1F6D0         ; Emoji_Presentation   #  8.0  [1] (🛐)       place of worship
-1F6D1..1F6D2  ; Emoji_Presentation   #  9.0  [2] (🛑..🛒)    stop sign..shopping cart
-1F6D5         ; Emoji_Presentation   # 12.0  [1] (🛕)       hindu temple
-1F6EB..1F6EC  ; Emoji_Presentation   #  7.0  [2] (🛫..🛬)    airplane departure..airplane arrival
-1F6F4..1F6F6  ; Emoji_Presentation   #  9.0  [3] (🛴..🛶)    kick scooter..canoe
-1F6F7..1F6F8  ; Emoji_Presentation   # 10.0  [2] (🛷..🛸)    sled..flying saucer
-1F6F9         ; Emoji_Presentation   # 11.0  [1] (🛹)       skateboard
-1F6FA         ; Emoji_Presentation   # 12.0  [1] (🛺)       auto rickshaw
-1F7E0..1F7EB  ; Emoji_Presentation   # 12.0 [12] (🟠..🟫)    orange circle..brown square
-1F90D..1F90F  ; Emoji_Presentation   # 12.0  [3] (🤍..🤏)    white heart..pinching hand
-1F910..1F918  ; Emoji_Presentation   #  8.0  [9] (🤐..🤘)    zipper-mouth face..sign of the horns
-1F919..1F91E  ; Emoji_Presentation   #  9.0  [6] (🤙..🤞)    call me hand..crossed fingers
-1F91F         ; Emoji_Presentation   # 10.0  [1] (🤟)       love-you gesture
-1F920..1F927  ; Emoji_Presentation   #  9.0  [8] (🤠..🤧)    cowboy hat face..sneezing face
-1F928..1F92F  ; Emoji_Presentation   # 10.0  [8] (🤨..🤯)    face with raised eyebrow..exploding head
-1F930         ; Emoji_Presentation   #  9.0  [1] (🤰)       pregnant woman
-1F931..1F932  ; Emoji_Presentation   # 10.0  [2] (🤱..🤲)    breast-feeding..palms up together
-1F933..1F93A  ; Emoji_Presentation   #  9.0  [8] (🤳..🤺)    selfie..person fencing
-1F93C..1F93E  ; Emoji_Presentation   #  9.0  [3] (🤼..🤾)    people wrestling..person playing handball
-1F93F         ; Emoji_Presentation   # 12.0  [1] (🤿)       diving mask
-1F940..1F945  ; Emoji_Presentation   #  9.0  [6] (🥀..🥅)    wilted flower..goal net
-1F947..1F94B  ; Emoji_Presentation   #  9.0  [5] (🥇..🥋)    1st place medal..martial arts uniform
-1F94C         ; Emoji_Presentation   # 10.0  [1] (🥌)       curling stone
-1F94D..1F94F  ; Emoji_Presentation   # 11.0  [3] (🥍..🥏)    lacrosse..flying disc
-1F950..1F95E  ; Emoji_Presentation   #  9.0 [15] (🥐..🥞)    croissant..pancakes
-1F95F..1F96B  ; Emoji_Presentation   # 10.0 [13] (🥟..🥫)    dumpling..canned food
-1F96C..1F970  ; Emoji_Presentation   # 11.0  [5] (🥬..🥰)    leafy green..smiling face with hearts
-1F971         ; Emoji_Presentation   # 12.0  [1] (🥱)       yawning face
-1F973..1F976  ; Emoji_Presentation   # 11.0  [4] (🥳..🥶)    partying face..cold face
-1F97A         ; Emoji_Presentation   # 11.0  [1] (🥺)       pleading face
-1F97B         ; Emoji_Presentation   # 12.0  [1] (🥻)       sari
-1F97C..1F97F  ; Emoji_Presentation   # 11.0  [4] (🥼..🥿)    lab coat..flat shoe
-1F980..1F984  ; Emoji_Presentation   #  8.0  [5] (🦀..🦄)    crab..unicorn
-1F985..1F991  ; Emoji_Presentation   #  9.0 [13] (🦅..🦑)    eagle..squid
-1F992..1F997  ; Emoji_Presentation   # 10.0  [6] (🦒..🦗)    giraffe..cricket
-1F998..1F9A2  ; Emoji_Presentation   # 11.0 [11] (🦘..🦢)    kangaroo..swan
-1F9A5..1F9AA  ; Emoji_Presentation   # 12.0  [6] (🦥..🦪)    sloth..oyster
-1F9AE..1F9AF  ; Emoji_Presentation   # 12.0  [2] (🦮..🦯)    guide dog..probing cane
-1F9B0..1F9B9  ; Emoji_Presentation   # 11.0 [10] (🦰..🦹)    red hair..supervillain
-1F9BA..1F9BF  ; Emoji_Presentation   # 12.0  [6] (🦺..🦿)    safety vest..mechanical leg
-1F9C0         ; Emoji_Presentation   #  8.0  [1] (🧀)       cheese wedge
-1F9C1..1F9C2  ; Emoji_Presentation   # 11.0  [2] (🧁..🧂)    cupcake..salt
-1F9C3..1F9CA  ; Emoji_Presentation   # 12.0  [8] (🧃..🧊)    beverage box..ice cube
-1F9CD..1F9CF  ; Emoji_Presentation   # 12.0  [3] (🧍..🧏)    person standing..deaf person
-1F9D0..1F9E6  ; Emoji_Presentation   # 10.0 [23] (🧐..🧦)    face with monocle..socks
-1F9E7..1F9FF  ; Emoji_Presentation   # 11.0 [25] (🧧..🧿)    red envelope..nazar amulet
-1FA70..1FA73  ; Emoji_Presentation   # 12.0  [4] (🩰..🩳)    ballet shoes..shorts
-1FA78..1FA7A  ; Emoji_Presentation   # 12.0  [3] (🩸..🩺)    drop of blood..stethoscope
-1FA80..1FA82  ; Emoji_Presentation   # 12.0  [3] (🪀..🪂)    yo-yo..parachute
-1FA90..1FA95  ; Emoji_Presentation   # 12.0  [6] (🪐..🪕)    ringed planet..banjo
-
-# Total elements: 1093
-
-# ================================================
-
-# All omitted code points have Emoji_Modifier=No
-# @missing: 0000..10FFFF  ; Emoji_Modifier ; No
-
-1F3FB..1F3FF  ; Emoji_Modifier       #  8.0  [5] (🏻..🏿)    light skin tone..dark skin tone
-
-# Total elements: 5
-
-# ================================================
-
-# All omitted code points have Emoji_Modifier_Base=No
-# @missing: 0000..10FFFF  ; Emoji_Modifier_Base ; No
-
-261D          ; Emoji_Modifier_Base  #  1.1  [1] (☝️)       index pointing up
-26F9          ; Emoji_Modifier_Base  #  5.2  [1] (⛹️)       person bouncing ball
-270A..270B    ; Emoji_Modifier_Base  #  6.0  [2] (✊..✋)    raised fist..raised hand
-270C..270D    ; Emoji_Modifier_Base  #  1.1  [2] (✌️..✍️)    victory hand..writing hand
-1F385         ; Emoji_Modifier_Base  #  6.0  [1] (🎅)       Santa Claus
-1F3C2..1F3C4  ; Emoji_Modifier_Base  #  6.0  [3] (🏂..🏄)    snowboarder..person surfing
-1F3C7         ; Emoji_Modifier_Base  #  6.0  [1] (🏇)       horse racing
-1F3CA         ; Emoji_Modifier_Base  #  6.0  [1] (🏊)       person swimming
-1F3CB..1F3CC  ; Emoji_Modifier_Base  #  7.0  [2] (🏋️..🏌️)    person lifting weights..person golfing
-1F442..1F443  ; Emoji_Modifier_Base  #  6.0  [2] (👂..👃)    ear..nose
-1F446..1F450  ; Emoji_Modifier_Base  #  6.0 [11] (👆..👐)    backhand index pointing up..open hands
-1F466..1F478  ; Emoji_Modifier_Base  #  6.0 [19] (👦..👸)    boy..princess
-1F47C         ; Emoji_Modifier_Base  #  6.0  [1] (👼)       baby angel
-1F481..1F483  ; Emoji_Modifier_Base  #  6.0  [3] (💁..💃)    person tipping hand..woman dancing
-1F485..1F487  ; Emoji_Modifier_Base  #  6.0  [3] (💅..💇)    nail polish..person getting haircut
-1F48F         ; Emoji_Modifier_Base  #  6.0  [1] (💏)       kiss
-1F491         ; Emoji_Modifier_Base  #  6.0  [1] (💑)       couple with heart
-1F4AA         ; Emoji_Modifier_Base  #  6.0  [1] (💪)       flexed biceps
-1F574..1F575  ; Emoji_Modifier_Base  #  7.0  [2] (🕴️..🕵️)    man in suit levitating..detective
-1F57A         ; Emoji_Modifier_Base  #  9.0  [1] (🕺)       man dancing
-1F590         ; Emoji_Modifier_Base  #  7.0  [1] (🖐️)       hand with fingers splayed
-1F595..1F596  ; Emoji_Modifier_Base  #  7.0  [2] (🖕..🖖)    middle finger..vulcan salute
-1F645..1F647  ; Emoji_Modifier_Base  #  6.0  [3] (🙅..🙇)    person gesturing NO..person bowing
-1F64B..1F64F  ; Emoji_Modifier_Base  #  6.0  [5] (🙋..🙏)    person raising hand..folded hands
-1F6A3         ; Emoji_Modifier_Base  #  6.0  [1] (🚣)       person rowing boat
-1F6B4..1F6B6  ; Emoji_Modifier_Base  #  6.0  [3] (🚴..🚶)    person biking..person walking
-1F6C0         ; Emoji_Modifier_Base  #  6.0  [1] (🛀)       person taking bath
-1F6CC         ; Emoji_Modifier_Base  #  7.0  [1] (🛌)       person in bed
-1F90F         ; Emoji_Modifier_Base  # 12.0  [1] (🤏)       pinching hand
-1F918         ; Emoji_Modifier_Base  #  8.0  [1] (🤘)       sign of the horns
-1F919..1F91E  ; Emoji_Modifier_Base  #  9.0  [6] (🤙..🤞)    call me hand..crossed fingers
-1F91F         ; Emoji_Modifier_Base  # 10.0  [1] (🤟)       love-you gesture
-1F926         ; Emoji_Modifier_Base  #  9.0  [1] (🤦)       person facepalming
-1F930         ; Emoji_Modifier_Base  #  9.0  [1] (🤰)       pregnant woman
-1F931..1F932  ; Emoji_Modifier_Base  # 10.0  [2] (🤱..🤲)    breast-feeding..palms up together
-1F933..1F939  ; Emoji_Modifier_Base  #  9.0  [7] (🤳..🤹)    selfie..person juggling
-1F93C..1F93E  ; Emoji_Modifier_Base  #  9.0  [3] (🤼..🤾)    people wrestling..person playing handball
-1F9B5..1F9B6  ; Emoji_Modifier_Base  # 11.0  [2] (🦵..🦶)    leg..foot
-1F9B8..1F9B9  ; Emoji_Modifier_Base  # 11.0  [2] (🦸..🦹)    superhero..supervillain
-1F9BB         ; Emoji_Modifier_Base  # 12.0  [1] (🦻)       ear with hearing aid
-1F9CD..1F9CF  ; Emoji_Modifier_Base  # 12.0  [3] (🧍..🧏)    person standing..deaf person
-1F9D1..1F9DD  ; Emoji_Modifier_Base  # 10.0 [13] (🧑..🧝)    person..elf
-
-# Total elements: 120
-
-# ================================================
-
-# All omitted code points have Emoji_Component=No
-# @missing: 0000..10FFFF  ; Emoji_Component ; No
-
-0023          ; Emoji_Component      #  1.1  [1] (#️)       number sign
-002A          ; Emoji_Component      #  1.1  [1] (*️)       asterisk
-0030..0039    ; Emoji_Component      #  1.1 [10] (0️..9️)    digit zero..digit nine
-200D          ; Emoji_Component      #  1.1  [1] (‍)        zero width joiner
-20E3          ; Emoji_Component      #  3.0  [1] (⃣)       combining enclosing keycap
-FE0F          ; Emoji_Component      #  3.2  [1] ()        VARIATION SELECTOR-16
-1F1E6..1F1FF  ; Emoji_Component      #  6.0 [26] (🇦..🇿)    regional indicator symbol letter a..regional indicator symbol letter z
-1F3FB..1F3FF  ; Emoji_Component      #  8.0  [5] (🏻..🏿)    light skin tone..dark skin tone
-1F9B0..1F9B3  ; Emoji_Component      # 11.0  [4] (🦰..🦳)    red hair..white hair
-E0020..E007F  ; Emoji_Component      #  3.1 [96] (󠀠..󠁿)      tag space..cancel tag
-
-# Total elements: 146
-
-# ================================================
-
-# All omitted code points have Extended_Pictographic=No
-# @missing: 0000..10FFFF  ; Extended_Pictographic ; No
-
-00A9          ; Extended_Pictographic#  1.1  [1] (©️)       copyright
-00AE          ; Extended_Pictographic#  1.1  [1] (®️)       registered
-203C          ; Extended_Pictographic#  1.1  [1] (‼️)       double exclamation mark
-2049          ; Extended_Pictographic#  3.0  [1] (⁉️)       exclamation question mark
-2122          ; Extended_Pictographic#  1.1  [1] (™️)       trade mark
-2139          ; Extended_Pictographic#  3.0  [1] (ℹ️)       information
-2194..2199    ; Extended_Pictographic#  1.1  [6] (↔️..↙️)    left-right arrow..down-left arrow
-21A9..21AA    ; Extended_Pictographic#  1.1  [2] (↩️..↪️)    right arrow curving left..left arrow curving right
-231A..231B    ; Extended_Pictographic#  1.1  [2] (⌚..⌛)    watch..hourglass done
-2328          ; Extended_Pictographic#  1.1  [1] (⌨️)       keyboard
-2388          ; Extended_Pictographic#  3.0  [1] (⎈)       HELM SYMBOL
-23CF          ; Extended_Pictographic#  4.0  [1] (⏏️)       eject button
-23E9..23F3    ; Extended_Pictographic#  6.0 [11] (⏩..⏳)    fast-forward button..hourglass not done
-23F8..23FA    ; Extended_Pictographic#  7.0  [3] (⏸️..⏺️)    pause button..record button
-24C2          ; Extended_Pictographic#  1.1  [1] (Ⓜ️)       circled M
-25AA..25AB    ; Extended_Pictographic#  1.1  [2] (▪️..▫️)    black small square..white small square
-25B6          ; Extended_Pictographic#  1.1  [1] (▶️)       play button
-25C0          ; Extended_Pictographic#  1.1  [1] (◀️)       reverse button
-25FB..25FE    ; Extended_Pictographic#  3.2  [4] (◻️..◾)    white medium square..black medium-small square
-2600..2605    ; Extended_Pictographic#  1.1  [6] (☀️..★)    sun..BLACK STAR
-2607..2612    ; Extended_Pictographic#  1.1 [12] (☇..☒)    LIGHTNING..BALLOT BOX WITH X
-2614..2615    ; Extended_Pictographic#  4.0  [2] (☔..☕)    umbrella with rain drops..hot beverage
-2616..2617    ; Extended_Pictographic#  3.2  [2] (☖..☗)    WHITE SHOGI PIECE..BLACK SHOGI PIECE
-2618          ; Extended_Pictographic#  4.1  [1] (☘️)       shamrock
-2619          ; Extended_Pictographic#  3.0  [1] (☙)       REVERSED ROTATED FLORAL HEART BULLET
-261A..266F    ; Extended_Pictographic#  1.1 [86] (☚..♯)    BLACK LEFT POINTING INDEX..MUSIC SHARP SIGN
-2670..2671    ; Extended_Pictographic#  3.0  [2] (♰..♱)    WEST SYRIAC CROSS..EAST SYRIAC CROSS
-2672..267D    ; Extended_Pictographic#  3.2 [12] (♲..♽)    UNIVERSAL RECYCLING SYMBOL..PARTIALLY-RECYCLED PAPER SYMBOL
-267E..267F    ; Extended_Pictographic#  4.1  [2] (♾️..♿)    infinity..wheelchair symbol
-2680..2685    ; Extended_Pictographic#  3.2  [6] (⚀..⚅)    DIE FACE-1..DIE FACE-6
-2690..2691    ; Extended_Pictographic#  4.0  [2] (⚐..⚑)    WHITE FLAG..BLACK FLAG
-2692..269C    ; Extended_Pictographic#  4.1 [11] (⚒️..⚜️)    hammer and pick..fleur-de-lis
-269D          ; Extended_Pictographic#  5.1  [1] (⚝)       OUTLINED WHITE STAR
-269E..269F    ; Extended_Pictographic#  5.2  [2] (⚞..⚟)    THREE LINES CONVERGING RIGHT..THREE LINES CONVERGING LEFT
-26A0..26A1    ; Extended_Pictographic#  4.0  [2] (⚠️..⚡)    warning..high voltage
-26A2..26B1    ; Extended_Pictographic#  4.1 [16] (⚢..⚱️)    DOUBLED FEMALE SIGN..funeral urn
-26B2          ; Extended_Pictographic#  5.0  [1] (⚲)       NEUTER
-26B3..26BC    ; Extended_Pictographic#  5.1 [10] (⚳..⚼)    CERES..SESQUIQUADRATE
-26BD..26BF    ; Extended_Pictographic#  5.2  [3] (⚽..⚿)    soccer ball..SQUARED KEY
-26C0..26C3    ; Extended_Pictographic#  5.1  [4] (⛀..⛃)    WHITE DRAUGHTS MAN..BLACK DRAUGHTS KING
-26C4..26CD    ; Extended_Pictographic#  5.2 [10] (⛄..⛍)    snowman without snow..DISABLED CAR
-26CE          ; Extended_Pictographic#  6.0  [1] (⛎)       Ophiuchus
-26CF..26E1    ; Extended_Pictographic#  5.2 [19] (⛏️..⛡)    pick..RESTRICTED LEFT ENTRY-2
-26E2          ; Extended_Pictographic#  6.0  [1] (⛢)       ASTRONOMICAL SYMBOL FOR URANUS
-26E3          ; Extended_Pictographic#  5.2  [1] (⛣)       HEAVY CIRCLE WITH STROKE AND TWO DOTS ABOVE
-26E4..26E7    ; Extended_Pictographic#  6.0  [4] (⛤..⛧)    PENTAGRAM..INVERTED PENTAGRAM
-26E8..26FF    ; Extended_Pictographic#  5.2 [24] (⛨..⛿)    BLACK CROSS ON SHIELD..WHITE FLAG WITH HORIZONTAL MIDDLE BLACK STRIPE
-2700          ; Extended_Pictographic#  7.0  [1] (✀)       BLACK SAFETY SCISSORS
-2701..2704    ; Extended_Pictographic#  1.1  [4] (✁..✄)    UPPER BLADE SCISSORS..WHITE SCISSORS
-2705          ; Extended_Pictographic#  6.0  [1] (✅)       check mark button
-2708..2709    ; Extended_Pictographic#  1.1  [2] (✈️..✉️)    airplane..envelope
-270A..270B    ; Extended_Pictographic#  6.0  [2] (✊..✋)    raised fist..raised hand
-270C..2712    ; Extended_Pictographic#  1.1  [7] (✌️..✒️)    victory hand..black nib
-2714          ; Extended_Pictographic#  1.1  [1] (✔️)       check mark
-2716          ; Extended_Pictographic#  1.1  [1] (✖️)       multiplication sign
-271D          ; Extended_Pictographic#  1.1  [1] (✝️)       latin cross
-2721          ; Extended_Pictographic#  1.1  [1] (✡️)       star of David
-2728          ; Extended_Pictographic#  6.0  [1] (✨)       sparkles
-2733..2734    ; Extended_Pictographic#  1.1  [2] (✳️..✴️)    eight-spoked asterisk..eight-pointed star
-2744          ; Extended_Pictographic#  1.1  [1] (❄️)       snowflake
-2747          ; Extended_Pictographic#  1.1  [1] (❇️)       sparkle
-274C          ; Extended_Pictographic#  6.0  [1] (❌)       cross mark
-274E          ; Extended_Pictographic#  6.0  [1] (❎)       cross mark button
-2753..2755    ; Extended_Pictographic#  6.0  [3] (❓..❕)    question mark..white exclamation mark
-2757          ; Extended_Pictographic#  5.2  [1] (❗)       exclamation mark
-2763..2767    ; Extended_Pictographic#  1.1  [5] (❣️..❧)    heart exclamation..ROTATED FLORAL HEART BULLET
-2795..2797    ; Extended_Pictographic#  6.0  [3] (➕..➗)    plus sign..division sign
-27A1          ; Extended_Pictographic#  1.1  [1] (➡️)       right arrow
-27B0          ; Extended_Pictographic#  6.0  [1] (➰)       curly loop
-27BF          ; Extended_Pictographic#  6.0  [1] (➿)       double curly loop
-2934..2935    ; Extended_Pictographic#  3.2  [2] (⤴️..⤵️)    right arrow curving up..right arrow curving down
-2B05..2B07    ; Extended_Pictographic#  4.0  [3] (⬅️..⬇️)    left arrow..down arrow
-2B1B..2B1C    ; Extended_Pictographic#  5.1  [2] (⬛..⬜)    black large square..white large square
-2B50          ; Extended_Pictographic#  5.1  [1] (⭐)       star
-2B55          ; Extended_Pictographic#  5.2  [1] (⭕)       hollow red circle
-3030          ; Extended_Pictographic#  1.1  [1] (〰️)       wavy dash
-303D          ; Extended_Pictographic#  3.2  [1] (〽️)       part alternation mark
-3297          ; Extended_Pictographic#  1.1  [1] (㊗️)       Japanese “congratulations” button
-3299          ; Extended_Pictographic#  1.1  [1] (㊙️)       Japanese “secret” button
-1F000..1F02B  ; Extended_Pictographic#  5.1 [44] (🀀..🀫)    MAHJONG TILE EAST WIND..MAHJONG TILE BACK
-1F02C..1F02F  ; Extended_Pictographic#   NA  [4] (🀬..🀯)    ..
-1F030..1F093  ; Extended_Pictographic#  5.1[100] (🀰..🂓)    DOMINO TILE HORIZONTAL BACK..DOMINO TILE VERTICAL-06-06
-1F094..1F09F  ; Extended_Pictographic#   NA [12] (🂔..🂟)    ..
-1F0A0..1F0AE  ; Extended_Pictographic#  6.0 [15] (🂠..🂮)    PLAYING CARD BACK..PLAYING CARD KING OF SPADES
-1F0AF..1F0B0  ; Extended_Pictographic#   NA  [2] (🂯..🂰)    ..
-1F0B1..1F0BE  ; Extended_Pictographic#  6.0 [14] (🂱..🂾)    PLAYING CARD ACE OF HEARTS..PLAYING CARD KING OF HEARTS
-1F0BF         ; Extended_Pictographic#  7.0  [1] (🂿)       PLAYING CARD RED JOKER
-1F0C0         ; Extended_Pictographic#   NA  [1] (🃀)       
-1F0C1..1F0CF  ; Extended_Pictographic#  6.0 [15] (🃁..🃏)    PLAYING CARD ACE OF DIAMONDS..joker
-1F0D0         ; Extended_Pictographic#   NA  [1] (🃐)       
-1F0D1..1F0DF  ; Extended_Pictographic#  6.0 [15] (🃑..🃟)    PLAYING CARD ACE OF CLUBS..PLAYING CARD WHITE JOKER
-1F0E0..1F0F5  ; Extended_Pictographic#  7.0 [22] (🃠..🃵)    PLAYING CARD FOOL..PLAYING CARD TRUMP-21
-1F0F6..1F0FF  ; Extended_Pictographic#   NA [10] (🃶..🃿)    ..
-1F10D..1F10F  ; Extended_Pictographic#   NA  [3] (🄍..🄏)    ..
-1F12F         ; Extended_Pictographic# 11.0  [1] (🄯)       COPYLEFT SYMBOL
-1F16C         ; Extended_Pictographic# 12.0  [1] (🅬)       RAISED MR SIGN
-1F16D..1F16F  ; Extended_Pictographic#   NA  [3] (🅭..🅯)    ..
-1F170..1F171  ; Extended_Pictographic#  6.0  [2] (🅰️..🅱️)    A button (blood type)..B button (blood type)
-1F17E         ; Extended_Pictographic#  6.0  [1] (🅾️)       O button (blood type)
-1F17F         ; Extended_Pictographic#  5.2  [1] (🅿️)       P button
-1F18E         ; Extended_Pictographic#  6.0  [1] (🆎)       AB button (blood type)
-1F191..1F19A  ; Extended_Pictographic#  6.0 [10] (🆑..🆚)    CL button..VS button
-1F1AD..1F1E5  ; Extended_Pictographic#   NA [57] (🆭..🇥)    ..
-1F201..1F202  ; Extended_Pictographic#  6.0  [2] (🈁..🈂️)    Japanese “here” button..Japanese “service charge” button
-1F203..1F20F  ; Extended_Pictographic#   NA [13] (🈃..🈏)    ..
-1F21A         ; Extended_Pictographic#  5.2  [1] (🈚)       Japanese “free of charge” button
-1F22F         ; Extended_Pictographic#  5.2  [1] (🈯)       Japanese “reserved” button
-1F232..1F23A  ; Extended_Pictographic#  6.0  [9] (🈲..🈺)    Japanese “prohibited” button..Japanese “open for business” button
-1F23C..1F23F  ; Extended_Pictographic#   NA  [4] (🈼..🈿)    ..
-1F249..1F24F  ; Extended_Pictographic#   NA  [7] (🉉..🉏)    ..
-1F250..1F251  ; Extended_Pictographic#  6.0  [2] (🉐..🉑)    Japanese “bargain” button..Japanese “acceptable” button
-1F252..1F25F  ; Extended_Pictographic#   NA [14] (🉒..🉟)    ..
-1F260..1F265  ; Extended_Pictographic# 10.0  [6] (🉠..🉥)    ROUNDED SYMBOL FOR FU..ROUNDED SYMBOL FOR CAI
-1F266..1F2FF  ; Extended_Pictographic#   NA[154] (🉦..🋿)    ..
-1F300..1F320  ; Extended_Pictographic#  6.0 [33] (🌀..🌠)    cyclone..shooting star
-1F321..1F32C  ; Extended_Pictographic#  7.0 [12] (🌡️..🌬️)    thermometer..wind face
-1F32D..1F32F  ; Extended_Pictographic#  8.0  [3] (🌭..🌯)    hot dog..burrito
-1F330..1F335  ; Extended_Pictographic#  6.0  [6] (🌰..🌵)    chestnut..cactus
-1F336         ; Extended_Pictographic#  7.0  [1] (🌶️)       hot pepper
-1F337..1F37C  ; Extended_Pictographic#  6.0 [70] (🌷..🍼)    tulip..baby bottle
-1F37D         ; Extended_Pictographic#  7.0  [1] (🍽️)       fork and knife with plate
-1F37E..1F37F  ; Extended_Pictographic#  8.0  [2] (🍾..🍿)    bottle with popping cork..popcorn
-1F380..1F393  ; Extended_Pictographic#  6.0 [20] (🎀..🎓)    ribbon..graduation cap
-1F394..1F39F  ; Extended_Pictographic#  7.0 [12] (🎔..🎟️)    HEART WITH TIP ON THE LEFT..admission tickets
-1F3A0..1F3C4  ; Extended_Pictographic#  6.0 [37] (🎠..🏄)    carousel horse..person surfing
-1F3C5         ; Extended_Pictographic#  7.0  [1] (🏅)       sports medal
-1F3C6..1F3CA  ; Extended_Pictographic#  6.0  [5] (🏆..🏊)    trophy..person swimming
-1F3CB..1F3CE  ; Extended_Pictographic#  7.0  [4] (🏋️..🏎️)    person lifting weights..racing car
-1F3CF..1F3D3  ; Extended_Pictographic#  8.0  [5] (🏏..🏓)    cricket game..ping pong
-1F3D4..1F3DF  ; Extended_Pictographic#  7.0 [12] (🏔️..🏟️)    snow-capped mountain..stadium
-1F3E0..1F3F0  ; Extended_Pictographic#  6.0 [17] (🏠..🏰)    house..castle
-1F3F1..1F3F7  ; Extended_Pictographic#  7.0  [7] (🏱..🏷️)    WHITE PENNANT..label
-1F3F8..1F3FA  ; Extended_Pictographic#  8.0  [3] (🏸..🏺)    badminton..amphora
-1F400..1F43E  ; Extended_Pictographic#  6.0 [63] (🐀..🐾)    rat..paw prints
-1F43F         ; Extended_Pictographic#  7.0  [1] (🐿️)       chipmunk
-1F440         ; Extended_Pictographic#  6.0  [1] (👀)       eyes
-1F441         ; Extended_Pictographic#  7.0  [1] (👁️)       eye
-1F442..1F4F7  ; Extended_Pictographic#  6.0[182] (👂..📷)    ear..camera
-1F4F8         ; Extended_Pictographic#  7.0  [1] (📸)       camera with flash
-1F4F9..1F4FC  ; Extended_Pictographic#  6.0  [4] (📹..📼)    video camera..videocassette
-1F4FD..1F4FE  ; Extended_Pictographic#  7.0  [2] (📽️..📾)    film projector..PORTABLE STEREO
-1F4FF         ; Extended_Pictographic#  8.0  [1] (📿)       prayer beads
-1F500..1F53D  ; Extended_Pictographic#  6.0 [62] (🔀..🔽)    shuffle tracks button..downwards button
-1F546..1F54A  ; Extended_Pictographic#  7.0  [5] (🕆..🕊️)    WHITE LATIN CROSS..dove
-1F54B..1F54F  ; Extended_Pictographic#  8.0  [5] (🕋..🕏)    kaaba..BOWL OF HYGIEIA
-1F550..1F567  ; Extended_Pictographic#  6.0 [24] (🕐..🕧)    one o’clock..twelve-thirty
-1F568..1F579  ; Extended_Pictographic#  7.0 [18] (🕨..🕹️)    RIGHT SPEAKER..joystick
-1F57A         ; Extended_Pictographic#  9.0  [1] (🕺)       man dancing
-1F57B..1F5A3  ; Extended_Pictographic#  7.0 [41] (🕻..🖣)    LEFT HAND TELEPHONE RECEIVER..BLACK DOWN POINTING BACKHAND INDEX
-1F5A4         ; Extended_Pictographic#  9.0  [1] (🖤)       black heart
-1F5A5..1F5FA  ; Extended_Pictographic#  7.0 [86] (🖥️..🗺️)    desktop computer..world map
-1F5FB..1F5FF  ; Extended_Pictographic#  6.0  [5] (🗻..🗿)    mount fuji..moai
-1F600         ; Extended_Pictographic#  6.1  [1] (😀)       grinning face
-1F601..1F610  ; Extended_Pictographic#  6.0 [16] (😁..😐)    beaming face with smiling eyes..neutral face
-1F611         ; Extended_Pictographic#  6.1  [1] (😑)       expressionless face
-1F612..1F614  ; Extended_Pictographic#  6.0  [3] (😒..😔)    unamused face..pensive face
-1F615         ; Extended_Pictographic#  6.1  [1] (😕)       confused face
-1F616         ; Extended_Pictographic#  6.0  [1] (😖)       confounded face
-1F617         ; Extended_Pictographic#  6.1  [1] (😗)       kissing face
-1F618         ; Extended_Pictographic#  6.0  [1] (😘)       face blowing a kiss
-1F619         ; Extended_Pictographic#  6.1  [1] (😙)       kissing face with smiling eyes
-1F61A         ; Extended_Pictographic#  6.0  [1] (😚)       kissing face with closed eyes
-1F61B         ; Extended_Pictographic#  6.1  [1] (😛)       face with tongue
-1F61C..1F61E  ; Extended_Pictographic#  6.0  [3] (😜..😞)    winking face with tongue..disappointed face
-1F61F         ; Extended_Pictographic#  6.1  [1] (😟)       worried face
-1F620..1F625  ; Extended_Pictographic#  6.0  [6] (😠..😥)    angry face..sad but relieved face
-1F626..1F627  ; Extended_Pictographic#  6.1  [2] (😦..😧)    frowning face with open mouth..anguished face
-1F628..1F62B  ; Extended_Pictographic#  6.0  [4] (😨..😫)    fearful face..tired face
-1F62C         ; Extended_Pictographic#  6.1  [1] (😬)       grimacing face
-1F62D         ; Extended_Pictographic#  6.0  [1] (😭)       loudly crying face
-1F62E..1F62F  ; Extended_Pictographic#  6.1  [2] (😮..😯)    face with open mouth..hushed face
-1F630..1F633  ; Extended_Pictographic#  6.0  [4] (😰..😳)    anxious face with sweat..flushed face
-1F634         ; Extended_Pictographic#  6.1  [1] (😴)       sleeping face
-1F635..1F640  ; Extended_Pictographic#  6.0 [12] (😵..🙀)    dizzy face..weary cat
-1F641..1F642  ; Extended_Pictographic#  7.0  [2] (🙁..🙂)    slightly frowning face..slightly smiling face
-1F643..1F644  ; Extended_Pictographic#  8.0  [2] (🙃..🙄)    upside-down face..face with rolling eyes
-1F645..1F64F  ; Extended_Pictographic#  6.0 [11] (🙅..🙏)    person gesturing NO..folded hands
-1F680..1F6C5  ; Extended_Pictographic#  6.0 [70] (🚀..🛅)    rocket..left luggage
-1F6C6..1F6CF  ; Extended_Pictographic#  7.0 [10] (🛆..🛏️)    TRIANGLE WITH ROUNDED CORNERS..bed
-1F6D0         ; Extended_Pictographic#  8.0  [1] (🛐)       place of worship
-1F6D1..1F6D2  ; Extended_Pictographic#  9.0  [2] (🛑..🛒)    stop sign..shopping cart
-1F6D3..1F6D4  ; Extended_Pictographic# 10.0  [2] (🛓..🛔)    STUPA..PAGODA
-1F6D5         ; Extended_Pictographic# 12.0  [1] (🛕)       hindu temple
-1F6D6..1F6DF  ; Extended_Pictographic#   NA [10] (🛖..🛟)    ..
-1F6E0..1F6EC  ; Extended_Pictographic#  7.0 [13] (🛠️..🛬)    hammer and wrench..airplane arrival
-1F6ED..1F6EF  ; Extended_Pictographic#   NA  [3] (🛭..🛯)    ..
-1F6F0..1F6F3  ; Extended_Pictographic#  7.0  [4] (🛰️..🛳️)    satellite..passenger ship
-1F6F4..1F6F6  ; Extended_Pictographic#  9.0  [3] (🛴..🛶)    kick scooter..canoe
-1F6F7..1F6F8  ; Extended_Pictographic# 10.0  [2] (🛷..🛸)    sled..flying saucer
-1F6F9         ; Extended_Pictographic# 11.0  [1] (🛹)       skateboard
-1F6FA         ; Extended_Pictographic# 12.0  [1] (🛺)       auto rickshaw
-1F6FB..1F6FF  ; Extended_Pictographic#   NA  [5] (🛻..🛿)    ..
-1F774..1F77F  ; Extended_Pictographic#   NA [12] (🝴..🝿)    ..
-1F7D5..1F7D8  ; Extended_Pictographic# 11.0  [4] (🟕..🟘)    CIRCLED TRIANGLE..NEGATIVE CIRCLED SQUARE
-1F7D9..1F7DF  ; Extended_Pictographic#   NA  [7] (🟙..🟟)    ..
-1F7E0..1F7EB  ; Extended_Pictographic# 12.0 [12] (🟠..🟫)    orange circle..brown square
-1F7EC..1F7FF  ; Extended_Pictographic#   NA [20] (🟬..🟿)    ..
-1F80C..1F80F  ; Extended_Pictographic#   NA  [4] (🠌..🠏)    ..
-1F848..1F84F  ; Extended_Pictographic#   NA  [8] (🡈..🡏)    ..
-1F85A..1F85F  ; Extended_Pictographic#   NA  [6] (🡚..🡟)    ..
-1F888..1F88F  ; Extended_Pictographic#   NA  [8] (🢈..🢏)    ..
-1F8AE..1F8FF  ; Extended_Pictographic#   NA [82] (🢮..🣿)    ..
-1F90C         ; Extended_Pictographic#   NA  [1] (🤌)       
-1F90D..1F90F  ; Extended_Pictographic# 12.0  [3] (🤍..🤏)    white heart..pinching hand
-1F910..1F918  ; Extended_Pictographic#  8.0  [9] (🤐..🤘)    zipper-mouth face..sign of the horns
-1F919..1F91E  ; Extended_Pictographic#  9.0  [6] (🤙..🤞)    call me hand..crossed fingers
-1F91F         ; Extended_Pictographic# 10.0  [1] (🤟)       love-you gesture
-1F920..1F927  ; Extended_Pictographic#  9.0  [8] (🤠..🤧)    cowboy hat face..sneezing face
-1F928..1F92F  ; Extended_Pictographic# 10.0  [8] (🤨..🤯)    face with raised eyebrow..exploding head
-1F930         ; Extended_Pictographic#  9.0  [1] (🤰)       pregnant woman
-1F931..1F932  ; Extended_Pictographic# 10.0  [2] (🤱..🤲)    breast-feeding..palms up together
-1F933..1F93A  ; Extended_Pictographic#  9.0  [8] (🤳..🤺)    selfie..person fencing
-1F93C..1F93E  ; Extended_Pictographic#  9.0  [3] (🤼..🤾)    people wrestling..person playing handball
-1F93F         ; Extended_Pictographic# 12.0  [1] (🤿)       diving mask
-1F940..1F945  ; Extended_Pictographic#  9.0  [6] (🥀..🥅)    wilted flower..goal net
-1F947..1F94B  ; Extended_Pictographic#  9.0  [5] (🥇..🥋)    1st place medal..martial arts uniform
-1F94C         ; Extended_Pictographic# 10.0  [1] (🥌)       curling stone
-1F94D..1F94F  ; Extended_Pictographic# 11.0  [3] (🥍..🥏)    lacrosse..flying disc
-1F950..1F95E  ; Extended_Pictographic#  9.0 [15] (🥐..🥞)    croissant..pancakes
-1F95F..1F96B  ; Extended_Pictographic# 10.0 [13] (🥟..🥫)    dumpling..canned food
-1F96C..1F970  ; Extended_Pictographic# 11.0  [5] (🥬..🥰)    leafy green..smiling face with hearts
-1F971         ; Extended_Pictographic# 12.0  [1] (🥱)       yawning face
-1F972         ; Extended_Pictographic#   NA  [1] (🥲)       
-1F973..1F976  ; Extended_Pictographic# 11.0  [4] (🥳..🥶)    partying face..cold face
-1F977..1F979  ; Extended_Pictographic#   NA  [3] (🥷..🥹)    ..
-1F97A         ; Extended_Pictographic# 11.0  [1] (🥺)       pleading face
-1F97B         ; Extended_Pictographic# 12.0  [1] (🥻)       sari
-1F97C..1F97F  ; Extended_Pictographic# 11.0  [4] (🥼..🥿)    lab coat..flat shoe
-1F980..1F984  ; Extended_Pictographic#  8.0  [5] (🦀..🦄)    crab..unicorn
-1F985..1F991  ; Extended_Pictographic#  9.0 [13] (🦅..🦑)    eagle..squid
-1F992..1F997  ; Extended_Pictographic# 10.0  [6] (🦒..🦗)    giraffe..cricket
-1F998..1F9A2  ; Extended_Pictographic# 11.0 [11] (🦘..🦢)    kangaroo..swan
-1F9A3..1F9A4  ; Extended_Pictographic#   NA  [2] (🦣..🦤)    ..
-1F9A5..1F9AA  ; Extended_Pictographic# 12.0  [6] (🦥..🦪)    sloth..oyster
-1F9AB..1F9AD  ; Extended_Pictographic#   NA  [3] (🦫..🦭)    ..
-1F9AE..1F9AF  ; Extended_Pictographic# 12.0  [2] (🦮..🦯)    guide dog..probing cane
-1F9B0..1F9B9  ; Extended_Pictographic# 11.0 [10] (🦰..🦹)    red hair..supervillain
-1F9BA..1F9BF  ; Extended_Pictographic# 12.0  [6] (🦺..🦿)    safety vest..mechanical leg
-1F9C0         ; Extended_Pictographic#  8.0  [1] (🧀)       cheese wedge
-1F9C1..1F9C2  ; Extended_Pictographic# 11.0  [2] (🧁..🧂)    cupcake..salt
-1F9C3..1F9CA  ; Extended_Pictographic# 12.0  [8] (🧃..🧊)    beverage box..ice cube
-1F9CB..1F9CC  ; Extended_Pictographic#   NA  [2] (🧋..🧌)    ..
-1F9CD..1F9CF  ; Extended_Pictographic# 12.0  [3] (🧍..🧏)    person standing..deaf person
-1F9D0..1F9E6  ; Extended_Pictographic# 10.0 [23] (🧐..🧦)    face with monocle..socks
-1F9E7..1F9FF  ; Extended_Pictographic# 11.0 [25] (🧧..🧿)    red envelope..nazar amulet
-1FA00..1FA53  ; Extended_Pictographic# 12.0 [84] (🨀..🩓)    NEUTRAL CHESS KING..BLACK CHESS KNIGHT-BISHOP
-1FA54..1FA5F  ; Extended_Pictographic#   NA [12] (🩔..🩟)    ..
-1FA60..1FA6D  ; Extended_Pictographic# 11.0 [14] (🩠..🩭)    XIANGQI RED GENERAL..XIANGQI BLACK SOLDIER
-1FA6E..1FA6F  ; Extended_Pictographic#   NA  [2] (🩮..🩯)    ..
-1FA70..1FA73  ; Extended_Pictographic# 12.0  [4] (🩰..🩳)    ballet shoes..shorts
-1FA74..1FA77  ; Extended_Pictographic#   NA  [4] (🩴..🩷)    ..
-1FA78..1FA7A  ; Extended_Pictographic# 12.0  [3] (🩸..🩺)    drop of blood..stethoscope
-1FA7B..1FA7F  ; Extended_Pictographic#   NA  [5] (🩻..🩿)    ..
-1FA80..1FA82  ; Extended_Pictographic# 12.0  [3] (🪀..🪂)    yo-yo..parachute
-1FA83..1FA8F  ; Extended_Pictographic#   NA [13] (🪃..🪏)    ..
-1FA90..1FA95  ; Extended_Pictographic# 12.0  [6] (🪐..🪕)    ringed planet..banjo
-1FA96..1FFFD  ; Extended_Pictographic#   NA[1384] (🪖..🿽)   ..
-
-# Total elements: 3793
-
-#EOF
diff --git a/make/data/unicodedata/emoji/emoji-data.txt b/make/data/unicodedata/emoji/emoji-data.txt
new file mode 100644
index 00000000000..a01213299b7
--- /dev/null
+++ b/make/data/unicodedata/emoji/emoji-data.txt
@@ -0,0 +1,1261 @@
+# emoji-data.txt
+# Date: 2020-01-28, 20:52:38 GMT
+# Copyright (c) 2020 Unicode, Inc.
+# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
+# For terms of use, see http://www.unicode.org/terms_of_use.html
+#
+# Emoji Data for UTS #51
+# Version: 13.0
+#
+# For documentation and usage, see http://www.unicode.org/reports/tr51
+#
+# Format: 
+#  ;  #  
+# Note: there is no guarantee as to the structure of whitespace or comments
+#
+# Characters and sequences are listed in code point order. Users should be shown a more natural order.
+# See the CLDR collation order for Emoji.
+
+
+# ================================================
+
+# All omitted code points have Emoji=No 
+# @missing: 0000..10FFFF  ; Emoji ; No
+
+0023          ; Emoji                # E0.0   [1] (#️)       number sign
+002A          ; Emoji                # E0.0   [1] (*️)       asterisk
+0030..0039    ; Emoji                # E0.0  [10] (0️..9️)    digit zero..digit nine
+00A9          ; Emoji                # E0.6   [1] (©️)       copyright
+00AE          ; Emoji                # E0.6   [1] (®️)       registered
+203C          ; Emoji                # E0.6   [1] (‼️)       double exclamation mark
+2049          ; Emoji                # E0.6   [1] (⁉️)       exclamation question mark
+2122          ; Emoji                # E0.6   [1] (™️)       trade mark
+2139          ; Emoji                # E0.6   [1] (ℹ️)       information
+2194..2199    ; Emoji                # E0.6   [6] (↔️..↙️)    left-right arrow..down-left arrow
+21A9..21AA    ; Emoji                # E0.6   [2] (↩️..↪️)    right arrow curving left..left arrow curving right
+231A..231B    ; Emoji                # E0.6   [2] (⌚..⌛)    watch..hourglass done
+2328          ; Emoji                # E1.0   [1] (⌨️)       keyboard
+23CF          ; Emoji                # E1.0   [1] (⏏️)       eject button
+23E9..23EC    ; Emoji                # E0.6   [4] (⏩..⏬)    fast-forward button..fast down button
+23ED..23EE    ; Emoji                # E0.7   [2] (⏭️..⏮️)    next track button..last track button
+23EF          ; Emoji                # E1.0   [1] (⏯️)       play or pause button
+23F0          ; Emoji                # E0.6   [1] (⏰)       alarm clock
+23F1..23F2    ; Emoji                # E1.0   [2] (⏱️..⏲️)    stopwatch..timer clock
+23F3          ; Emoji                # E0.6   [1] (⏳)       hourglass not done
+23F8..23FA    ; Emoji                # E0.7   [3] (⏸️..⏺️)    pause button..record button
+24C2          ; Emoji                # E0.6   [1] (Ⓜ️)       circled M
+25AA..25AB    ; Emoji                # E0.6   [2] (▪️..▫️)    black small square..white small square
+25B6          ; Emoji                # E0.6   [1] (▶️)       play button
+25C0          ; Emoji                # E0.6   [1] (◀️)       reverse button
+25FB..25FE    ; Emoji                # E0.6   [4] (◻️..◾)    white medium square..black medium-small square
+2600..2601    ; Emoji                # E0.6   [2] (☀️..☁️)    sun..cloud
+2602..2603    ; Emoji                # E0.7   [2] (☂️..☃️)    umbrella..snowman
+2604          ; Emoji                # E1.0   [1] (☄️)       comet
+260E          ; Emoji                # E0.6   [1] (☎️)       telephone
+2611          ; Emoji                # E0.6   [1] (☑️)       check box with check
+2614..2615    ; Emoji                # E0.6   [2] (☔..☕)    umbrella with rain drops..hot beverage
+2618          ; Emoji                # E1.0   [1] (☘️)       shamrock
+261D          ; Emoji                # E0.6   [1] (☝️)       index pointing up
+2620          ; Emoji                # E1.0   [1] (☠️)       skull and crossbones
+2622..2623    ; Emoji                # E1.0   [2] (☢️..☣️)    radioactive..biohazard
+2626          ; Emoji                # E1.0   [1] (☦️)       orthodox cross
+262A          ; Emoji                # E0.7   [1] (☪️)       star and crescent
+262E          ; Emoji                # E1.0   [1] (☮️)       peace symbol
+262F          ; Emoji                # E0.7   [1] (☯️)       yin yang
+2638..2639    ; Emoji                # E0.7   [2] (☸️..☹️)    wheel of dharma..frowning face
+263A          ; Emoji                # E0.6   [1] (☺️)       smiling face
+2640          ; Emoji                # E4.0   [1] (♀️)       female sign
+2642          ; Emoji                # E4.0   [1] (♂️)       male sign
+2648..2653    ; Emoji                # E0.6  [12] (♈..♓)    Aries..Pisces
+265F          ; Emoji                # E11.0  [1] (♟️)       chess pawn
+2660          ; Emoji                # E0.6   [1] (♠️)       spade suit
+2663          ; Emoji                # E0.6   [1] (♣️)       club suit
+2665..2666    ; Emoji                # E0.6   [2] (♥️..♦️)    heart suit..diamond suit
+2668          ; Emoji                # E0.6   [1] (♨️)       hot springs
+267B          ; Emoji                # E0.6   [1] (♻️)       recycling symbol
+267E          ; Emoji                # E11.0  [1] (♾️)       infinity
+267F          ; Emoji                # E0.6   [1] (♿)       wheelchair symbol
+2692          ; Emoji                # E1.0   [1] (⚒️)       hammer and pick
+2693          ; Emoji                # E0.6   [1] (⚓)       anchor
+2694          ; Emoji                # E1.0   [1] (⚔️)       crossed swords
+2695          ; Emoji                # E4.0   [1] (⚕️)       medical symbol
+2696..2697    ; Emoji                # E1.0   [2] (⚖️..⚗️)    balance scale..alembic
+2699          ; Emoji                # E1.0   [1] (⚙️)       gear
+269B..269C    ; Emoji                # E1.0   [2] (⚛️..⚜️)    atom symbol..fleur-de-lis
+26A0..26A1    ; Emoji                # E0.6   [2] (⚠️..⚡)    warning..high voltage
+26A7          ; Emoji                # E13.0  [1] (⚧️)       transgender symbol
+26AA..26AB    ; Emoji                # E0.6   [2] (⚪..⚫)    white circle..black circle
+26B0..26B1    ; Emoji                # E1.0   [2] (⚰️..⚱️)    coffin..funeral urn
+26BD..26BE    ; Emoji                # E0.6   [2] (⚽..⚾)    soccer ball..baseball
+26C4..26C5    ; Emoji                # E0.6   [2] (⛄..⛅)    snowman without snow..sun behind cloud
+26C8          ; Emoji                # E0.7   [1] (⛈️)       cloud with lightning and rain
+26CE          ; Emoji                # E0.6   [1] (⛎)       Ophiuchus
+26CF          ; Emoji                # E0.7   [1] (⛏️)       pick
+26D1          ; Emoji                # E0.7   [1] (⛑️)       rescue worker’s helmet
+26D3          ; Emoji                # E0.7   [1] (⛓️)       chains
+26D4          ; Emoji                # E0.6   [1] (⛔)       no entry
+26E9          ; Emoji                # E0.7   [1] (⛩️)       shinto shrine
+26EA          ; Emoji                # E0.6   [1] (⛪)       church
+26F0..26F1    ; Emoji                # E0.7   [2] (⛰️..⛱️)    mountain..umbrella on ground
+26F2..26F3    ; Emoji                # E0.6   [2] (⛲..⛳)    fountain..flag in hole
+26F4          ; Emoji                # E0.7   [1] (⛴️)       ferry
+26F5          ; Emoji                # E0.6   [1] (⛵)       sailboat
+26F7..26F9    ; Emoji                # E0.7   [3] (⛷️..⛹️)    skier..person bouncing ball
+26FA          ; Emoji                # E0.6   [1] (⛺)       tent
+26FD          ; Emoji                # E0.6   [1] (⛽)       fuel pump
+2702          ; Emoji                # E0.6   [1] (✂️)       scissors
+2705          ; Emoji                # E0.6   [1] (✅)       check mark button
+2708..270C    ; Emoji                # E0.6   [5] (✈️..✌️)    airplane..victory hand
+270D          ; Emoji                # E0.7   [1] (✍️)       writing hand
+270F          ; Emoji                # E0.6   [1] (✏️)       pencil
+2712          ; Emoji                # E0.6   [1] (✒️)       black nib
+2714          ; Emoji                # E0.6   [1] (✔️)       check mark
+2716          ; Emoji                # E0.6   [1] (✖️)       multiply
+271D          ; Emoji                # E0.7   [1] (✝️)       latin cross
+2721          ; Emoji                # E0.7   [1] (✡️)       star of David
+2728          ; Emoji                # E0.6   [1] (✨)       sparkles
+2733..2734    ; Emoji                # E0.6   [2] (✳️..✴️)    eight-spoked asterisk..eight-pointed star
+2744          ; Emoji                # E0.6   [1] (❄️)       snowflake
+2747          ; Emoji                # E0.6   [1] (❇️)       sparkle
+274C          ; Emoji                # E0.6   [1] (❌)       cross mark
+274E          ; Emoji                # E0.6   [1] (❎)       cross mark button
+2753..2755    ; Emoji                # E0.6   [3] (❓..❕)    question mark..white exclamation mark
+2757          ; Emoji                # E0.6   [1] (❗)       exclamation mark
+2763          ; Emoji                # E1.0   [1] (❣️)       heart exclamation
+2764          ; Emoji                # E0.6   [1] (❤️)       red heart
+2795..2797    ; Emoji                # E0.6   [3] (➕..➗)    plus..divide
+27A1          ; Emoji                # E0.6   [1] (➡️)       right arrow
+27B0          ; Emoji                # E0.6   [1] (➰)       curly loop
+27BF          ; Emoji                # E1.0   [1] (➿)       double curly loop
+2934..2935    ; Emoji                # E0.6   [2] (⤴️..⤵️)    right arrow curving up..right arrow curving down
+2B05..2B07    ; Emoji                # E0.6   [3] (⬅️..⬇️)    left arrow..down arrow
+2B1B..2B1C    ; Emoji                # E0.6   [2] (⬛..⬜)    black large square..white large square
+2B50          ; Emoji                # E0.6   [1] (⭐)       star
+2B55          ; Emoji                # E0.6   [1] (⭕)       hollow red circle
+3030          ; Emoji                # E0.6   [1] (〰️)       wavy dash
+303D          ; Emoji                # E0.6   [1] (〽️)       part alternation mark
+3297          ; Emoji                # E0.6   [1] (㊗️)       Japanese “congratulations” button
+3299          ; Emoji                # E0.6   [1] (㊙️)       Japanese “secret” button
+1F004         ; Emoji                # E0.6   [1] (🀄)       mahjong red dragon
+1F0CF         ; Emoji                # E0.6   [1] (🃏)       joker
+1F170..1F171  ; Emoji                # E0.6   [2] (🅰️..🅱️)    A button (blood type)..B button (blood type)
+1F17E..1F17F  ; Emoji                # E0.6   [2] (🅾️..🅿️)    O button (blood type)..P button
+1F18E         ; Emoji                # E0.6   [1] (🆎)       AB button (blood type)
+1F191..1F19A  ; Emoji                # E0.6  [10] (🆑..🆚)    CL button..VS button
+1F1E6..1F1FF  ; Emoji                # E0.0  [26] (🇦..🇿)    regional indicator symbol letter a..regional indicator symbol letter z
+1F201..1F202  ; Emoji                # E0.6   [2] (🈁..🈂️)    Japanese “here” button..Japanese “service charge” button
+1F21A         ; Emoji                # E0.6   [1] (🈚)       Japanese “free of charge” button
+1F22F         ; Emoji                # E0.6   [1] (🈯)       Japanese “reserved” button
+1F232..1F23A  ; Emoji                # E0.6   [9] (🈲..🈺)    Japanese “prohibited” button..Japanese “open for business” button
+1F250..1F251  ; Emoji                # E0.6   [2] (🉐..🉑)    Japanese “bargain” button..Japanese “acceptable” button
+1F300..1F30C  ; Emoji                # E0.6  [13] (🌀..🌌)    cyclone..milky way
+1F30D..1F30E  ; Emoji                # E0.7   [2] (🌍..🌎)    globe showing Europe-Africa..globe showing Americas
+1F30F         ; Emoji                # E0.6   [1] (🌏)       globe showing Asia-Australia
+1F310         ; Emoji                # E1.0   [1] (🌐)       globe with meridians
+1F311         ; Emoji                # E0.6   [1] (🌑)       new moon
+1F312         ; Emoji                # E1.0   [1] (🌒)       waxing crescent moon
+1F313..1F315  ; Emoji                # E0.6   [3] (🌓..🌕)    first quarter moon..full moon
+1F316..1F318  ; Emoji                # E1.0   [3] (🌖..🌘)    waning gibbous moon..waning crescent moon
+1F319         ; Emoji                # E0.6   [1] (🌙)       crescent moon
+1F31A         ; Emoji                # E1.0   [1] (🌚)       new moon face
+1F31B         ; Emoji                # E0.6   [1] (🌛)       first quarter moon face
+1F31C         ; Emoji                # E0.7   [1] (🌜)       last quarter moon face
+1F31D..1F31E  ; Emoji                # E1.0   [2] (🌝..🌞)    full moon face..sun with face
+1F31F..1F320  ; Emoji                # E0.6   [2] (🌟..🌠)    glowing star..shooting star
+1F321         ; Emoji                # E0.7   [1] (🌡️)       thermometer
+1F324..1F32C  ; Emoji                # E0.7   [9] (🌤️..🌬️)    sun behind small cloud..wind face
+1F32D..1F32F  ; Emoji                # E1.0   [3] (🌭..🌯)    hot dog..burrito
+1F330..1F331  ; Emoji                # E0.6   [2] (🌰..🌱)    chestnut..seedling
+1F332..1F333  ; Emoji                # E1.0   [2] (🌲..🌳)    evergreen tree..deciduous tree
+1F334..1F335  ; Emoji                # E0.6   [2] (🌴..🌵)    palm tree..cactus
+1F336         ; Emoji                # E0.7   [1] (🌶️)       hot pepper
+1F337..1F34A  ; Emoji                # E0.6  [20] (🌷..🍊)    tulip..tangerine
+1F34B         ; Emoji                # E1.0   [1] (🍋)       lemon
+1F34C..1F34F  ; Emoji                # E0.6   [4] (🍌..🍏)    banana..green apple
+1F350         ; Emoji                # E1.0   [1] (🍐)       pear
+1F351..1F37B  ; Emoji                # E0.6  [43] (🍑..🍻)    peach..clinking beer mugs
+1F37C         ; Emoji                # E1.0   [1] (🍼)       baby bottle
+1F37D         ; Emoji                # E0.7   [1] (🍽️)       fork and knife with plate
+1F37E..1F37F  ; Emoji                # E1.0   [2] (🍾..🍿)    bottle with popping cork..popcorn
+1F380..1F393  ; Emoji                # E0.6  [20] (🎀..🎓)    ribbon..graduation cap
+1F396..1F397  ; Emoji                # E0.7   [2] (🎖️..🎗️)    military medal..reminder ribbon
+1F399..1F39B  ; Emoji                # E0.7   [3] (🎙️..🎛️)    studio microphone..control knobs
+1F39E..1F39F  ; Emoji                # E0.7   [2] (🎞️..🎟️)    film frames..admission tickets
+1F3A0..1F3C4  ; Emoji                # E0.6  [37] (🎠..🏄)    carousel horse..person surfing
+1F3C5         ; Emoji                # E1.0   [1] (🏅)       sports medal
+1F3C6         ; Emoji                # E0.6   [1] (🏆)       trophy
+1F3C7         ; Emoji                # E1.0   [1] (🏇)       horse racing
+1F3C8         ; Emoji                # E0.6   [1] (🏈)       american football
+1F3C9         ; Emoji                # E1.0   [1] (🏉)       rugby football
+1F3CA         ; Emoji                # E0.6   [1] (🏊)       person swimming
+1F3CB..1F3CE  ; Emoji                # E0.7   [4] (🏋️..🏎️)    person lifting weights..racing car
+1F3CF..1F3D3  ; Emoji                # E1.0   [5] (🏏..🏓)    cricket game..ping pong
+1F3D4..1F3DF  ; Emoji                # E0.7  [12] (🏔️..🏟️)    snow-capped mountain..stadium
+1F3E0..1F3E3  ; Emoji                # E0.6   [4] (🏠..🏣)    house..Japanese post office
+1F3E4         ; Emoji                # E1.0   [1] (🏤)       post office
+1F3E5..1F3F0  ; Emoji                # E0.6  [12] (🏥..🏰)    hospital..castle
+1F3F3         ; Emoji                # E0.7   [1] (🏳️)       white flag
+1F3F4         ; Emoji                # E1.0   [1] (🏴)       black flag
+1F3F5         ; Emoji                # E0.7   [1] (🏵️)       rosette
+1F3F7         ; Emoji                # E0.7   [1] (🏷️)       label
+1F3F8..1F407  ; Emoji                # E1.0  [16] (🏸..🐇)    badminton..rabbit
+1F408         ; Emoji                # E0.7   [1] (🐈)       cat
+1F409..1F40B  ; Emoji                # E1.0   [3] (🐉..🐋)    dragon..whale
+1F40C..1F40E  ; Emoji                # E0.6   [3] (🐌..🐎)    snail..horse
+1F40F..1F410  ; Emoji                # E1.0   [2] (🐏..🐐)    ram..goat
+1F411..1F412  ; Emoji                # E0.6   [2] (🐑..🐒)    ewe..monkey
+1F413         ; Emoji                # E1.0   [1] (🐓)       rooster
+1F414         ; Emoji                # E0.6   [1] (🐔)       chicken
+1F415         ; Emoji                # E0.7   [1] (🐕)       dog
+1F416         ; Emoji                # E1.0   [1] (🐖)       pig
+1F417..1F429  ; Emoji                # E0.6  [19] (🐗..🐩)    boar..poodle
+1F42A         ; Emoji                # E1.0   [1] (🐪)       camel
+1F42B..1F43E  ; Emoji                # E0.6  [20] (🐫..🐾)    two-hump camel..paw prints
+1F43F         ; Emoji                # E0.7   [1] (🐿️)       chipmunk
+1F440         ; Emoji                # E0.6   [1] (👀)       eyes
+1F441         ; Emoji                # E0.7   [1] (👁️)       eye
+1F442..1F464  ; Emoji                # E0.6  [35] (👂..👤)    ear..bust in silhouette
+1F465         ; Emoji                # E1.0   [1] (👥)       busts in silhouette
+1F466..1F46B  ; Emoji                # E0.6   [6] (👦..👫)    boy..woman and man holding hands
+1F46C..1F46D  ; Emoji                # E1.0   [2] (👬..👭)    men holding hands..women holding hands
+1F46E..1F4AC  ; Emoji                # E0.6  [63] (👮..💬)    police officer..speech balloon
+1F4AD         ; Emoji                # E1.0   [1] (💭)       thought balloon
+1F4AE..1F4B5  ; Emoji                # E0.6   [8] (💮..💵)    white flower..dollar banknote
+1F4B6..1F4B7  ; Emoji                # E1.0   [2] (💶..💷)    euro banknote..pound banknote
+1F4B8..1F4EB  ; Emoji                # E0.6  [52] (💸..📫)    money with wings..closed mailbox with raised flag
+1F4EC..1F4ED  ; Emoji                # E0.7   [2] (📬..📭)    open mailbox with raised flag..open mailbox with lowered flag
+1F4EE         ; Emoji                # E0.6   [1] (📮)       postbox
+1F4EF         ; Emoji                # E1.0   [1] (📯)       postal horn
+1F4F0..1F4F4  ; Emoji                # E0.6   [5] (📰..📴)    newspaper..mobile phone off
+1F4F5         ; Emoji                # E1.0   [1] (📵)       no mobile phones
+1F4F6..1F4F7  ; Emoji                # E0.6   [2] (📶..📷)    antenna bars..camera
+1F4F8         ; Emoji                # E1.0   [1] (📸)       camera with flash
+1F4F9..1F4FC  ; Emoji                # E0.6   [4] (📹..📼)    video camera..videocassette
+1F4FD         ; Emoji                # E0.7   [1] (📽️)       film projector
+1F4FF..1F502  ; Emoji                # E1.0   [4] (📿..🔂)    prayer beads..repeat single button
+1F503         ; Emoji                # E0.6   [1] (🔃)       clockwise vertical arrows
+1F504..1F507  ; Emoji                # E1.0   [4] (🔄..🔇)    counterclockwise arrows button..muted speaker
+1F508         ; Emoji                # E0.7   [1] (🔈)       speaker low volume
+1F509         ; Emoji                # E1.0   [1] (🔉)       speaker medium volume
+1F50A..1F514  ; Emoji                # E0.6  [11] (🔊..🔔)    speaker high volume..bell
+1F515         ; Emoji                # E1.0   [1] (🔕)       bell with slash
+1F516..1F52B  ; Emoji                # E0.6  [22] (🔖..🔫)    bookmark..pistol
+1F52C..1F52D  ; Emoji                # E1.0   [2] (🔬..🔭)    microscope..telescope
+1F52E..1F53D  ; Emoji                # E0.6  [16] (🔮..🔽)    crystal ball..downwards button
+1F549..1F54A  ; Emoji                # E0.7   [2] (🕉️..🕊️)    om..dove
+1F54B..1F54E  ; Emoji                # E1.0   [4] (🕋..🕎)    kaaba..menorah
+1F550..1F55B  ; Emoji                # E0.6  [12] (🕐..🕛)    one o’clock..twelve o’clock
+1F55C..1F567  ; Emoji                # E0.7  [12] (🕜..🕧)    one-thirty..twelve-thirty
+1F56F..1F570  ; Emoji                # E0.7   [2] (🕯️..🕰️)    candle..mantelpiece clock
+1F573..1F579  ; Emoji                # E0.7   [7] (🕳️..🕹️)    hole..joystick
+1F57A         ; Emoji                # E3.0   [1] (🕺)       man dancing
+1F587         ; Emoji                # E0.7   [1] (🖇️)       linked paperclips
+1F58A..1F58D  ; Emoji                # E0.7   [4] (🖊️..🖍️)    pen..crayon
+1F590         ; Emoji                # E0.7   [1] (🖐️)       hand with fingers splayed
+1F595..1F596  ; Emoji                # E1.0   [2] (🖕..🖖)    middle finger..vulcan salute
+1F5A4         ; Emoji                # E3.0   [1] (🖤)       black heart
+1F5A5         ; Emoji                # E0.7   [1] (🖥️)       desktop computer
+1F5A8         ; Emoji                # E0.7   [1] (🖨️)       printer
+1F5B1..1F5B2  ; Emoji                # E0.7   [2] (🖱️..🖲️)    computer mouse..trackball
+1F5BC         ; Emoji                # E0.7   [1] (🖼️)       framed picture
+1F5C2..1F5C4  ; Emoji                # E0.7   [3] (🗂️..🗄️)    card index dividers..file cabinet
+1F5D1..1F5D3  ; Emoji                # E0.7   [3] (🗑️..🗓️)    wastebasket..spiral calendar
+1F5DC..1F5DE  ; Emoji                # E0.7   [3] (🗜️..🗞️)    clamp..rolled-up newspaper
+1F5E1         ; Emoji                # E0.7   [1] (🗡️)       dagger
+1F5E3         ; Emoji                # E0.7   [1] (🗣️)       speaking head
+1F5E8         ; Emoji                # E2.0   [1] (🗨️)       left speech bubble
+1F5EF         ; Emoji                # E0.7   [1] (🗯️)       right anger bubble
+1F5F3         ; Emoji                # E0.7   [1] (🗳️)       ballot box with ballot
+1F5FA         ; Emoji                # E0.7   [1] (🗺️)       world map
+1F5FB..1F5FF  ; Emoji                # E0.6   [5] (🗻..🗿)    mount fuji..moai
+1F600         ; Emoji                # E1.0   [1] (😀)       grinning face
+1F601..1F606  ; Emoji                # E0.6   [6] (😁..😆)    beaming face with smiling eyes..grinning squinting face
+1F607..1F608  ; Emoji                # E1.0   [2] (😇..😈)    smiling face with halo..smiling face with horns
+1F609..1F60D  ; Emoji                # E0.6   [5] (😉..😍)    winking face..smiling face with heart-eyes
+1F60E         ; Emoji                # E1.0   [1] (😎)       smiling face with sunglasses
+1F60F         ; Emoji                # E0.6   [1] (😏)       smirking face
+1F610         ; Emoji                # E0.7   [1] (😐)       neutral face
+1F611         ; Emoji                # E1.0   [1] (😑)       expressionless face
+1F612..1F614  ; Emoji                # E0.6   [3] (😒..😔)    unamused face..pensive face
+1F615         ; Emoji                # E1.0   [1] (😕)       confused face
+1F616         ; Emoji                # E0.6   [1] (😖)       confounded face
+1F617         ; Emoji                # E1.0   [1] (😗)       kissing face
+1F618         ; Emoji                # E0.6   [1] (😘)       face blowing a kiss
+1F619         ; Emoji                # E1.0   [1] (😙)       kissing face with smiling eyes
+1F61A         ; Emoji                # E0.6   [1] (😚)       kissing face with closed eyes
+1F61B         ; Emoji                # E1.0   [1] (😛)       face with tongue
+1F61C..1F61E  ; Emoji                # E0.6   [3] (😜..😞)    winking face with tongue..disappointed face
+1F61F         ; Emoji                # E1.0   [1] (😟)       worried face
+1F620..1F625  ; Emoji                # E0.6   [6] (😠..😥)    angry face..sad but relieved face
+1F626..1F627  ; Emoji                # E1.0   [2] (😦..😧)    frowning face with open mouth..anguished face
+1F628..1F62B  ; Emoji                # E0.6   [4] (😨..😫)    fearful face..tired face
+1F62C         ; Emoji                # E1.0   [1] (😬)       grimacing face
+1F62D         ; Emoji                # E0.6   [1] (😭)       loudly crying face
+1F62E..1F62F  ; Emoji                # E1.0   [2] (😮..😯)    face with open mouth..hushed face
+1F630..1F633  ; Emoji                # E0.6   [4] (😰..😳)    anxious face with sweat..flushed face
+1F634         ; Emoji                # E1.0   [1] (😴)       sleeping face
+1F635         ; Emoji                # E0.6   [1] (😵)       dizzy face
+1F636         ; Emoji                # E1.0   [1] (😶)       face without mouth
+1F637..1F640  ; Emoji                # E0.6  [10] (😷..🙀)    face with medical mask..weary cat
+1F641..1F644  ; Emoji                # E1.0   [4] (🙁..🙄)    slightly frowning face..face with rolling eyes
+1F645..1F64F  ; Emoji                # E0.6  [11] (🙅..🙏)    person gesturing NO..folded hands
+1F680         ; Emoji                # E0.6   [1] (🚀)       rocket
+1F681..1F682  ; Emoji                # E1.0   [2] (🚁..🚂)    helicopter..locomotive
+1F683..1F685  ; Emoji                # E0.6   [3] (🚃..🚅)    railway car..bullet train
+1F686         ; Emoji                # E1.0   [1] (🚆)       train
+1F687         ; Emoji                # E0.6   [1] (🚇)       metro
+1F688         ; Emoji                # E1.0   [1] (🚈)       light rail
+1F689         ; Emoji                # E0.6   [1] (🚉)       station
+1F68A..1F68B  ; Emoji                # E1.0   [2] (🚊..🚋)    tram..tram car
+1F68C         ; Emoji                # E0.6   [1] (🚌)       bus
+1F68D         ; Emoji                # E0.7   [1] (🚍)       oncoming bus
+1F68E         ; Emoji                # E1.0   [1] (🚎)       trolleybus
+1F68F         ; Emoji                # E0.6   [1] (🚏)       bus stop
+1F690         ; Emoji                # E1.0   [1] (🚐)       minibus
+1F691..1F693  ; Emoji                # E0.6   [3] (🚑..🚓)    ambulance..police car
+1F694         ; Emoji                # E0.7   [1] (🚔)       oncoming police car
+1F695         ; Emoji                # E0.6   [1] (🚕)       taxi
+1F696         ; Emoji                # E1.0   [1] (🚖)       oncoming taxi
+1F697         ; Emoji                # E0.6   [1] (🚗)       automobile
+1F698         ; Emoji                # E0.7   [1] (🚘)       oncoming automobile
+1F699..1F69A  ; Emoji                # E0.6   [2] (🚙..🚚)    sport utility vehicle..delivery truck
+1F69B..1F6A1  ; Emoji                # E1.0   [7] (🚛..🚡)    articulated lorry..aerial tramway
+1F6A2         ; Emoji                # E0.6   [1] (🚢)       ship
+1F6A3         ; Emoji                # E1.0   [1] (🚣)       person rowing boat
+1F6A4..1F6A5  ; Emoji                # E0.6   [2] (🚤..🚥)    speedboat..horizontal traffic light
+1F6A6         ; Emoji                # E1.0   [1] (🚦)       vertical traffic light
+1F6A7..1F6AD  ; Emoji                # E0.6   [7] (🚧..🚭)    construction..no smoking
+1F6AE..1F6B1  ; Emoji                # E1.0   [4] (🚮..🚱)    litter in bin sign..non-potable water
+1F6B2         ; Emoji                # E0.6   [1] (🚲)       bicycle
+1F6B3..1F6B5  ; Emoji                # E1.0   [3] (🚳..🚵)    no bicycles..person mountain biking
+1F6B6         ; Emoji                # E0.6   [1] (🚶)       person walking
+1F6B7..1F6B8  ; Emoji                # E1.0   [2] (🚷..🚸)    no pedestrians..children crossing
+1F6B9..1F6BE  ; Emoji                # E0.6   [6] (🚹..🚾)    men’s room..water closet
+1F6BF         ; Emoji                # E1.0   [1] (🚿)       shower
+1F6C0         ; Emoji                # E0.6   [1] (🛀)       person taking bath
+1F6C1..1F6C5  ; Emoji                # E1.0   [5] (🛁..🛅)    bathtub..left luggage
+1F6CB         ; Emoji                # E0.7   [1] (🛋️)       couch and lamp
+1F6CC         ; Emoji                # E1.0   [1] (🛌)       person in bed
+1F6CD..1F6CF  ; Emoji                # E0.7   [3] (🛍️..🛏️)    shopping bags..bed
+1F6D0         ; Emoji                # E1.0   [1] (🛐)       place of worship
+1F6D1..1F6D2  ; Emoji                # E3.0   [2] (🛑..🛒)    stop sign..shopping cart
+1F6D5         ; Emoji                # E12.0  [1] (🛕)       hindu temple
+1F6D6..1F6D7  ; Emoji                # E13.0  [2] (🛖..🛗)    hut..elevator
+1F6E0..1F6E5  ; Emoji                # E0.7   [6] (🛠️..🛥️)    hammer and wrench..motor boat
+1F6E9         ; Emoji                # E0.7   [1] (🛩️)       small airplane
+1F6EB..1F6EC  ; Emoji                # E1.0   [2] (🛫..🛬)    airplane departure..airplane arrival
+1F6F0         ; Emoji                # E0.7   [1] (🛰️)       satellite
+1F6F3         ; Emoji                # E0.7   [1] (🛳️)       passenger ship
+1F6F4..1F6F6  ; Emoji                # E3.0   [3] (🛴..🛶)    kick scooter..canoe
+1F6F7..1F6F8  ; Emoji                # E5.0   [2] (🛷..🛸)    sled..flying saucer
+1F6F9         ; Emoji                # E11.0  [1] (🛹)       skateboard
+1F6FA         ; Emoji                # E12.0  [1] (🛺)       auto rickshaw
+1F6FB..1F6FC  ; Emoji                # E13.0  [2] (🛻..🛼)    pickup truck..roller skate
+1F7E0..1F7EB  ; Emoji                # E12.0 [12] (🟠..🟫)    orange circle..brown square
+1F90C         ; Emoji                # E13.0  [1] (🤌)       pinched fingers
+1F90D..1F90F  ; Emoji                # E12.0  [3] (🤍..🤏)    white heart..pinching hand
+1F910..1F918  ; Emoji                # E1.0   [9] (🤐..🤘)    zipper-mouth face..sign of the horns
+1F919..1F91E  ; Emoji                # E3.0   [6] (🤙..🤞)    call me hand..crossed fingers
+1F91F         ; Emoji                # E5.0   [1] (🤟)       love-you gesture
+1F920..1F927  ; Emoji                # E3.0   [8] (🤠..🤧)    cowboy hat face..sneezing face
+1F928..1F92F  ; Emoji                # E5.0   [8] (🤨..🤯)    face with raised eyebrow..exploding head
+1F930         ; Emoji                # E3.0   [1] (🤰)       pregnant woman
+1F931..1F932  ; Emoji                # E5.0   [2] (🤱..🤲)    breast-feeding..palms up together
+1F933..1F93A  ; Emoji                # E3.0   [8] (🤳..🤺)    selfie..person fencing
+1F93C..1F93E  ; Emoji                # E3.0   [3] (🤼..🤾)    people wrestling..person playing handball
+1F93F         ; Emoji                # E12.0  [1] (🤿)       diving mask
+1F940..1F945  ; Emoji                # E3.0   [6] (🥀..🥅)    wilted flower..goal net
+1F947..1F94B  ; Emoji                # E3.0   [5] (🥇..🥋)    1st place medal..martial arts uniform
+1F94C         ; Emoji                # E5.0   [1] (🥌)       curling stone
+1F94D..1F94F  ; Emoji                # E11.0  [3] (🥍..🥏)    lacrosse..flying disc
+1F950..1F95E  ; Emoji                # E3.0  [15] (🥐..🥞)    croissant..pancakes
+1F95F..1F96B  ; Emoji                # E5.0  [13] (🥟..🥫)    dumpling..canned food
+1F96C..1F970  ; Emoji                # E11.0  [5] (🥬..🥰)    leafy green..smiling face with hearts
+1F971         ; Emoji                # E12.0  [1] (🥱)       yawning face
+1F972         ; Emoji                # E13.0  [1] (🥲)       smiling face with tear
+1F973..1F976  ; Emoji                # E11.0  [4] (🥳..🥶)    partying face..cold face
+1F977..1F978  ; Emoji                # E13.0  [2] (🥷..🥸)    ninja..disguised face
+1F97A         ; Emoji                # E11.0  [1] (🥺)       pleading face
+1F97B         ; Emoji                # E12.0  [1] (🥻)       sari
+1F97C..1F97F  ; Emoji                # E11.0  [4] (🥼..🥿)    lab coat..flat shoe
+1F980..1F984  ; Emoji                # E1.0   [5] (🦀..🦄)    crab..unicorn
+1F985..1F991  ; Emoji                # E3.0  [13] (🦅..🦑)    eagle..squid
+1F992..1F997  ; Emoji                # E5.0   [6] (🦒..🦗)    giraffe..cricket
+1F998..1F9A2  ; Emoji                # E11.0 [11] (🦘..🦢)    kangaroo..swan
+1F9A3..1F9A4  ; Emoji                # E13.0  [2] (🦣..🦤)    mammoth..dodo
+1F9A5..1F9AA  ; Emoji                # E12.0  [6] (🦥..🦪)    sloth..oyster
+1F9AB..1F9AD  ; Emoji                # E13.0  [3] (🦫..🦭)    beaver..seal
+1F9AE..1F9AF  ; Emoji                # E12.0  [2] (🦮..🦯)    guide dog..white cane
+1F9B0..1F9B9  ; Emoji                # E11.0 [10] (🦰..🦹)    red hair..supervillain
+1F9BA..1F9BF  ; Emoji                # E12.0  [6] (🦺..🦿)    safety vest..mechanical leg
+1F9C0         ; Emoji                # E1.0   [1] (🧀)       cheese wedge
+1F9C1..1F9C2  ; Emoji                # E11.0  [2] (🧁..🧂)    cupcake..salt
+1F9C3..1F9CA  ; Emoji                # E12.0  [8] (🧃..🧊)    beverage box..ice
+1F9CB         ; Emoji                # E13.0  [1] (🧋)       bubble tea
+1F9CD..1F9CF  ; Emoji                # E12.0  [3] (🧍..🧏)    person standing..deaf person
+1F9D0..1F9E6  ; Emoji                # E5.0  [23] (🧐..🧦)    face with monocle..socks
+1F9E7..1F9FF  ; Emoji                # E11.0 [25] (🧧..🧿)    red envelope..nazar amulet
+1FA70..1FA73  ; Emoji                # E12.0  [4] (🩰..🩳)    ballet shoes..shorts
+1FA74         ; Emoji                # E13.0  [1] (🩴)       thong sandal
+1FA78..1FA7A  ; Emoji                # E12.0  [3] (🩸..🩺)    drop of blood..stethoscope
+1FA80..1FA82  ; Emoji                # E12.0  [3] (🪀..🪂)    yo-yo..parachute
+1FA83..1FA86  ; Emoji                # E13.0  [4] (🪃..🪆)    boomerang..nesting dolls
+1FA90..1FA95  ; Emoji                # E12.0  [6] (🪐..🪕)    ringed planet..banjo
+1FA96..1FAA8  ; Emoji                # E13.0 [19] (🪖..🪨)    military helmet..rock
+1FAB0..1FAB6  ; Emoji                # E13.0  [7] (🪰..🪶)    fly..feather
+1FAC0..1FAC2  ; Emoji                # E13.0  [3] (🫀..🫂)    anatomical heart..people hugging
+1FAD0..1FAD6  ; Emoji                # E13.0  [7] (🫐..🫖)    blueberries..teapot
+
+# Total elements: 1367
+
+# ================================================
+
+# All omitted code points have Emoji_Presentation=No 
+# @missing: 0000..10FFFF  ; Emoji_Presentation ; No
+
+231A..231B    ; Emoji_Presentation   # E0.6   [2] (⌚..⌛)    watch..hourglass done
+23E9..23EC    ; Emoji_Presentation   # E0.6   [4] (⏩..⏬)    fast-forward button..fast down button
+23F0          ; Emoji_Presentation   # E0.6   [1] (⏰)       alarm clock
+23F3          ; Emoji_Presentation   # E0.6   [1] (⏳)       hourglass not done
+25FD..25FE    ; Emoji_Presentation   # E0.6   [2] (◽..◾)    white medium-small square..black medium-small square
+2614..2615    ; Emoji_Presentation   # E0.6   [2] (☔..☕)    umbrella with rain drops..hot beverage
+2648..2653    ; Emoji_Presentation   # E0.6  [12] (♈..♓)    Aries..Pisces
+267F          ; Emoji_Presentation   # E0.6   [1] (♿)       wheelchair symbol
+2693          ; Emoji_Presentation   # E0.6   [1] (⚓)       anchor
+26A1          ; Emoji_Presentation   # E0.6   [1] (⚡)       high voltage
+26AA..26AB    ; Emoji_Presentation   # E0.6   [2] (⚪..⚫)    white circle..black circle
+26BD..26BE    ; Emoji_Presentation   # E0.6   [2] (⚽..⚾)    soccer ball..baseball
+26C4..26C5    ; Emoji_Presentation   # E0.6   [2] (⛄..⛅)    snowman without snow..sun behind cloud
+26CE          ; Emoji_Presentation   # E0.6   [1] (⛎)       Ophiuchus
+26D4          ; Emoji_Presentation   # E0.6   [1] (⛔)       no entry
+26EA          ; Emoji_Presentation   # E0.6   [1] (⛪)       church
+26F2..26F3    ; Emoji_Presentation   # E0.6   [2] (⛲..⛳)    fountain..flag in hole
+26F5          ; Emoji_Presentation   # E0.6   [1] (⛵)       sailboat
+26FA          ; Emoji_Presentation   # E0.6   [1] (⛺)       tent
+26FD          ; Emoji_Presentation   # E0.6   [1] (⛽)       fuel pump
+2705          ; Emoji_Presentation   # E0.6   [1] (✅)       check mark button
+270A..270B    ; Emoji_Presentation   # E0.6   [2] (✊..✋)    raised fist..raised hand
+2728          ; Emoji_Presentation   # E0.6   [1] (✨)       sparkles
+274C          ; Emoji_Presentation   # E0.6   [1] (❌)       cross mark
+274E          ; Emoji_Presentation   # E0.6   [1] (❎)       cross mark button
+2753..2755    ; Emoji_Presentation   # E0.6   [3] (❓..❕)    question mark..white exclamation mark
+2757          ; Emoji_Presentation   # E0.6   [1] (❗)       exclamation mark
+2795..2797    ; Emoji_Presentation   # E0.6   [3] (➕..➗)    plus..divide
+27B0          ; Emoji_Presentation   # E0.6   [1] (➰)       curly loop
+27BF          ; Emoji_Presentation   # E1.0   [1] (➿)       double curly loop
+2B1B..2B1C    ; Emoji_Presentation   # E0.6   [2] (⬛..⬜)    black large square..white large square
+2B50          ; Emoji_Presentation   # E0.6   [1] (⭐)       star
+2B55          ; Emoji_Presentation   # E0.6   [1] (⭕)       hollow red circle
+1F004         ; Emoji_Presentation   # E0.6   [1] (🀄)       mahjong red dragon
+1F0CF         ; Emoji_Presentation   # E0.6   [1] (🃏)       joker
+1F18E         ; Emoji_Presentation   # E0.6   [1] (🆎)       AB button (blood type)
+1F191..1F19A  ; Emoji_Presentation   # E0.6  [10] (🆑..🆚)    CL button..VS button
+1F1E6..1F1FF  ; Emoji_Presentation   # E0.0  [26] (🇦..🇿)    regional indicator symbol letter a..regional indicator symbol letter z
+1F201         ; Emoji_Presentation   # E0.6   [1] (🈁)       Japanese “here” button
+1F21A         ; Emoji_Presentation   # E0.6   [1] (🈚)       Japanese “free of charge” button
+1F22F         ; Emoji_Presentation   # E0.6   [1] (🈯)       Japanese “reserved” button
+1F232..1F236  ; Emoji_Presentation   # E0.6   [5] (🈲..🈶)    Japanese “prohibited” button..Japanese “not free of charge” button
+1F238..1F23A  ; Emoji_Presentation   # E0.6   [3] (🈸..🈺)    Japanese “application” button..Japanese “open for business” button
+1F250..1F251  ; Emoji_Presentation   # E0.6   [2] (🉐..🉑)    Japanese “bargain” button..Japanese “acceptable” button
+1F300..1F30C  ; Emoji_Presentation   # E0.6  [13] (🌀..🌌)    cyclone..milky way
+1F30D..1F30E  ; Emoji_Presentation   # E0.7   [2] (🌍..🌎)    globe showing Europe-Africa..globe showing Americas
+1F30F         ; Emoji_Presentation   # E0.6   [1] (🌏)       globe showing Asia-Australia
+1F310         ; Emoji_Presentation   # E1.0   [1] (🌐)       globe with meridians
+1F311         ; Emoji_Presentation   # E0.6   [1] (🌑)       new moon
+1F312         ; Emoji_Presentation   # E1.0   [1] (🌒)       waxing crescent moon
+1F313..1F315  ; Emoji_Presentation   # E0.6   [3] (🌓..🌕)    first quarter moon..full moon
+1F316..1F318  ; Emoji_Presentation   # E1.0   [3] (🌖..🌘)    waning gibbous moon..waning crescent moon
+1F319         ; Emoji_Presentation   # E0.6   [1] (🌙)       crescent moon
+1F31A         ; Emoji_Presentation   # E1.0   [1] (🌚)       new moon face
+1F31B         ; Emoji_Presentation   # E0.6   [1] (🌛)       first quarter moon face
+1F31C         ; Emoji_Presentation   # E0.7   [1] (🌜)       last quarter moon face
+1F31D..1F31E  ; Emoji_Presentation   # E1.0   [2] (🌝..🌞)    full moon face..sun with face
+1F31F..1F320  ; Emoji_Presentation   # E0.6   [2] (🌟..🌠)    glowing star..shooting star
+1F32D..1F32F  ; Emoji_Presentation   # E1.0   [3] (🌭..🌯)    hot dog..burrito
+1F330..1F331  ; Emoji_Presentation   # E0.6   [2] (🌰..🌱)    chestnut..seedling
+1F332..1F333  ; Emoji_Presentation   # E1.0   [2] (🌲..🌳)    evergreen tree..deciduous tree
+1F334..1F335  ; Emoji_Presentation   # E0.6   [2] (🌴..🌵)    palm tree..cactus
+1F337..1F34A  ; Emoji_Presentation   # E0.6  [20] (🌷..🍊)    tulip..tangerine
+1F34B         ; Emoji_Presentation   # E1.0   [1] (🍋)       lemon
+1F34C..1F34F  ; Emoji_Presentation   # E0.6   [4] (🍌..🍏)    banana..green apple
+1F350         ; Emoji_Presentation   # E1.0   [1] (🍐)       pear
+1F351..1F37B  ; Emoji_Presentation   # E0.6  [43] (🍑..🍻)    peach..clinking beer mugs
+1F37C         ; Emoji_Presentation   # E1.0   [1] (🍼)       baby bottle
+1F37E..1F37F  ; Emoji_Presentation   # E1.0   [2] (🍾..🍿)    bottle with popping cork..popcorn
+1F380..1F393  ; Emoji_Presentation   # E0.6  [20] (🎀..🎓)    ribbon..graduation cap
+1F3A0..1F3C4  ; Emoji_Presentation   # E0.6  [37] (🎠..🏄)    carousel horse..person surfing
+1F3C5         ; Emoji_Presentation   # E1.0   [1] (🏅)       sports medal
+1F3C6         ; Emoji_Presentation   # E0.6   [1] (🏆)       trophy
+1F3C7         ; Emoji_Presentation   # E1.0   [1] (🏇)       horse racing
+1F3C8         ; Emoji_Presentation   # E0.6   [1] (🏈)       american football
+1F3C9         ; Emoji_Presentation   # E1.0   [1] (🏉)       rugby football
+1F3CA         ; Emoji_Presentation   # E0.6   [1] (🏊)       person swimming
+1F3CF..1F3D3  ; Emoji_Presentation   # E1.0   [5] (🏏..🏓)    cricket game..ping pong
+1F3E0..1F3E3  ; Emoji_Presentation   # E0.6   [4] (🏠..🏣)    house..Japanese post office
+1F3E4         ; Emoji_Presentation   # E1.0   [1] (🏤)       post office
+1F3E5..1F3F0  ; Emoji_Presentation   # E0.6  [12] (🏥..🏰)    hospital..castle
+1F3F4         ; Emoji_Presentation   # E1.0   [1] (🏴)       black flag
+1F3F8..1F407  ; Emoji_Presentation   # E1.0  [16] (🏸..🐇)    badminton..rabbit
+1F408         ; Emoji_Presentation   # E0.7   [1] (🐈)       cat
+1F409..1F40B  ; Emoji_Presentation   # E1.0   [3] (🐉..🐋)    dragon..whale
+1F40C..1F40E  ; Emoji_Presentation   # E0.6   [3] (🐌..🐎)    snail..horse
+1F40F..1F410  ; Emoji_Presentation   # E1.0   [2] (🐏..🐐)    ram..goat
+1F411..1F412  ; Emoji_Presentation   # E0.6   [2] (🐑..🐒)    ewe..monkey
+1F413         ; Emoji_Presentation   # E1.0   [1] (🐓)       rooster
+1F414         ; Emoji_Presentation   # E0.6   [1] (🐔)       chicken
+1F415         ; Emoji_Presentation   # E0.7   [1] (🐕)       dog
+1F416         ; Emoji_Presentation   # E1.0   [1] (🐖)       pig
+1F417..1F429  ; Emoji_Presentation   # E0.6  [19] (🐗..🐩)    boar..poodle
+1F42A         ; Emoji_Presentation   # E1.0   [1] (🐪)       camel
+1F42B..1F43E  ; Emoji_Presentation   # E0.6  [20] (🐫..🐾)    two-hump camel..paw prints
+1F440         ; Emoji_Presentation   # E0.6   [1] (👀)       eyes
+1F442..1F464  ; Emoji_Presentation   # E0.6  [35] (👂..👤)    ear..bust in silhouette
+1F465         ; Emoji_Presentation   # E1.0   [1] (👥)       busts in silhouette
+1F466..1F46B  ; Emoji_Presentation   # E0.6   [6] (👦..👫)    boy..woman and man holding hands
+1F46C..1F46D  ; Emoji_Presentation   # E1.0   [2] (👬..👭)    men holding hands..women holding hands
+1F46E..1F4AC  ; Emoji_Presentation   # E0.6  [63] (👮..💬)    police officer..speech balloon
+1F4AD         ; Emoji_Presentation   # E1.0   [1] (💭)       thought balloon
+1F4AE..1F4B5  ; Emoji_Presentation   # E0.6   [8] (💮..💵)    white flower..dollar banknote
+1F4B6..1F4B7  ; Emoji_Presentation   # E1.0   [2] (💶..💷)    euro banknote..pound banknote
+1F4B8..1F4EB  ; Emoji_Presentation   # E0.6  [52] (💸..📫)    money with wings..closed mailbox with raised flag
+1F4EC..1F4ED  ; Emoji_Presentation   # E0.7   [2] (📬..📭)    open mailbox with raised flag..open mailbox with lowered flag
+1F4EE         ; Emoji_Presentation   # E0.6   [1] (📮)       postbox
+1F4EF         ; Emoji_Presentation   # E1.0   [1] (📯)       postal horn
+1F4F0..1F4F4  ; Emoji_Presentation   # E0.6   [5] (📰..📴)    newspaper..mobile phone off
+1F4F5         ; Emoji_Presentation   # E1.0   [1] (📵)       no mobile phones
+1F4F6..1F4F7  ; Emoji_Presentation   # E0.6   [2] (📶..📷)    antenna bars..camera
+1F4F8         ; Emoji_Presentation   # E1.0   [1] (📸)       camera with flash
+1F4F9..1F4FC  ; Emoji_Presentation   # E0.6   [4] (📹..📼)    video camera..videocassette
+1F4FF..1F502  ; Emoji_Presentation   # E1.0   [4] (📿..🔂)    prayer beads..repeat single button
+1F503         ; Emoji_Presentation   # E0.6   [1] (🔃)       clockwise vertical arrows
+1F504..1F507  ; Emoji_Presentation   # E1.0   [4] (🔄..🔇)    counterclockwise arrows button..muted speaker
+1F508         ; Emoji_Presentation   # E0.7   [1] (🔈)       speaker low volume
+1F509         ; Emoji_Presentation   # E1.0   [1] (🔉)       speaker medium volume
+1F50A..1F514  ; Emoji_Presentation   # E0.6  [11] (🔊..🔔)    speaker high volume..bell
+1F515         ; Emoji_Presentation   # E1.0   [1] (🔕)       bell with slash
+1F516..1F52B  ; Emoji_Presentation   # E0.6  [22] (🔖..🔫)    bookmark..pistol
+1F52C..1F52D  ; Emoji_Presentation   # E1.0   [2] (🔬..🔭)    microscope..telescope
+1F52E..1F53D  ; Emoji_Presentation   # E0.6  [16] (🔮..🔽)    crystal ball..downwards button
+1F54B..1F54E  ; Emoji_Presentation   # E1.0   [4] (🕋..🕎)    kaaba..menorah
+1F550..1F55B  ; Emoji_Presentation   # E0.6  [12] (🕐..🕛)    one o’clock..twelve o’clock
+1F55C..1F567  ; Emoji_Presentation   # E0.7  [12] (🕜..🕧)    one-thirty..twelve-thirty
+1F57A         ; Emoji_Presentation   # E3.0   [1] (🕺)       man dancing
+1F595..1F596  ; Emoji_Presentation   # E1.0   [2] (🖕..🖖)    middle finger..vulcan salute
+1F5A4         ; Emoji_Presentation   # E3.0   [1] (🖤)       black heart
+1F5FB..1F5FF  ; Emoji_Presentation   # E0.6   [5] (🗻..🗿)    mount fuji..moai
+1F600         ; Emoji_Presentation   # E1.0   [1] (😀)       grinning face
+1F601..1F606  ; Emoji_Presentation   # E0.6   [6] (😁..😆)    beaming face with smiling eyes..grinning squinting face
+1F607..1F608  ; Emoji_Presentation   # E1.0   [2] (😇..😈)    smiling face with halo..smiling face with horns
+1F609..1F60D  ; Emoji_Presentation   # E0.6   [5] (😉..😍)    winking face..smiling face with heart-eyes
+1F60E         ; Emoji_Presentation   # E1.0   [1] (😎)       smiling face with sunglasses
+1F60F         ; Emoji_Presentation   # E0.6   [1] (😏)       smirking face
+1F610         ; Emoji_Presentation   # E0.7   [1] (😐)       neutral face
+1F611         ; Emoji_Presentation   # E1.0   [1] (😑)       expressionless face
+1F612..1F614  ; Emoji_Presentation   # E0.6   [3] (😒..😔)    unamused face..pensive face
+1F615         ; Emoji_Presentation   # E1.0   [1] (😕)       confused face
+1F616         ; Emoji_Presentation   # E0.6   [1] (😖)       confounded face
+1F617         ; Emoji_Presentation   # E1.0   [1] (😗)       kissing face
+1F618         ; Emoji_Presentation   # E0.6   [1] (😘)       face blowing a kiss
+1F619         ; Emoji_Presentation   # E1.0   [1] (😙)       kissing face with smiling eyes
+1F61A         ; Emoji_Presentation   # E0.6   [1] (😚)       kissing face with closed eyes
+1F61B         ; Emoji_Presentation   # E1.0   [1] (😛)       face with tongue
+1F61C..1F61E  ; Emoji_Presentation   # E0.6   [3] (😜..😞)    winking face with tongue..disappointed face
+1F61F         ; Emoji_Presentation   # E1.0   [1] (😟)       worried face
+1F620..1F625  ; Emoji_Presentation   # E0.6   [6] (😠..😥)    angry face..sad but relieved face
+1F626..1F627  ; Emoji_Presentation   # E1.0   [2] (😦..😧)    frowning face with open mouth..anguished face
+1F628..1F62B  ; Emoji_Presentation   # E0.6   [4] (😨..😫)    fearful face..tired face
+1F62C         ; Emoji_Presentation   # E1.0   [1] (😬)       grimacing face
+1F62D         ; Emoji_Presentation   # E0.6   [1] (😭)       loudly crying face
+1F62E..1F62F  ; Emoji_Presentation   # E1.0   [2] (😮..😯)    face with open mouth..hushed face
+1F630..1F633  ; Emoji_Presentation   # E0.6   [4] (😰..😳)    anxious face with sweat..flushed face
+1F634         ; Emoji_Presentation   # E1.0   [1] (😴)       sleeping face
+1F635         ; Emoji_Presentation   # E0.6   [1] (😵)       dizzy face
+1F636         ; Emoji_Presentation   # E1.0   [1] (😶)       face without mouth
+1F637..1F640  ; Emoji_Presentation   # E0.6  [10] (😷..🙀)    face with medical mask..weary cat
+1F641..1F644  ; Emoji_Presentation   # E1.0   [4] (🙁..🙄)    slightly frowning face..face with rolling eyes
+1F645..1F64F  ; Emoji_Presentation   # E0.6  [11] (🙅..🙏)    person gesturing NO..folded hands
+1F680         ; Emoji_Presentation   # E0.6   [1] (🚀)       rocket
+1F681..1F682  ; Emoji_Presentation   # E1.0   [2] (🚁..🚂)    helicopter..locomotive
+1F683..1F685  ; Emoji_Presentation   # E0.6   [3] (🚃..🚅)    railway car..bullet train
+1F686         ; Emoji_Presentation   # E1.0   [1] (🚆)       train
+1F687         ; Emoji_Presentation   # E0.6   [1] (🚇)       metro
+1F688         ; Emoji_Presentation   # E1.0   [1] (🚈)       light rail
+1F689         ; Emoji_Presentation   # E0.6   [1] (🚉)       station
+1F68A..1F68B  ; Emoji_Presentation   # E1.0   [2] (🚊..🚋)    tram..tram car
+1F68C         ; Emoji_Presentation   # E0.6   [1] (🚌)       bus
+1F68D         ; Emoji_Presentation   # E0.7   [1] (🚍)       oncoming bus
+1F68E         ; Emoji_Presentation   # E1.0   [1] (🚎)       trolleybus
+1F68F         ; Emoji_Presentation   # E0.6   [1] (🚏)       bus stop
+1F690         ; Emoji_Presentation   # E1.0   [1] (🚐)       minibus
+1F691..1F693  ; Emoji_Presentation   # E0.6   [3] (🚑..🚓)    ambulance..police car
+1F694         ; Emoji_Presentation   # E0.7   [1] (🚔)       oncoming police car
+1F695         ; Emoji_Presentation   # E0.6   [1] (🚕)       taxi
+1F696         ; Emoji_Presentation   # E1.0   [1] (🚖)       oncoming taxi
+1F697         ; Emoji_Presentation   # E0.6   [1] (🚗)       automobile
+1F698         ; Emoji_Presentation   # E0.7   [1] (🚘)       oncoming automobile
+1F699..1F69A  ; Emoji_Presentation   # E0.6   [2] (🚙..🚚)    sport utility vehicle..delivery truck
+1F69B..1F6A1  ; Emoji_Presentation   # E1.0   [7] (🚛..🚡)    articulated lorry..aerial tramway
+1F6A2         ; Emoji_Presentation   # E0.6   [1] (🚢)       ship
+1F6A3         ; Emoji_Presentation   # E1.0   [1] (🚣)       person rowing boat
+1F6A4..1F6A5  ; Emoji_Presentation   # E0.6   [2] (🚤..🚥)    speedboat..horizontal traffic light
+1F6A6         ; Emoji_Presentation   # E1.0   [1] (🚦)       vertical traffic light
+1F6A7..1F6AD  ; Emoji_Presentation   # E0.6   [7] (🚧..🚭)    construction..no smoking
+1F6AE..1F6B1  ; Emoji_Presentation   # E1.0   [4] (🚮..🚱)    litter in bin sign..non-potable water
+1F6B2         ; Emoji_Presentation   # E0.6   [1] (🚲)       bicycle
+1F6B3..1F6B5  ; Emoji_Presentation   # E1.0   [3] (🚳..🚵)    no bicycles..person mountain biking
+1F6B6         ; Emoji_Presentation   # E0.6   [1] (🚶)       person walking
+1F6B7..1F6B8  ; Emoji_Presentation   # E1.0   [2] (🚷..🚸)    no pedestrians..children crossing
+1F6B9..1F6BE  ; Emoji_Presentation   # E0.6   [6] (🚹..🚾)    men’s room..water closet
+1F6BF         ; Emoji_Presentation   # E1.0   [1] (🚿)       shower
+1F6C0         ; Emoji_Presentation   # E0.6   [1] (🛀)       person taking bath
+1F6C1..1F6C5  ; Emoji_Presentation   # E1.0   [5] (🛁..🛅)    bathtub..left luggage
+1F6CC         ; Emoji_Presentation   # E1.0   [1] (🛌)       person in bed
+1F6D0         ; Emoji_Presentation   # E1.0   [1] (🛐)       place of worship
+1F6D1..1F6D2  ; Emoji_Presentation   # E3.0   [2] (🛑..🛒)    stop sign..shopping cart
+1F6D5         ; Emoji_Presentation   # E12.0  [1] (🛕)       hindu temple
+1F6D6..1F6D7  ; Emoji_Presentation   # E13.0  [2] (🛖..🛗)    hut..elevator
+1F6EB..1F6EC  ; Emoji_Presentation   # E1.0   [2] (🛫..🛬)    airplane departure..airplane arrival
+1F6F4..1F6F6  ; Emoji_Presentation   # E3.0   [3] (🛴..🛶)    kick scooter..canoe
+1F6F7..1F6F8  ; Emoji_Presentation   # E5.0   [2] (🛷..🛸)    sled..flying saucer
+1F6F9         ; Emoji_Presentation   # E11.0  [1] (🛹)       skateboard
+1F6FA         ; Emoji_Presentation   # E12.0  [1] (🛺)       auto rickshaw
+1F6FB..1F6FC  ; Emoji_Presentation   # E13.0  [2] (🛻..🛼)    pickup truck..roller skate
+1F7E0..1F7EB  ; Emoji_Presentation   # E12.0 [12] (🟠..🟫)    orange circle..brown square
+1F90C         ; Emoji_Presentation   # E13.0  [1] (🤌)       pinched fingers
+1F90D..1F90F  ; Emoji_Presentation   # E12.0  [3] (🤍..🤏)    white heart..pinching hand
+1F910..1F918  ; Emoji_Presentation   # E1.0   [9] (🤐..🤘)    zipper-mouth face..sign of the horns
+1F919..1F91E  ; Emoji_Presentation   # E3.0   [6] (🤙..🤞)    call me hand..crossed fingers
+1F91F         ; Emoji_Presentation   # E5.0   [1] (🤟)       love-you gesture
+1F920..1F927  ; Emoji_Presentation   # E3.0   [8] (🤠..🤧)    cowboy hat face..sneezing face
+1F928..1F92F  ; Emoji_Presentation   # E5.0   [8] (🤨..🤯)    face with raised eyebrow..exploding head
+1F930         ; Emoji_Presentation   # E3.0   [1] (🤰)       pregnant woman
+1F931..1F932  ; Emoji_Presentation   # E5.0   [2] (🤱..🤲)    breast-feeding..palms up together
+1F933..1F93A  ; Emoji_Presentation   # E3.0   [8] (🤳..🤺)    selfie..person fencing
+1F93C..1F93E  ; Emoji_Presentation   # E3.0   [3] (🤼..🤾)    people wrestling..person playing handball
+1F93F         ; Emoji_Presentation   # E12.0  [1] (🤿)       diving mask
+1F940..1F945  ; Emoji_Presentation   # E3.0   [6] (🥀..🥅)    wilted flower..goal net
+1F947..1F94B  ; Emoji_Presentation   # E3.0   [5] (🥇..🥋)    1st place medal..martial arts uniform
+1F94C         ; Emoji_Presentation   # E5.0   [1] (🥌)       curling stone
+1F94D..1F94F  ; Emoji_Presentation   # E11.0  [3] (🥍..🥏)    lacrosse..flying disc
+1F950..1F95E  ; Emoji_Presentation   # E3.0  [15] (🥐..🥞)    croissant..pancakes
+1F95F..1F96B  ; Emoji_Presentation   # E5.0  [13] (🥟..🥫)    dumpling..canned food
+1F96C..1F970  ; Emoji_Presentation   # E11.0  [5] (🥬..🥰)    leafy green..smiling face with hearts
+1F971         ; Emoji_Presentation   # E12.0  [1] (🥱)       yawning face
+1F972         ; Emoji_Presentation   # E13.0  [1] (🥲)       smiling face with tear
+1F973..1F976  ; Emoji_Presentation   # E11.0  [4] (🥳..🥶)    partying face..cold face
+1F977..1F978  ; Emoji_Presentation   # E13.0  [2] (🥷..🥸)    ninja..disguised face
+1F97A         ; Emoji_Presentation   # E11.0  [1] (🥺)       pleading face
+1F97B         ; Emoji_Presentation   # E12.0  [1] (🥻)       sari
+1F97C..1F97F  ; Emoji_Presentation   # E11.0  [4] (🥼..🥿)    lab coat..flat shoe
+1F980..1F984  ; Emoji_Presentation   # E1.0   [5] (🦀..🦄)    crab..unicorn
+1F985..1F991  ; Emoji_Presentation   # E3.0  [13] (🦅..🦑)    eagle..squid
+1F992..1F997  ; Emoji_Presentation   # E5.0   [6] (🦒..🦗)    giraffe..cricket
+1F998..1F9A2  ; Emoji_Presentation   # E11.0 [11] (🦘..🦢)    kangaroo..swan
+1F9A3..1F9A4  ; Emoji_Presentation   # E13.0  [2] (🦣..🦤)    mammoth..dodo
+1F9A5..1F9AA  ; Emoji_Presentation   # E12.0  [6] (🦥..🦪)    sloth..oyster
+1F9AB..1F9AD  ; Emoji_Presentation   # E13.0  [3] (🦫..🦭)    beaver..seal
+1F9AE..1F9AF  ; Emoji_Presentation   # E12.0  [2] (🦮..🦯)    guide dog..white cane
+1F9B0..1F9B9  ; Emoji_Presentation   # E11.0 [10] (🦰..🦹)    red hair..supervillain
+1F9BA..1F9BF  ; Emoji_Presentation   # E12.0  [6] (🦺..🦿)    safety vest..mechanical leg
+1F9C0         ; Emoji_Presentation   # E1.0   [1] (🧀)       cheese wedge
+1F9C1..1F9C2  ; Emoji_Presentation   # E11.0  [2] (🧁..🧂)    cupcake..salt
+1F9C3..1F9CA  ; Emoji_Presentation   # E12.0  [8] (🧃..🧊)    beverage box..ice
+1F9CB         ; Emoji_Presentation   # E13.0  [1] (🧋)       bubble tea
+1F9CD..1F9CF  ; Emoji_Presentation   # E12.0  [3] (🧍..🧏)    person standing..deaf person
+1F9D0..1F9E6  ; Emoji_Presentation   # E5.0  [23] (🧐..🧦)    face with monocle..socks
+1F9E7..1F9FF  ; Emoji_Presentation   # E11.0 [25] (🧧..🧿)    red envelope..nazar amulet
+1FA70..1FA73  ; Emoji_Presentation   # E12.0  [4] (🩰..🩳)    ballet shoes..shorts
+1FA74         ; Emoji_Presentation   # E13.0  [1] (🩴)       thong sandal
+1FA78..1FA7A  ; Emoji_Presentation   # E12.0  [3] (🩸..🩺)    drop of blood..stethoscope
+1FA80..1FA82  ; Emoji_Presentation   # E12.0  [3] (🪀..🪂)    yo-yo..parachute
+1FA83..1FA86  ; Emoji_Presentation   # E13.0  [4] (🪃..🪆)    boomerang..nesting dolls
+1FA90..1FA95  ; Emoji_Presentation   # E12.0  [6] (🪐..🪕)    ringed planet..banjo
+1FA96..1FAA8  ; Emoji_Presentation   # E13.0 [19] (🪖..🪨)    military helmet..rock
+1FAB0..1FAB6  ; Emoji_Presentation   # E13.0  [7] (🪰..🪶)    fly..feather
+1FAC0..1FAC2  ; Emoji_Presentation   # E13.0  [3] (🫀..🫂)    anatomical heart..people hugging
+1FAD0..1FAD6  ; Emoji_Presentation   # E13.0  [7] (🫐..🫖)    blueberries..teapot
+
+# Total elements: 1148
+
+# ================================================
+
+# All omitted code points have Emoji_Modifier=No 
+# @missing: 0000..10FFFF  ; Emoji_Modifier ; No
+
+1F3FB..1F3FF  ; Emoji_Modifier       # E1.0   [5] (🏻..🏿)    light skin tone..dark skin tone
+
+# Total elements: 5
+
+# ================================================
+
+# All omitted code points have Emoji_Modifier_Base=No 
+# @missing: 0000..10FFFF  ; Emoji_Modifier_Base ; No
+
+261D          ; Emoji_Modifier_Base  # E0.6   [1] (☝️)       index pointing up
+26F9          ; Emoji_Modifier_Base  # E0.7   [1] (⛹️)       person bouncing ball
+270A..270C    ; Emoji_Modifier_Base  # E0.6   [3] (✊..✌️)    raised fist..victory hand
+270D          ; Emoji_Modifier_Base  # E0.7   [1] (✍️)       writing hand
+1F385         ; Emoji_Modifier_Base  # E0.6   [1] (🎅)       Santa Claus
+1F3C2..1F3C4  ; Emoji_Modifier_Base  # E0.6   [3] (🏂..🏄)    snowboarder..person surfing
+1F3C7         ; Emoji_Modifier_Base  # E1.0   [1] (🏇)       horse racing
+1F3CA         ; Emoji_Modifier_Base  # E0.6   [1] (🏊)       person swimming
+1F3CB..1F3CC  ; Emoji_Modifier_Base  # E0.7   [2] (🏋️..🏌️)    person lifting weights..person golfing
+1F442..1F443  ; Emoji_Modifier_Base  # E0.6   [2] (👂..👃)    ear..nose
+1F446..1F450  ; Emoji_Modifier_Base  # E0.6  [11] (👆..👐)    backhand index pointing up..open hands
+1F466..1F46B  ; Emoji_Modifier_Base  # E0.6   [6] (👦..👫)    boy..woman and man holding hands
+1F46C..1F46D  ; Emoji_Modifier_Base  # E1.0   [2] (👬..👭)    men holding hands..women holding hands
+1F46E..1F478  ; Emoji_Modifier_Base  # E0.6  [11] (👮..👸)    police officer..princess
+1F47C         ; Emoji_Modifier_Base  # E0.6   [1] (👼)       baby angel
+1F481..1F483  ; Emoji_Modifier_Base  # E0.6   [3] (💁..💃)    person tipping hand..woman dancing
+1F485..1F487  ; Emoji_Modifier_Base  # E0.6   [3] (💅..💇)    nail polish..person getting haircut
+1F48F         ; Emoji_Modifier_Base  # E0.6   [1] (💏)       kiss
+1F491         ; Emoji_Modifier_Base  # E0.6   [1] (💑)       couple with heart
+1F4AA         ; Emoji_Modifier_Base  # E0.6   [1] (💪)       flexed biceps
+1F574..1F575  ; Emoji_Modifier_Base  # E0.7   [2] (🕴️..🕵️)    person in suit levitating..detective
+1F57A         ; Emoji_Modifier_Base  # E3.0   [1] (🕺)       man dancing
+1F590         ; Emoji_Modifier_Base  # E0.7   [1] (🖐️)       hand with fingers splayed
+1F595..1F596  ; Emoji_Modifier_Base  # E1.0   [2] (🖕..🖖)    middle finger..vulcan salute
+1F645..1F647  ; Emoji_Modifier_Base  # E0.6   [3] (🙅..🙇)    person gesturing NO..person bowing
+1F64B..1F64F  ; Emoji_Modifier_Base  # E0.6   [5] (🙋..🙏)    person raising hand..folded hands
+1F6A3         ; Emoji_Modifier_Base  # E1.0   [1] (🚣)       person rowing boat
+1F6B4..1F6B5  ; Emoji_Modifier_Base  # E1.0   [2] (🚴..🚵)    person biking..person mountain biking
+1F6B6         ; Emoji_Modifier_Base  # E0.6   [1] (🚶)       person walking
+1F6C0         ; Emoji_Modifier_Base  # E0.6   [1] (🛀)       person taking bath
+1F6CC         ; Emoji_Modifier_Base  # E1.0   [1] (🛌)       person in bed
+1F90C         ; Emoji_Modifier_Base  # E13.0  [1] (🤌)       pinched fingers
+1F90F         ; Emoji_Modifier_Base  # E12.0  [1] (🤏)       pinching hand
+1F918         ; Emoji_Modifier_Base  # E1.0   [1] (🤘)       sign of the horns
+1F919..1F91E  ; Emoji_Modifier_Base  # E3.0   [6] (🤙..🤞)    call me hand..crossed fingers
+1F91F         ; Emoji_Modifier_Base  # E5.0   [1] (🤟)       love-you gesture
+1F926         ; Emoji_Modifier_Base  # E3.0   [1] (🤦)       person facepalming
+1F930         ; Emoji_Modifier_Base  # E3.0   [1] (🤰)       pregnant woman
+1F931..1F932  ; Emoji_Modifier_Base  # E5.0   [2] (🤱..🤲)    breast-feeding..palms up together
+1F933..1F939  ; Emoji_Modifier_Base  # E3.0   [7] (🤳..🤹)    selfie..person juggling
+1F93C..1F93E  ; Emoji_Modifier_Base  # E3.0   [3] (🤼..🤾)    people wrestling..person playing handball
+1F977         ; Emoji_Modifier_Base  # E13.0  [1] (🥷)       ninja
+1F9B5..1F9B6  ; Emoji_Modifier_Base  # E11.0  [2] (🦵..🦶)    leg..foot
+1F9B8..1F9B9  ; Emoji_Modifier_Base  # E11.0  [2] (🦸..🦹)    superhero..supervillain
+1F9BB         ; Emoji_Modifier_Base  # E12.0  [1] (🦻)       ear with hearing aid
+1F9CD..1F9CF  ; Emoji_Modifier_Base  # E12.0  [3] (🧍..🧏)    person standing..deaf person
+1F9D1..1F9DD  ; Emoji_Modifier_Base  # E5.0  [13] (🧑..🧝)    person..elf
+
+# Total elements: 122
+
+# ================================================
+
+# All omitted code points have Emoji_Component=No 
+# @missing: 0000..10FFFF  ; Emoji_Component ; No
+
+0023          ; Emoji_Component      # E0.0   [1] (#️)       number sign
+002A          ; Emoji_Component      # E0.0   [1] (*️)       asterisk
+0030..0039    ; Emoji_Component      # E0.0  [10] (0️..9️)    digit zero..digit nine
+200D          ; Emoji_Component      # E0.0   [1] (‍)        zero width joiner
+20E3          ; Emoji_Component      # E0.0   [1] (⃣)       combining enclosing keycap
+FE0F          ; Emoji_Component      # E0.0   [1] ()        VARIATION SELECTOR-16
+1F1E6..1F1FF  ; Emoji_Component      # E0.0  [26] (🇦..🇿)    regional indicator symbol letter a..regional indicator symbol letter z
+1F3FB..1F3FF  ; Emoji_Component      # E1.0   [5] (🏻..🏿)    light skin tone..dark skin tone
+1F9B0..1F9B3  ; Emoji_Component      # E11.0  [4] (🦰..🦳)    red hair..white hair
+E0020..E007F  ; Emoji_Component      # E0.0  [96] (󠀠..󠁿)      tag space..cancel tag
+
+# Total elements: 146
+
+# ================================================
+
+# All omitted code points have Extended_Pictographic=No 
+# @missing: 0000..10FFFF  ; Extended_Pictographic ; No
+
+00A9          ; Extended_Pictographic# E0.6   [1] (©️)       copyright
+00AE          ; Extended_Pictographic# E0.6   [1] (®️)       registered
+203C          ; Extended_Pictographic# E0.6   [1] (‼️)       double exclamation mark
+2049          ; Extended_Pictographic# E0.6   [1] (⁉️)       exclamation question mark
+2122          ; Extended_Pictographic# E0.6   [1] (™️)       trade mark
+2139          ; Extended_Pictographic# E0.6   [1] (ℹ️)       information
+2194..2199    ; Extended_Pictographic# E0.6   [6] (↔️..↙️)    left-right arrow..down-left arrow
+21A9..21AA    ; Extended_Pictographic# E0.6   [2] (↩️..↪️)    right arrow curving left..left arrow curving right
+231A..231B    ; Extended_Pictographic# E0.6   [2] (⌚..⌛)    watch..hourglass done
+2328          ; Extended_Pictographic# E1.0   [1] (⌨️)       keyboard
+2388          ; Extended_Pictographic# E0.0   [1] (⎈)       HELM SYMBOL
+23CF          ; Extended_Pictographic# E1.0   [1] (⏏️)       eject button
+23E9..23EC    ; Extended_Pictographic# E0.6   [4] (⏩..⏬)    fast-forward button..fast down button
+23ED..23EE    ; Extended_Pictographic# E0.7   [2] (⏭️..⏮️)    next track button..last track button
+23EF          ; Extended_Pictographic# E1.0   [1] (⏯️)       play or pause button
+23F0          ; Extended_Pictographic# E0.6   [1] (⏰)       alarm clock
+23F1..23F2    ; Extended_Pictographic# E1.0   [2] (⏱️..⏲️)    stopwatch..timer clock
+23F3          ; Extended_Pictographic# E0.6   [1] (⏳)       hourglass not done
+23F8..23FA    ; Extended_Pictographic# E0.7   [3] (⏸️..⏺️)    pause button..record button
+24C2          ; Extended_Pictographic# E0.6   [1] (Ⓜ️)       circled M
+25AA..25AB    ; Extended_Pictographic# E0.6   [2] (▪️..▫️)    black small square..white small square
+25B6          ; Extended_Pictographic# E0.6   [1] (▶️)       play button
+25C0          ; Extended_Pictographic# E0.6   [1] (◀️)       reverse button
+25FB..25FE    ; Extended_Pictographic# E0.6   [4] (◻️..◾)    white medium square..black medium-small square
+2600..2601    ; Extended_Pictographic# E0.6   [2] (☀️..☁️)    sun..cloud
+2602..2603    ; Extended_Pictographic# E0.7   [2] (☂️..☃️)    umbrella..snowman
+2604          ; Extended_Pictographic# E1.0   [1] (☄️)       comet
+2605          ; Extended_Pictographic# E0.0   [1] (★)       BLACK STAR
+2607..260D    ; Extended_Pictographic# E0.0   [7] (☇..☍)    LIGHTNING..OPPOSITION
+260E          ; Extended_Pictographic# E0.6   [1] (☎️)       telephone
+260F..2610    ; Extended_Pictographic# E0.0   [2] (☏..☐)    WHITE TELEPHONE..BALLOT BOX
+2611          ; Extended_Pictographic# E0.6   [1] (☑️)       check box with check
+2612          ; Extended_Pictographic# E0.0   [1] (☒)       BALLOT BOX WITH X
+2614..2615    ; Extended_Pictographic# E0.6   [2] (☔..☕)    umbrella with rain drops..hot beverage
+2616..2617    ; Extended_Pictographic# E0.0   [2] (☖..☗)    WHITE SHOGI PIECE..BLACK SHOGI PIECE
+2618          ; Extended_Pictographic# E1.0   [1] (☘️)       shamrock
+2619..261C    ; Extended_Pictographic# E0.0   [4] (☙..☜)    REVERSED ROTATED FLORAL HEART BULLET..WHITE LEFT POINTING INDEX
+261D          ; Extended_Pictographic# E0.6   [1] (☝️)       index pointing up
+261E..261F    ; Extended_Pictographic# E0.0   [2] (☞..☟)    WHITE RIGHT POINTING INDEX..WHITE DOWN POINTING INDEX
+2620          ; Extended_Pictographic# E1.0   [1] (☠️)       skull and crossbones
+2621          ; Extended_Pictographic# E0.0   [1] (☡)       CAUTION SIGN
+2622..2623    ; Extended_Pictographic# E1.0   [2] (☢️..☣️)    radioactive..biohazard
+2624..2625    ; Extended_Pictographic# E0.0   [2] (☤..☥)    CADUCEUS..ANKH
+2626          ; Extended_Pictographic# E1.0   [1] (☦️)       orthodox cross
+2627..2629    ; Extended_Pictographic# E0.0   [3] (☧..☩)    CHI RHO..CROSS OF JERUSALEM
+262A          ; Extended_Pictographic# E0.7   [1] (☪️)       star and crescent
+262B..262D    ; Extended_Pictographic# E0.0   [3] (☫..☭)    FARSI SYMBOL..HAMMER AND SICKLE
+262E          ; Extended_Pictographic# E1.0   [1] (☮️)       peace symbol
+262F          ; Extended_Pictographic# E0.7   [1] (☯️)       yin yang
+2630..2637    ; Extended_Pictographic# E0.0   [8] (☰..☷)    TRIGRAM FOR HEAVEN..TRIGRAM FOR EARTH
+2638..2639    ; Extended_Pictographic# E0.7   [2] (☸️..☹️)    wheel of dharma..frowning face
+263A          ; Extended_Pictographic# E0.6   [1] (☺️)       smiling face
+263B..263F    ; Extended_Pictographic# E0.0   [5] (☻..☿)    BLACK SMILING FACE..MERCURY
+2640          ; Extended_Pictographic# E4.0   [1] (♀️)       female sign
+2641          ; Extended_Pictographic# E0.0   [1] (♁)       EARTH
+2642          ; Extended_Pictographic# E4.0   [1] (♂️)       male sign
+2643..2647    ; Extended_Pictographic# E0.0   [5] (♃..♇)    JUPITER..PLUTO
+2648..2653    ; Extended_Pictographic# E0.6  [12] (♈..♓)    Aries..Pisces
+2654..265E    ; Extended_Pictographic# E0.0  [11] (♔..♞)    WHITE CHESS KING..BLACK CHESS KNIGHT
+265F          ; Extended_Pictographic# E11.0  [1] (♟️)       chess pawn
+2660          ; Extended_Pictographic# E0.6   [1] (♠️)       spade suit
+2661..2662    ; Extended_Pictographic# E0.0   [2] (♡..♢)    WHITE HEART SUIT..WHITE DIAMOND SUIT
+2663          ; Extended_Pictographic# E0.6   [1] (♣️)       club suit
+2664          ; Extended_Pictographic# E0.0   [1] (♤)       WHITE SPADE SUIT
+2665..2666    ; Extended_Pictographic# E0.6   [2] (♥️..♦️)    heart suit..diamond suit
+2667          ; Extended_Pictographic# E0.0   [1] (♧)       WHITE CLUB SUIT
+2668          ; Extended_Pictographic# E0.6   [1] (♨️)       hot springs
+2669..267A    ; Extended_Pictographic# E0.0  [18] (♩..♺)    QUARTER NOTE..RECYCLING SYMBOL FOR GENERIC MATERIALS
+267B          ; Extended_Pictographic# E0.6   [1] (♻️)       recycling symbol
+267C..267D    ; Extended_Pictographic# E0.0   [2] (♼..♽)    RECYCLED PAPER SYMBOL..PARTIALLY-RECYCLED PAPER SYMBOL
+267E          ; Extended_Pictographic# E11.0  [1] (♾️)       infinity
+267F          ; Extended_Pictographic# E0.6   [1] (♿)       wheelchair symbol
+2680..2685    ; Extended_Pictographic# E0.0   [6] (⚀..⚅)    DIE FACE-1..DIE FACE-6
+2690..2691    ; Extended_Pictographic# E0.0   [2] (⚐..⚑)    WHITE FLAG..BLACK FLAG
+2692          ; Extended_Pictographic# E1.0   [1] (⚒️)       hammer and pick
+2693          ; Extended_Pictographic# E0.6   [1] (⚓)       anchor
+2694          ; Extended_Pictographic# E1.0   [1] (⚔️)       crossed swords
+2695          ; Extended_Pictographic# E4.0   [1] (⚕️)       medical symbol
+2696..2697    ; Extended_Pictographic# E1.0   [2] (⚖️..⚗️)    balance scale..alembic
+2698          ; Extended_Pictographic# E0.0   [1] (⚘)       FLOWER
+2699          ; Extended_Pictographic# E1.0   [1] (⚙️)       gear
+269A          ; Extended_Pictographic# E0.0   [1] (⚚)       STAFF OF HERMES
+269B..269C    ; Extended_Pictographic# E1.0   [2] (⚛️..⚜️)    atom symbol..fleur-de-lis
+269D..269F    ; Extended_Pictographic# E0.0   [3] (⚝..⚟)    OUTLINED WHITE STAR..THREE LINES CONVERGING LEFT
+26A0..26A1    ; Extended_Pictographic# E0.6   [2] (⚠️..⚡)    warning..high voltage
+26A2..26A6    ; Extended_Pictographic# E0.0   [5] (⚢..⚦)    DOUBLED FEMALE SIGN..MALE WITH STROKE SIGN
+26A7          ; Extended_Pictographic# E13.0  [1] (⚧️)       transgender symbol
+26A8..26A9    ; Extended_Pictographic# E0.0   [2] (⚨..⚩)    VERTICAL MALE WITH STROKE SIGN..HORIZONTAL MALE WITH STROKE SIGN
+26AA..26AB    ; Extended_Pictographic# E0.6   [2] (⚪..⚫)    white circle..black circle
+26AC..26AF    ; Extended_Pictographic# E0.0   [4] (⚬..⚯)    MEDIUM SMALL WHITE CIRCLE..UNMARRIED PARTNERSHIP SYMBOL
+26B0..26B1    ; Extended_Pictographic# E1.0   [2] (⚰️..⚱️)    coffin..funeral urn
+26B2..26BC    ; Extended_Pictographic# E0.0  [11] (⚲..⚼)    NEUTER..SESQUIQUADRATE
+26BD..26BE    ; Extended_Pictographic# E0.6   [2] (⚽..⚾)    soccer ball..baseball
+26BF..26C3    ; Extended_Pictographic# E0.0   [5] (⚿..⛃)    SQUARED KEY..BLACK DRAUGHTS KING
+26C4..26C5    ; Extended_Pictographic# E0.6   [2] (⛄..⛅)    snowman without snow..sun behind cloud
+26C6..26C7    ; Extended_Pictographic# E0.0   [2] (⛆..⛇)    RAIN..BLACK SNOWMAN
+26C8          ; Extended_Pictographic# E0.7   [1] (⛈️)       cloud with lightning and rain
+26C9..26CD    ; Extended_Pictographic# E0.0   [5] (⛉..⛍)    TURNED WHITE SHOGI PIECE..DISABLED CAR
+26CE          ; Extended_Pictographic# E0.6   [1] (⛎)       Ophiuchus
+26CF          ; Extended_Pictographic# E0.7   [1] (⛏️)       pick
+26D0          ; Extended_Pictographic# E0.0   [1] (⛐)       CAR SLIDING
+26D1          ; Extended_Pictographic# E0.7   [1] (⛑️)       rescue worker’s helmet
+26D2          ; Extended_Pictographic# E0.0   [1] (⛒)       CIRCLED CROSSING LANES
+26D3          ; Extended_Pictographic# E0.7   [1] (⛓️)       chains
+26D4          ; Extended_Pictographic# E0.6   [1] (⛔)       no entry
+26D5..26E8    ; Extended_Pictographic# E0.0  [20] (⛕..⛨)    ALTERNATE ONE-WAY LEFT WAY TRAFFIC..BLACK CROSS ON SHIELD
+26E9          ; Extended_Pictographic# E0.7   [1] (⛩️)       shinto shrine
+26EA          ; Extended_Pictographic# E0.6   [1] (⛪)       church
+26EB..26EF    ; Extended_Pictographic# E0.0   [5] (⛫..⛯)    CASTLE..MAP SYMBOL FOR LIGHTHOUSE
+26F0..26F1    ; Extended_Pictographic# E0.7   [2] (⛰️..⛱️)    mountain..umbrella on ground
+26F2..26F3    ; Extended_Pictographic# E0.6   [2] (⛲..⛳)    fountain..flag in hole
+26F4          ; Extended_Pictographic# E0.7   [1] (⛴️)       ferry
+26F5          ; Extended_Pictographic# E0.6   [1] (⛵)       sailboat
+26F6          ; Extended_Pictographic# E0.0   [1] (⛶)       SQUARE FOUR CORNERS
+26F7..26F9    ; Extended_Pictographic# E0.7   [3] (⛷️..⛹️)    skier..person bouncing ball
+26FA          ; Extended_Pictographic# E0.6   [1] (⛺)       tent
+26FB..26FC    ; Extended_Pictographic# E0.0   [2] (⛻..⛼)    JAPANESE BANK SYMBOL..HEADSTONE GRAVEYARD SYMBOL
+26FD          ; Extended_Pictographic# E0.6   [1] (⛽)       fuel pump
+26FE..2701    ; Extended_Pictographic# E0.0   [4] (⛾..✁)    CUP ON BLACK SQUARE..UPPER BLADE SCISSORS
+2702          ; Extended_Pictographic# E0.6   [1] (✂️)       scissors
+2703..2704    ; Extended_Pictographic# E0.0   [2] (✃..✄)    LOWER BLADE SCISSORS..WHITE SCISSORS
+2705          ; Extended_Pictographic# E0.6   [1] (✅)       check mark button
+2708..270C    ; Extended_Pictographic# E0.6   [5] (✈️..✌️)    airplane..victory hand
+270D          ; Extended_Pictographic# E0.7   [1] (✍️)       writing hand
+270E          ; Extended_Pictographic# E0.0   [1] (✎)       LOWER RIGHT PENCIL
+270F          ; Extended_Pictographic# E0.6   [1] (✏️)       pencil
+2710..2711    ; Extended_Pictographic# E0.0   [2] (✐..✑)    UPPER RIGHT PENCIL..WHITE NIB
+2712          ; Extended_Pictographic# E0.6   [1] (✒️)       black nib
+2714          ; Extended_Pictographic# E0.6   [1] (✔️)       check mark
+2716          ; Extended_Pictographic# E0.6   [1] (✖️)       multiply
+271D          ; Extended_Pictographic# E0.7   [1] (✝️)       latin cross
+2721          ; Extended_Pictographic# E0.7   [1] (✡️)       star of David
+2728          ; Extended_Pictographic# E0.6   [1] (✨)       sparkles
+2733..2734    ; Extended_Pictographic# E0.6   [2] (✳️..✴️)    eight-spoked asterisk..eight-pointed star
+2744          ; Extended_Pictographic# E0.6   [1] (❄️)       snowflake
+2747          ; Extended_Pictographic# E0.6   [1] (❇️)       sparkle
+274C          ; Extended_Pictographic# E0.6   [1] (❌)       cross mark
+274E          ; Extended_Pictographic# E0.6   [1] (❎)       cross mark button
+2753..2755    ; Extended_Pictographic# E0.6   [3] (❓..❕)    question mark..white exclamation mark
+2757          ; Extended_Pictographic# E0.6   [1] (❗)       exclamation mark
+2763          ; Extended_Pictographic# E1.0   [1] (❣️)       heart exclamation
+2764          ; Extended_Pictographic# E0.6   [1] (❤️)       red heart
+2765..2767    ; Extended_Pictographic# E0.0   [3] (❥..❧)    ROTATED HEAVY BLACK HEART BULLET..ROTATED FLORAL HEART BULLET
+2795..2797    ; Extended_Pictographic# E0.6   [3] (➕..➗)    plus..divide
+27A1          ; Extended_Pictographic# E0.6   [1] (➡️)       right arrow
+27B0          ; Extended_Pictographic# E0.6   [1] (➰)       curly loop
+27BF          ; Extended_Pictographic# E1.0   [1] (➿)       double curly loop
+2934..2935    ; Extended_Pictographic# E0.6   [2] (⤴️..⤵️)    right arrow curving up..right arrow curving down
+2B05..2B07    ; Extended_Pictographic# E0.6   [3] (⬅️..⬇️)    left arrow..down arrow
+2B1B..2B1C    ; Extended_Pictographic# E0.6   [2] (⬛..⬜)    black large square..white large square
+2B50          ; Extended_Pictographic# E0.6   [1] (⭐)       star
+2B55          ; Extended_Pictographic# E0.6   [1] (⭕)       hollow red circle
+3030          ; Extended_Pictographic# E0.6   [1] (〰️)       wavy dash
+303D          ; Extended_Pictographic# E0.6   [1] (〽️)       part alternation mark
+3297          ; Extended_Pictographic# E0.6   [1] (㊗️)       Japanese “congratulations” button
+3299          ; Extended_Pictographic# E0.6   [1] (㊙️)       Japanese “secret” button
+1F000..1F003  ; Extended_Pictographic# E0.0   [4] (🀀..🀃)    MAHJONG TILE EAST WIND..MAHJONG TILE NORTH WIND
+1F004         ; Extended_Pictographic# E0.6   [1] (🀄)       mahjong red dragon
+1F005..1F0CE  ; Extended_Pictographic# E0.0 [202] (🀅..🃎)    MAHJONG TILE GREEN DRAGON..PLAYING CARD KING OF DIAMONDS
+1F0CF         ; Extended_Pictographic# E0.6   [1] (🃏)       joker
+1F0D0..1F0FF  ; Extended_Pictographic# E0.0  [48] (🃐..🃿)    ..
+1F10D..1F10F  ; Extended_Pictographic# E0.0   [3] (🄍..🄏)    CIRCLED ZERO WITH SLASH..CIRCLED DOLLAR SIGN WITH OVERLAID BACKSLASH
+1F12F         ; Extended_Pictographic# E0.0   [1] (🄯)       COPYLEFT SYMBOL
+1F16C..1F16F  ; Extended_Pictographic# E0.0   [4] (🅬..🅯)    RAISED MR SIGN..CIRCLED HUMAN FIGURE
+1F170..1F171  ; Extended_Pictographic# E0.6   [2] (🅰️..🅱️)    A button (blood type)..B button (blood type)
+1F17E..1F17F  ; Extended_Pictographic# E0.6   [2] (🅾️..🅿️)    O button (blood type)..P button
+1F18E         ; Extended_Pictographic# E0.6   [1] (🆎)       AB button (blood type)
+1F191..1F19A  ; Extended_Pictographic# E0.6  [10] (🆑..🆚)    CL button..VS button
+1F1AD..1F1E5  ; Extended_Pictographic# E0.0  [57] (🆭..🇥)    MASK WORK SYMBOL..
+1F201..1F202  ; Extended_Pictographic# E0.6   [2] (🈁..🈂️)    Japanese “here” button..Japanese “service charge” button
+1F203..1F20F  ; Extended_Pictographic# E0.0  [13] (🈃..🈏)    ..
+1F21A         ; Extended_Pictographic# E0.6   [1] (🈚)       Japanese “free of charge” button
+1F22F         ; Extended_Pictographic# E0.6   [1] (🈯)       Japanese “reserved” button
+1F232..1F23A  ; Extended_Pictographic# E0.6   [9] (🈲..🈺)    Japanese “prohibited” button..Japanese “open for business” button
+1F23C..1F23F  ; Extended_Pictographic# E0.0   [4] (🈼..🈿)    ..
+1F249..1F24F  ; Extended_Pictographic# E0.0   [7] (🉉..🉏)    ..
+1F250..1F251  ; Extended_Pictographic# E0.6   [2] (🉐..🉑)    Japanese “bargain” button..Japanese “acceptable” button
+1F252..1F2FF  ; Extended_Pictographic# E0.0 [174] (🉒..🋿)    ..
+1F300..1F30C  ; Extended_Pictographic# E0.6  [13] (🌀..🌌)    cyclone..milky way
+1F30D..1F30E  ; Extended_Pictographic# E0.7   [2] (🌍..🌎)    globe showing Europe-Africa..globe showing Americas
+1F30F         ; Extended_Pictographic# E0.6   [1] (🌏)       globe showing Asia-Australia
+1F310         ; Extended_Pictographic# E1.0   [1] (🌐)       globe with meridians
+1F311         ; Extended_Pictographic# E0.6   [1] (🌑)       new moon
+1F312         ; Extended_Pictographic# E1.0   [1] (🌒)       waxing crescent moon
+1F313..1F315  ; Extended_Pictographic# E0.6   [3] (🌓..🌕)    first quarter moon..full moon
+1F316..1F318  ; Extended_Pictographic# E1.0   [3] (🌖..🌘)    waning gibbous moon..waning crescent moon
+1F319         ; Extended_Pictographic# E0.6   [1] (🌙)       crescent moon
+1F31A         ; Extended_Pictographic# E1.0   [1] (🌚)       new moon face
+1F31B         ; Extended_Pictographic# E0.6   [1] (🌛)       first quarter moon face
+1F31C         ; Extended_Pictographic# E0.7   [1] (🌜)       last quarter moon face
+1F31D..1F31E  ; Extended_Pictographic# E1.0   [2] (🌝..🌞)    full moon face..sun with face
+1F31F..1F320  ; Extended_Pictographic# E0.6   [2] (🌟..🌠)    glowing star..shooting star
+1F321         ; Extended_Pictographic# E0.7   [1] (🌡️)       thermometer
+1F322..1F323  ; Extended_Pictographic# E0.0   [2] (🌢..🌣)    BLACK DROPLET..WHITE SUN
+1F324..1F32C  ; Extended_Pictographic# E0.7   [9] (🌤️..🌬️)    sun behind small cloud..wind face
+1F32D..1F32F  ; Extended_Pictographic# E1.0   [3] (🌭..🌯)    hot dog..burrito
+1F330..1F331  ; Extended_Pictographic# E0.6   [2] (🌰..🌱)    chestnut..seedling
+1F332..1F333  ; Extended_Pictographic# E1.0   [2] (🌲..🌳)    evergreen tree..deciduous tree
+1F334..1F335  ; Extended_Pictographic# E0.6   [2] (🌴..🌵)    palm tree..cactus
+1F336         ; Extended_Pictographic# E0.7   [1] (🌶️)       hot pepper
+1F337..1F34A  ; Extended_Pictographic# E0.6  [20] (🌷..🍊)    tulip..tangerine
+1F34B         ; Extended_Pictographic# E1.0   [1] (🍋)       lemon
+1F34C..1F34F  ; Extended_Pictographic# E0.6   [4] (🍌..🍏)    banana..green apple
+1F350         ; Extended_Pictographic# E1.0   [1] (🍐)       pear
+1F351..1F37B  ; Extended_Pictographic# E0.6  [43] (🍑..🍻)    peach..clinking beer mugs
+1F37C         ; Extended_Pictographic# E1.0   [1] (🍼)       baby bottle
+1F37D         ; Extended_Pictographic# E0.7   [1] (🍽️)       fork and knife with plate
+1F37E..1F37F  ; Extended_Pictographic# E1.0   [2] (🍾..🍿)    bottle with popping cork..popcorn
+1F380..1F393  ; Extended_Pictographic# E0.6  [20] (🎀..🎓)    ribbon..graduation cap
+1F394..1F395  ; Extended_Pictographic# E0.0   [2] (🎔..🎕)    HEART WITH TIP ON THE LEFT..BOUQUET OF FLOWERS
+1F396..1F397  ; Extended_Pictographic# E0.7   [2] (🎖️..🎗️)    military medal..reminder ribbon
+1F398         ; Extended_Pictographic# E0.0   [1] (🎘)       MUSICAL KEYBOARD WITH JACKS
+1F399..1F39B  ; Extended_Pictographic# E0.7   [3] (🎙️..🎛️)    studio microphone..control knobs
+1F39C..1F39D  ; Extended_Pictographic# E0.0   [2] (🎜..🎝)    BEAMED ASCENDING MUSICAL NOTES..BEAMED DESCENDING MUSICAL NOTES
+1F39E..1F39F  ; Extended_Pictographic# E0.7   [2] (🎞️..🎟️)    film frames..admission tickets
+1F3A0..1F3C4  ; Extended_Pictographic# E0.6  [37] (🎠..🏄)    carousel horse..person surfing
+1F3C5         ; Extended_Pictographic# E1.0   [1] (🏅)       sports medal
+1F3C6         ; Extended_Pictographic# E0.6   [1] (🏆)       trophy
+1F3C7         ; Extended_Pictographic# E1.0   [1] (🏇)       horse racing
+1F3C8         ; Extended_Pictographic# E0.6   [1] (🏈)       american football
+1F3C9         ; Extended_Pictographic# E1.0   [1] (🏉)       rugby football
+1F3CA         ; Extended_Pictographic# E0.6   [1] (🏊)       person swimming
+1F3CB..1F3CE  ; Extended_Pictographic# E0.7   [4] (🏋️..🏎️)    person lifting weights..racing car
+1F3CF..1F3D3  ; Extended_Pictographic# E1.0   [5] (🏏..🏓)    cricket game..ping pong
+1F3D4..1F3DF  ; Extended_Pictographic# E0.7  [12] (🏔️..🏟️)    snow-capped mountain..stadium
+1F3E0..1F3E3  ; Extended_Pictographic# E0.6   [4] (🏠..🏣)    house..Japanese post office
+1F3E4         ; Extended_Pictographic# E1.0   [1] (🏤)       post office
+1F3E5..1F3F0  ; Extended_Pictographic# E0.6  [12] (🏥..🏰)    hospital..castle
+1F3F1..1F3F2  ; Extended_Pictographic# E0.0   [2] (🏱..🏲)    WHITE PENNANT..BLACK PENNANT
+1F3F3         ; Extended_Pictographic# E0.7   [1] (🏳️)       white flag
+1F3F4         ; Extended_Pictographic# E1.0   [1] (🏴)       black flag
+1F3F5         ; Extended_Pictographic# E0.7   [1] (🏵️)       rosette
+1F3F6         ; Extended_Pictographic# E0.0   [1] (🏶)       BLACK ROSETTE
+1F3F7         ; Extended_Pictographic# E0.7   [1] (🏷️)       label
+1F3F8..1F3FA  ; Extended_Pictographic# E1.0   [3] (🏸..🏺)    badminton..amphora
+1F400..1F407  ; Extended_Pictographic# E1.0   [8] (🐀..🐇)    rat..rabbit
+1F408         ; Extended_Pictographic# E0.7   [1] (🐈)       cat
+1F409..1F40B  ; Extended_Pictographic# E1.0   [3] (🐉..🐋)    dragon..whale
+1F40C..1F40E  ; Extended_Pictographic# E0.6   [3] (🐌..🐎)    snail..horse
+1F40F..1F410  ; Extended_Pictographic# E1.0   [2] (🐏..🐐)    ram..goat
+1F411..1F412  ; Extended_Pictographic# E0.6   [2] (🐑..🐒)    ewe..monkey
+1F413         ; Extended_Pictographic# E1.0   [1] (🐓)       rooster
+1F414         ; Extended_Pictographic# E0.6   [1] (🐔)       chicken
+1F415         ; Extended_Pictographic# E0.7   [1] (🐕)       dog
+1F416         ; Extended_Pictographic# E1.0   [1] (🐖)       pig
+1F417..1F429  ; Extended_Pictographic# E0.6  [19] (🐗..🐩)    boar..poodle
+1F42A         ; Extended_Pictographic# E1.0   [1] (🐪)       camel
+1F42B..1F43E  ; Extended_Pictographic# E0.6  [20] (🐫..🐾)    two-hump camel..paw prints
+1F43F         ; Extended_Pictographic# E0.7   [1] (🐿️)       chipmunk
+1F440         ; Extended_Pictographic# E0.6   [1] (👀)       eyes
+1F441         ; Extended_Pictographic# E0.7   [1] (👁️)       eye
+1F442..1F464  ; Extended_Pictographic# E0.6  [35] (👂..👤)    ear..bust in silhouette
+1F465         ; Extended_Pictographic# E1.0   [1] (👥)       busts in silhouette
+1F466..1F46B  ; Extended_Pictographic# E0.6   [6] (👦..👫)    boy..woman and man holding hands
+1F46C..1F46D  ; Extended_Pictographic# E1.0   [2] (👬..👭)    men holding hands..women holding hands
+1F46E..1F4AC  ; Extended_Pictographic# E0.6  [63] (👮..💬)    police officer..speech balloon
+1F4AD         ; Extended_Pictographic# E1.0   [1] (💭)       thought balloon
+1F4AE..1F4B5  ; Extended_Pictographic# E0.6   [8] (💮..💵)    white flower..dollar banknote
+1F4B6..1F4B7  ; Extended_Pictographic# E1.0   [2] (💶..💷)    euro banknote..pound banknote
+1F4B8..1F4EB  ; Extended_Pictographic# E0.6  [52] (💸..📫)    money with wings..closed mailbox with raised flag
+1F4EC..1F4ED  ; Extended_Pictographic# E0.7   [2] (📬..📭)    open mailbox with raised flag..open mailbox with lowered flag
+1F4EE         ; Extended_Pictographic# E0.6   [1] (📮)       postbox
+1F4EF         ; Extended_Pictographic# E1.0   [1] (📯)       postal horn
+1F4F0..1F4F4  ; Extended_Pictographic# E0.6   [5] (📰..📴)    newspaper..mobile phone off
+1F4F5         ; Extended_Pictographic# E1.0   [1] (📵)       no mobile phones
+1F4F6..1F4F7  ; Extended_Pictographic# E0.6   [2] (📶..📷)    antenna bars..camera
+1F4F8         ; Extended_Pictographic# E1.0   [1] (📸)       camera with flash
+1F4F9..1F4FC  ; Extended_Pictographic# E0.6   [4] (📹..📼)    video camera..videocassette
+1F4FD         ; Extended_Pictographic# E0.7   [1] (📽️)       film projector
+1F4FE         ; Extended_Pictographic# E0.0   [1] (📾)       PORTABLE STEREO
+1F4FF..1F502  ; Extended_Pictographic# E1.0   [4] (📿..🔂)    prayer beads..repeat single button
+1F503         ; Extended_Pictographic# E0.6   [1] (🔃)       clockwise vertical arrows
+1F504..1F507  ; Extended_Pictographic# E1.0   [4] (🔄..🔇)    counterclockwise arrows button..muted speaker
+1F508         ; Extended_Pictographic# E0.7   [1] (🔈)       speaker low volume
+1F509         ; Extended_Pictographic# E1.0   [1] (🔉)       speaker medium volume
+1F50A..1F514  ; Extended_Pictographic# E0.6  [11] (🔊..🔔)    speaker high volume..bell
+1F515         ; Extended_Pictographic# E1.0   [1] (🔕)       bell with slash
+1F516..1F52B  ; Extended_Pictographic# E0.6  [22] (🔖..🔫)    bookmark..pistol
+1F52C..1F52D  ; Extended_Pictographic# E1.0   [2] (🔬..🔭)    microscope..telescope
+1F52E..1F53D  ; Extended_Pictographic# E0.6  [16] (🔮..🔽)    crystal ball..downwards button
+1F546..1F548  ; Extended_Pictographic# E0.0   [3] (🕆..🕈)    WHITE LATIN CROSS..CELTIC CROSS
+1F549..1F54A  ; Extended_Pictographic# E0.7   [2] (🕉️..🕊️)    om..dove
+1F54B..1F54E  ; Extended_Pictographic# E1.0   [4] (🕋..🕎)    kaaba..menorah
+1F54F         ; Extended_Pictographic# E0.0   [1] (🕏)       BOWL OF HYGIEIA
+1F550..1F55B  ; Extended_Pictographic# E0.6  [12] (🕐..🕛)    one o’clock..twelve o’clock
+1F55C..1F567  ; Extended_Pictographic# E0.7  [12] (🕜..🕧)    one-thirty..twelve-thirty
+1F568..1F56E  ; Extended_Pictographic# E0.0   [7] (🕨..🕮)    RIGHT SPEAKER..BOOK
+1F56F..1F570  ; Extended_Pictographic# E0.7   [2] (🕯️..🕰️)    candle..mantelpiece clock
+1F571..1F572  ; Extended_Pictographic# E0.0   [2] (🕱..🕲)    BLACK SKULL AND CROSSBONES..NO PIRACY
+1F573..1F579  ; Extended_Pictographic# E0.7   [7] (🕳️..🕹️)    hole..joystick
+1F57A         ; Extended_Pictographic# E3.0   [1] (🕺)       man dancing
+1F57B..1F586  ; Extended_Pictographic# E0.0  [12] (🕻..🖆)    LEFT HAND TELEPHONE RECEIVER..PEN OVER STAMPED ENVELOPE
+1F587         ; Extended_Pictographic# E0.7   [1] (🖇️)       linked paperclips
+1F588..1F589  ; Extended_Pictographic# E0.0   [2] (🖈..🖉)    BLACK PUSHPIN..LOWER LEFT PENCIL
+1F58A..1F58D  ; Extended_Pictographic# E0.7   [4] (🖊️..🖍️)    pen..crayon
+1F58E..1F58F  ; Extended_Pictographic# E0.0   [2] (🖎..🖏)    LEFT WRITING HAND..TURNED OK HAND SIGN
+1F590         ; Extended_Pictographic# E0.7   [1] (🖐️)       hand with fingers splayed
+1F591..1F594  ; Extended_Pictographic# E0.0   [4] (🖑..🖔)    REVERSED RAISED HAND WITH FINGERS SPLAYED..REVERSED VICTORY HAND
+1F595..1F596  ; Extended_Pictographic# E1.0   [2] (🖕..🖖)    middle finger..vulcan salute
+1F597..1F5A3  ; Extended_Pictographic# E0.0  [13] (🖗..🖣)    WHITE DOWN POINTING LEFT HAND INDEX..BLACK DOWN POINTING BACKHAND INDEX
+1F5A4         ; Extended_Pictographic# E3.0   [1] (🖤)       black heart
+1F5A5         ; Extended_Pictographic# E0.7   [1] (🖥️)       desktop computer
+1F5A6..1F5A7  ; Extended_Pictographic# E0.0   [2] (🖦..🖧)    KEYBOARD AND MOUSE..THREE NETWORKED COMPUTERS
+1F5A8         ; Extended_Pictographic# E0.7   [1] (🖨️)       printer
+1F5A9..1F5B0  ; Extended_Pictographic# E0.0   [8] (🖩..🖰)    POCKET CALCULATOR..TWO BUTTON MOUSE
+1F5B1..1F5B2  ; Extended_Pictographic# E0.7   [2] (🖱️..🖲️)    computer mouse..trackball
+1F5B3..1F5BB  ; Extended_Pictographic# E0.0   [9] (🖳..🖻)    OLD PERSONAL COMPUTER..DOCUMENT WITH PICTURE
+1F5BC         ; Extended_Pictographic# E0.7   [1] (🖼️)       framed picture
+1F5BD..1F5C1  ; Extended_Pictographic# E0.0   [5] (🖽..🗁)    FRAME WITH TILES..OPEN FOLDER
+1F5C2..1F5C4  ; Extended_Pictographic# E0.7   [3] (🗂️..🗄️)    card index dividers..file cabinet
+1F5C5..1F5D0  ; Extended_Pictographic# E0.0  [12] (🗅..🗐)    EMPTY NOTE..PAGES
+1F5D1..1F5D3  ; Extended_Pictographic# E0.7   [3] (🗑️..🗓️)    wastebasket..spiral calendar
+1F5D4..1F5DB  ; Extended_Pictographic# E0.0   [8] (🗔..🗛)    DESKTOP WINDOW..DECREASE FONT SIZE SYMBOL
+1F5DC..1F5DE  ; Extended_Pictographic# E0.7   [3] (🗜️..🗞️)    clamp..rolled-up newspaper
+1F5DF..1F5E0  ; Extended_Pictographic# E0.0   [2] (🗟..🗠)    PAGE WITH CIRCLED TEXT..STOCK CHART
+1F5E1         ; Extended_Pictographic# E0.7   [1] (🗡️)       dagger
+1F5E2         ; Extended_Pictographic# E0.0   [1] (🗢)       LIPS
+1F5E3         ; Extended_Pictographic# E0.7   [1] (🗣️)       speaking head
+1F5E4..1F5E7  ; Extended_Pictographic# E0.0   [4] (🗤..🗧)    THREE RAYS ABOVE..THREE RAYS RIGHT
+1F5E8         ; Extended_Pictographic# E2.0   [1] (🗨️)       left speech bubble
+1F5E9..1F5EE  ; Extended_Pictographic# E0.0   [6] (🗩..🗮)    RIGHT SPEECH BUBBLE..LEFT ANGER BUBBLE
+1F5EF         ; Extended_Pictographic# E0.7   [1] (🗯️)       right anger bubble
+1F5F0..1F5F2  ; Extended_Pictographic# E0.0   [3] (🗰..🗲)    MOOD BUBBLE..LIGHTNING MOOD
+1F5F3         ; Extended_Pictographic# E0.7   [1] (🗳️)       ballot box with ballot
+1F5F4..1F5F9  ; Extended_Pictographic# E0.0   [6] (🗴..🗹)    BALLOT SCRIPT X..BALLOT BOX WITH BOLD CHECK
+1F5FA         ; Extended_Pictographic# E0.7   [1] (🗺️)       world map
+1F5FB..1F5FF  ; Extended_Pictographic# E0.6   [5] (🗻..🗿)    mount fuji..moai
+1F600         ; Extended_Pictographic# E1.0   [1] (😀)       grinning face
+1F601..1F606  ; Extended_Pictographic# E0.6   [6] (😁..😆)    beaming face with smiling eyes..grinning squinting face
+1F607..1F608  ; Extended_Pictographic# E1.0   [2] (😇..😈)    smiling face with halo..smiling face with horns
+1F609..1F60D  ; Extended_Pictographic# E0.6   [5] (😉..😍)    winking face..smiling face with heart-eyes
+1F60E         ; Extended_Pictographic# E1.0   [1] (😎)       smiling face with sunglasses
+1F60F         ; Extended_Pictographic# E0.6   [1] (😏)       smirking face
+1F610         ; Extended_Pictographic# E0.7   [1] (😐)       neutral face
+1F611         ; Extended_Pictographic# E1.0   [1] (😑)       expressionless face
+1F612..1F614  ; Extended_Pictographic# E0.6   [3] (😒..😔)    unamused face..pensive face
+1F615         ; Extended_Pictographic# E1.0   [1] (😕)       confused face
+1F616         ; Extended_Pictographic# E0.6   [1] (😖)       confounded face
+1F617         ; Extended_Pictographic# E1.0   [1] (😗)       kissing face
+1F618         ; Extended_Pictographic# E0.6   [1] (😘)       face blowing a kiss
+1F619         ; Extended_Pictographic# E1.0   [1] (😙)       kissing face with smiling eyes
+1F61A         ; Extended_Pictographic# E0.6   [1] (😚)       kissing face with closed eyes
+1F61B         ; Extended_Pictographic# E1.0   [1] (😛)       face with tongue
+1F61C..1F61E  ; Extended_Pictographic# E0.6   [3] (😜..😞)    winking face with tongue..disappointed face
+1F61F         ; Extended_Pictographic# E1.0   [1] (😟)       worried face
+1F620..1F625  ; Extended_Pictographic# E0.6   [6] (😠..😥)    angry face..sad but relieved face
+1F626..1F627  ; Extended_Pictographic# E1.0   [2] (😦..😧)    frowning face with open mouth..anguished face
+1F628..1F62B  ; Extended_Pictographic# E0.6   [4] (😨..😫)    fearful face..tired face
+1F62C         ; Extended_Pictographic# E1.0   [1] (😬)       grimacing face
+1F62D         ; Extended_Pictographic# E0.6   [1] (😭)       loudly crying face
+1F62E..1F62F  ; Extended_Pictographic# E1.0   [2] (😮..😯)    face with open mouth..hushed face
+1F630..1F633  ; Extended_Pictographic# E0.6   [4] (😰..😳)    anxious face with sweat..flushed face
+1F634         ; Extended_Pictographic# E1.0   [1] (😴)       sleeping face
+1F635         ; Extended_Pictographic# E0.6   [1] (😵)       dizzy face
+1F636         ; Extended_Pictographic# E1.0   [1] (😶)       face without mouth
+1F637..1F640  ; Extended_Pictographic# E0.6  [10] (😷..🙀)    face with medical mask..weary cat
+1F641..1F644  ; Extended_Pictographic# E1.0   [4] (🙁..🙄)    slightly frowning face..face with rolling eyes
+1F645..1F64F  ; Extended_Pictographic# E0.6  [11] (🙅..🙏)    person gesturing NO..folded hands
+1F680         ; Extended_Pictographic# E0.6   [1] (🚀)       rocket
+1F681..1F682  ; Extended_Pictographic# E1.0   [2] (🚁..🚂)    helicopter..locomotive
+1F683..1F685  ; Extended_Pictographic# E0.6   [3] (🚃..🚅)    railway car..bullet train
+1F686         ; Extended_Pictographic# E1.0   [1] (🚆)       train
+1F687         ; Extended_Pictographic# E0.6   [1] (🚇)       metro
+1F688         ; Extended_Pictographic# E1.0   [1] (🚈)       light rail
+1F689         ; Extended_Pictographic# E0.6   [1] (🚉)       station
+1F68A..1F68B  ; Extended_Pictographic# E1.0   [2] (🚊..🚋)    tram..tram car
+1F68C         ; Extended_Pictographic# E0.6   [1] (🚌)       bus
+1F68D         ; Extended_Pictographic# E0.7   [1] (🚍)       oncoming bus
+1F68E         ; Extended_Pictographic# E1.0   [1] (🚎)       trolleybus
+1F68F         ; Extended_Pictographic# E0.6   [1] (🚏)       bus stop
+1F690         ; Extended_Pictographic# E1.0   [1] (🚐)       minibus
+1F691..1F693  ; Extended_Pictographic# E0.6   [3] (🚑..🚓)    ambulance..police car
+1F694         ; Extended_Pictographic# E0.7   [1] (🚔)       oncoming police car
+1F695         ; Extended_Pictographic# E0.6   [1] (🚕)       taxi
+1F696         ; Extended_Pictographic# E1.0   [1] (🚖)       oncoming taxi
+1F697         ; Extended_Pictographic# E0.6   [1] (🚗)       automobile
+1F698         ; Extended_Pictographic# E0.7   [1] (🚘)       oncoming automobile
+1F699..1F69A  ; Extended_Pictographic# E0.6   [2] (🚙..🚚)    sport utility vehicle..delivery truck
+1F69B..1F6A1  ; Extended_Pictographic# E1.0   [7] (🚛..🚡)    articulated lorry..aerial tramway
+1F6A2         ; Extended_Pictographic# E0.6   [1] (🚢)       ship
+1F6A3         ; Extended_Pictographic# E1.0   [1] (🚣)       person rowing boat
+1F6A4..1F6A5  ; Extended_Pictographic# E0.6   [2] (🚤..🚥)    speedboat..horizontal traffic light
+1F6A6         ; Extended_Pictographic# E1.0   [1] (🚦)       vertical traffic light
+1F6A7..1F6AD  ; Extended_Pictographic# E0.6   [7] (🚧..🚭)    construction..no smoking
+1F6AE..1F6B1  ; Extended_Pictographic# E1.0   [4] (🚮..🚱)    litter in bin sign..non-potable water
+1F6B2         ; Extended_Pictographic# E0.6   [1] (🚲)       bicycle
+1F6B3..1F6B5  ; Extended_Pictographic# E1.0   [3] (🚳..🚵)    no bicycles..person mountain biking
+1F6B6         ; Extended_Pictographic# E0.6   [1] (🚶)       person walking
+1F6B7..1F6B8  ; Extended_Pictographic# E1.0   [2] (🚷..🚸)    no pedestrians..children crossing
+1F6B9..1F6BE  ; Extended_Pictographic# E0.6   [6] (🚹..🚾)    men’s room..water closet
+1F6BF         ; Extended_Pictographic# E1.0   [1] (🚿)       shower
+1F6C0         ; Extended_Pictographic# E0.6   [1] (🛀)       person taking bath
+1F6C1..1F6C5  ; Extended_Pictographic# E1.0   [5] (🛁..🛅)    bathtub..left luggage
+1F6C6..1F6CA  ; Extended_Pictographic# E0.0   [5] (🛆..🛊)    TRIANGLE WITH ROUNDED CORNERS..GIRLS SYMBOL
+1F6CB         ; Extended_Pictographic# E0.7   [1] (🛋️)       couch and lamp
+1F6CC         ; Extended_Pictographic# E1.0   [1] (🛌)       person in bed
+1F6CD..1F6CF  ; Extended_Pictographic# E0.7   [3] (🛍️..🛏️)    shopping bags..bed
+1F6D0         ; Extended_Pictographic# E1.0   [1] (🛐)       place of worship
+1F6D1..1F6D2  ; Extended_Pictographic# E3.0   [2] (🛑..🛒)    stop sign..shopping cart
+1F6D3..1F6D4  ; Extended_Pictographic# E0.0   [2] (🛓..🛔)    STUPA..PAGODA
+1F6D5         ; Extended_Pictographic# E12.0  [1] (🛕)       hindu temple
+1F6D6..1F6D7  ; Extended_Pictographic# E13.0  [2] (🛖..🛗)    hut..elevator
+1F6D8..1F6DF  ; Extended_Pictographic# E0.0   [8] (🛘..🛟)    ..
+1F6E0..1F6E5  ; Extended_Pictographic# E0.7   [6] (🛠️..🛥️)    hammer and wrench..motor boat
+1F6E6..1F6E8  ; Extended_Pictographic# E0.0   [3] (🛦..🛨)    UP-POINTING MILITARY AIRPLANE..UP-POINTING SMALL AIRPLANE
+1F6E9         ; Extended_Pictographic# E0.7   [1] (🛩️)       small airplane
+1F6EA         ; Extended_Pictographic# E0.0   [1] (🛪)       NORTHEAST-POINTING AIRPLANE
+1F6EB..1F6EC  ; Extended_Pictographic# E1.0   [2] (🛫..🛬)    airplane departure..airplane arrival
+1F6ED..1F6EF  ; Extended_Pictographic# E0.0   [3] (🛭..🛯)    ..
+1F6F0         ; Extended_Pictographic# E0.7   [1] (🛰️)       satellite
+1F6F1..1F6F2  ; Extended_Pictographic# E0.0   [2] (🛱..🛲)    ONCOMING FIRE ENGINE..DIESEL LOCOMOTIVE
+1F6F3         ; Extended_Pictographic# E0.7   [1] (🛳️)       passenger ship
+1F6F4..1F6F6  ; Extended_Pictographic# E3.0   [3] (🛴..🛶)    kick scooter..canoe
+1F6F7..1F6F8  ; Extended_Pictographic# E5.0   [2] (🛷..🛸)    sled..flying saucer
+1F6F9         ; Extended_Pictographic# E11.0  [1] (🛹)       skateboard
+1F6FA         ; Extended_Pictographic# E12.0  [1] (🛺)       auto rickshaw
+1F6FB..1F6FC  ; Extended_Pictographic# E13.0  [2] (🛻..🛼)    pickup truck..roller skate
+1F6FD..1F6FF  ; Extended_Pictographic# E0.0   [3] (🛽..🛿)    ..
+1F774..1F77F  ; Extended_Pictographic# E0.0  [12] (🝴..🝿)    ..
+1F7D5..1F7DF  ; Extended_Pictographic# E0.0  [11] (🟕..🟟)    CIRCLED TRIANGLE..
+1F7E0..1F7EB  ; Extended_Pictographic# E12.0 [12] (🟠..🟫)    orange circle..brown square
+1F7EC..1F7FF  ; Extended_Pictographic# E0.0  [20] (🟬..🟿)    ..
+1F80C..1F80F  ; Extended_Pictographic# E0.0   [4] (🠌..🠏)    ..
+1F848..1F84F  ; Extended_Pictographic# E0.0   [8] (🡈..🡏)    ..
+1F85A..1F85F  ; Extended_Pictographic# E0.0   [6] (🡚..🡟)    ..
+1F888..1F88F  ; Extended_Pictographic# E0.0   [8] (🢈..🢏)    ..
+1F8AE..1F8FF  ; Extended_Pictographic# E0.0  [82] (🢮..🣿)    ..
+1F90C         ; Extended_Pictographic# E13.0  [1] (🤌)       pinched fingers
+1F90D..1F90F  ; Extended_Pictographic# E12.0  [3] (🤍..🤏)    white heart..pinching hand
+1F910..1F918  ; Extended_Pictographic# E1.0   [9] (🤐..🤘)    zipper-mouth face..sign of the horns
+1F919..1F91E  ; Extended_Pictographic# E3.0   [6] (🤙..🤞)    call me hand..crossed fingers
+1F91F         ; Extended_Pictographic# E5.0   [1] (🤟)       love-you gesture
+1F920..1F927  ; Extended_Pictographic# E3.0   [8] (🤠..🤧)    cowboy hat face..sneezing face
+1F928..1F92F  ; Extended_Pictographic# E5.0   [8] (🤨..🤯)    face with raised eyebrow..exploding head
+1F930         ; Extended_Pictographic# E3.0   [1] (🤰)       pregnant woman
+1F931..1F932  ; Extended_Pictographic# E5.0   [2] (🤱..🤲)    breast-feeding..palms up together
+1F933..1F93A  ; Extended_Pictographic# E3.0   [8] (🤳..🤺)    selfie..person fencing
+1F93C..1F93E  ; Extended_Pictographic# E3.0   [3] (🤼..🤾)    people wrestling..person playing handball
+1F93F         ; Extended_Pictographic# E12.0  [1] (🤿)       diving mask
+1F940..1F945  ; Extended_Pictographic# E3.0   [6] (🥀..🥅)    wilted flower..goal net
+1F947..1F94B  ; Extended_Pictographic# E3.0   [5] (🥇..🥋)    1st place medal..martial arts uniform
+1F94C         ; Extended_Pictographic# E5.0   [1] (🥌)       curling stone
+1F94D..1F94F  ; Extended_Pictographic# E11.0  [3] (🥍..🥏)    lacrosse..flying disc
+1F950..1F95E  ; Extended_Pictographic# E3.0  [15] (🥐..🥞)    croissant..pancakes
+1F95F..1F96B  ; Extended_Pictographic# E5.0  [13] (🥟..🥫)    dumpling..canned food
+1F96C..1F970  ; Extended_Pictographic# E11.0  [5] (🥬..🥰)    leafy green..smiling face with hearts
+1F971         ; Extended_Pictographic# E12.0  [1] (🥱)       yawning face
+1F972         ; Extended_Pictographic# E13.0  [1] (🥲)       smiling face with tear
+1F973..1F976  ; Extended_Pictographic# E11.0  [4] (🥳..🥶)    partying face..cold face
+1F977..1F978  ; Extended_Pictographic# E13.0  [2] (🥷..🥸)    ninja..disguised face
+1F979         ; Extended_Pictographic# E0.0   [1] (🥹)       
+1F97A         ; Extended_Pictographic# E11.0  [1] (🥺)       pleading face
+1F97B         ; Extended_Pictographic# E12.0  [1] (🥻)       sari
+1F97C..1F97F  ; Extended_Pictographic# E11.0  [4] (🥼..🥿)    lab coat..flat shoe
+1F980..1F984  ; Extended_Pictographic# E1.0   [5] (🦀..🦄)    crab..unicorn
+1F985..1F991  ; Extended_Pictographic# E3.0  [13] (🦅..🦑)    eagle..squid
+1F992..1F997  ; Extended_Pictographic# E5.0   [6] (🦒..🦗)    giraffe..cricket
+1F998..1F9A2  ; Extended_Pictographic# E11.0 [11] (🦘..🦢)    kangaroo..swan
+1F9A3..1F9A4  ; Extended_Pictographic# E13.0  [2] (🦣..🦤)    mammoth..dodo
+1F9A5..1F9AA  ; Extended_Pictographic# E12.0  [6] (🦥..🦪)    sloth..oyster
+1F9AB..1F9AD  ; Extended_Pictographic# E13.0  [3] (🦫..🦭)    beaver..seal
+1F9AE..1F9AF  ; Extended_Pictographic# E12.0  [2] (🦮..🦯)    guide dog..white cane
+1F9B0..1F9B9  ; Extended_Pictographic# E11.0 [10] (🦰..🦹)    red hair..supervillain
+1F9BA..1F9BF  ; Extended_Pictographic# E12.0  [6] (🦺..🦿)    safety vest..mechanical leg
+1F9C0         ; Extended_Pictographic# E1.0   [1] (🧀)       cheese wedge
+1F9C1..1F9C2  ; Extended_Pictographic# E11.0  [2] (🧁..🧂)    cupcake..salt
+1F9C3..1F9CA  ; Extended_Pictographic# E12.0  [8] (🧃..🧊)    beverage box..ice
+1F9CB         ; Extended_Pictographic# E13.0  [1] (🧋)       bubble tea
+1F9CC         ; Extended_Pictographic# E0.0   [1] (🧌)       
+1F9CD..1F9CF  ; Extended_Pictographic# E12.0  [3] (🧍..🧏)    person standing..deaf person
+1F9D0..1F9E6  ; Extended_Pictographic# E5.0  [23] (🧐..🧦)    face with monocle..socks
+1F9E7..1F9FF  ; Extended_Pictographic# E11.0 [25] (🧧..🧿)    red envelope..nazar amulet
+1FA00..1FA6F  ; Extended_Pictographic# E0.0 [112] (🨀..🩯)    NEUTRAL CHESS KING..
+1FA70..1FA73  ; Extended_Pictographic# E12.0  [4] (🩰..🩳)    ballet shoes..shorts
+1FA74         ; Extended_Pictographic# E13.0  [1] (🩴)       thong sandal
+1FA75..1FA77  ; Extended_Pictographic# E0.0   [3] (🩵..🩷)    ..
+1FA78..1FA7A  ; Extended_Pictographic# E12.0  [3] (🩸..🩺)    drop of blood..stethoscope
+1FA7B..1FA7F  ; Extended_Pictographic# E0.0   [5] (🩻..🩿)    ..
+1FA80..1FA82  ; Extended_Pictographic# E12.0  [3] (🪀..🪂)    yo-yo..parachute
+1FA83..1FA86  ; Extended_Pictographic# E13.0  [4] (🪃..🪆)    boomerang..nesting dolls
+1FA87..1FA8F  ; Extended_Pictographic# E0.0   [9] (🪇..🪏)    ..
+1FA90..1FA95  ; Extended_Pictographic# E12.0  [6] (🪐..🪕)    ringed planet..banjo
+1FA96..1FAA8  ; Extended_Pictographic# E13.0 [19] (🪖..🪨)    military helmet..rock
+1FAA9..1FAAF  ; Extended_Pictographic# E0.0   [7] (🪩..🪯)    ..
+1FAB0..1FAB6  ; Extended_Pictographic# E13.0  [7] (🪰..🪶)    fly..feather
+1FAB7..1FABF  ; Extended_Pictographic# E0.0   [9] (🪷..🪿)    ..
+1FAC0..1FAC2  ; Extended_Pictographic# E13.0  [3] (🫀..🫂)    anatomical heart..people hugging
+1FAC3..1FACF  ; Extended_Pictographic# E0.0  [13] (🫃..🫏)    ..
+1FAD0..1FAD6  ; Extended_Pictographic# E13.0  [7] (🫐..🫖)    blueberries..teapot
+1FAD7..1FAFF  ; Extended_Pictographic# E0.0  [41] (🫗..🫿)    ..
+1FC00..1FFFD  ; Extended_Pictographic# E0.0[1022] (🰀..🿽)    ..
+
+# Total elements: 3537
+
+#EOF
diff --git a/make/jdk/src/classes/build/tools/generateemojidata/GenerateEmojiData.java b/make/jdk/src/classes/build/tools/generateemojidata/GenerateEmojiData.java
index 80091ec47b6..64154f2ddcb 100644
--- a/make/jdk/src/classes/build/tools/generateemojidata/GenerateEmojiData.java
+++ b/make/jdk/src/classes/build/tools/generateemojidata/GenerateEmojiData.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
@@ -47,7 +47,7 @@ public class GenerateEmojiData {
             final Range[] last = new Range[1]; // last extended pictographic range
             last[0] = new Range(0, 0);
 
-            List extPictRanges = Files.lines(Paths.get(args[1], "emoji-data.txt"))
+            List extPictRanges = Files.lines(Paths.get(args[1], "emoji", "emoji-data.txt"))
                 .filter(Predicate.not(l -> l.startsWith("#") || l.isBlank()))
                 .filter(l -> l.contains("; Extended_Pictograph"))
                 .map(l -> new Range(l.replaceFirst(" .*", "")))
diff --git a/make/modules/java.base/gensrc/GensrcCharacterData.gmk b/make/modules/java.base/gensrc/GensrcCharacterData.gmk
index 9c2a4902da3..09966bab4d7 100644
--- a/make/modules/java.base/gensrc/GensrcCharacterData.gmk
+++ b/make/modules/java.base/gensrc/GensrcCharacterData.gmk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2011, 2019, 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
@@ -54,6 +54,7 @@ $(eval $(call SetupCharacterData,CharacterDataLatin1, , -latin1 8))
 $(eval $(call SetupCharacterData,CharacterData00, -string -plane 0, 11 4 1))
 $(eval $(call SetupCharacterData,CharacterData01, -string -plane 1, 11 4 1))
 $(eval $(call SetupCharacterData,CharacterData02, -string -plane 2, 11 4 1))
+$(eval $(call SetupCharacterData,CharacterData03, -string -plane 3, 11 4 1))
 $(eval $(call SetupCharacterData,CharacterData0E, -string -plane 14, 11 4 1))
 
 # Copy two Java files that need no preprocessing.
diff --git a/make/modules/java.base/gensrc/GensrcEmojiData.gmk b/make/modules/java.base/gensrc/GensrcEmojiData.gmk
index f727a01dd2e..c6ae6fa9c32 100644
--- a/make/modules/java.base/gensrc/GensrcEmojiData.gmk
+++ b/make/modules/java.base/gensrc/GensrcEmojiData.gmk
@@ -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
@@ -32,7 +32,7 @@ GENSRC_EMOJIDATA := $(SUPPORT_OUTPUTDIR)/gensrc/java.base/java/util/regex/EmojiD
 EMOJIDATATEMP = $(TOPDIR)/src/java.base/share/classes/java/util/regex/EmojiData.java.template
 UNICODEDATA = $(TOPDIR)/make/data/unicodedata
 
-$(GENSRC_EMOJIDATA): $(BUILD_TOOLS_JDK) $(EMOJIDATATEMP) $(UNICODEDATA)/emoji-data.txt
+$(GENSRC_EMOJIDATA): $(BUILD_TOOLS_JDK) $(EMOJIDATATEMP) $(UNICODEDATA)/emoji/emoji-data.txt
 	$(call LogInfo, Generating $@)
 	$(call MakeTargetDir)
 	$(TOOL_GENERATEEMOJIDATA) \
diff --git a/src/java.base/share/classes/java/lang/Character.java b/src/java.base/share/classes/java/lang/Character.java
index 5c9da38de21..dd69413f1b8 100644
--- a/src/java.base/share/classes/java/lang/Character.java
+++ b/src/java.base/share/classes/java/lang/Character.java
@@ -62,7 +62,7 @@ import static java.lang.constant.ConstantDescs.DEFAULT_NAME;
  * from the Unicode Consortium at
  * http://www.unicode.org.
  * 

- * Character information is based on the Unicode Standard, version 12.1. + * Character information is based on the Unicode Standard, version 13.0. * *

Unicode Character Representations

* @@ -691,10 +691,10 @@ class Character implements java.io.Serializable, Comparable, Constabl */ public static final class UnicodeBlock extends Subset { /** - * 676 - the expected number of entities + * 684 - the expected number of entities * 0.75 - the default load factor of HashMap */ - private static final int NUM_ENTITIES = 676; + private static final int NUM_ENTITIES = 684; private static Map map = new HashMap<>((int)(NUM_ENTITIES / 0.75f + 1.0f)); @@ -3304,6 +3304,82 @@ class Character implements java.io.Serializable, Comparable, Constabl "SYMBOLS AND PICTOGRAPHS EXTENDED-A", "SYMBOLSANDPICTOGRAPHSEXTENDED-A"); + /** + * Constant for the "Yezidi" Unicode + * character block. + * @since 15 + */ + public static final UnicodeBlock YEZIDI = + new UnicodeBlock("YEZIDI"); + + /** + * Constant for the "Chorasmian" Unicode + * character block. + * @since 15 + */ + public static final UnicodeBlock CHORASMIAN = + new UnicodeBlock("CHORASMIAN"); + + /** + * Constant for the "Dives Akuru" Unicode + * character block. + * @since 15 + */ + public static final UnicodeBlock DIVES_AKURU = + new UnicodeBlock("DIVES_AKURU", + "DIVES AKURU", + "DIVESAKURU"); + + /** + * Constant for the "Lisu Supplement" Unicode + * character block. + * @since 15 + */ + public static final UnicodeBlock LISU_SUPPLEMENT = + new UnicodeBlock("LISU_SUPPLEMENT", + "LISU SUPPLEMENT", + "LISUSUPPLEMENT"); + + /** + * Constant for the "Khitan Small Script" Unicode + * character block. + * @since 15 + */ + public static final UnicodeBlock KHITAN_SMALL_SCRIPT = + new UnicodeBlock("KHITAN_SMALL_SCRIPT", + "KHITAN SMALL SCRIPT", + "KHITANSMALLSCRIPT"); + + /** + * Constant for the "Tangut Supplement" Unicode + * character block. + * @since 15 + */ + public static final UnicodeBlock TANGUT_SUPPLEMENT = + new UnicodeBlock("TANGUT_SUPPLEMENT", + "TANGUT SUPPLEMENT", + "TANGUTSUPPLEMENT"); + + /** + * Constant for the "Symbols for Legacy Computing" Unicode + * character block. + * @since 15 + */ + public static final UnicodeBlock SYMBOLS_FOR_LEGACY_COMPUTING = + new UnicodeBlock("SYMBOLS_FOR_LEGACY_COMPUTING", + "SYMBOLS FOR LEGACY COMPUTING", + "SYMBOLSFORLEGACYCOMPUTING"); + + /** + * Constant for the "CJK Unified Ideographs Extension G" Unicode + * character block. + * @since 15 + */ + public static final UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_G = + new UnicodeBlock("CJK_UNIFIED_IDEOGRAPHS_EXTENSION_G", + "CJK UNIFIED IDEOGRAPHS EXTENSION G", + "CJKUNIFIEDIDEOGRAPHSEXTENSIONG"); + private static final int[] blockStarts = { 0x0000, // 0000..007F; Basic Latin 0x0080, // 0080..00FF; Latin-1 Supplement @@ -3522,10 +3598,12 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x10D00, // 10D00..10D3F; Hanifi Rohingya 0x10D40, // unassigned 0x10E60, // 10E60..10E7F; Rumi Numeral Symbols - 0x10E80, // unassigned + 0x10E80, // 10E80..10EBF; Yezidi + 0x10EC0, // unassigned 0x10F00, // 10F00..10F2F; Old Sogdian 0x10F30, // 10F30..10F6F; Sogdian 0x10F70, // unassigned + 0x10FB0, // 10FB0..10FDF; Chorasmian 0x10FE0, // 10FE0..10FFF; Elymaic 0x11000, // 11000..1107F; Brahmi 0x11080, // 11080..110CF; Kaithi @@ -3553,7 +3631,8 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x11800, // 11800..1184F; Dogra 0x11850, // unassigned 0x118A0, // 118A0..118FF; Warang Citi - 0x11900, // unassigned + 0x11900, // 11900..1195F; Dives Akuru + 0x11960, // unassigned 0x119A0, // 119A0..119FF; Nandinagari 0x11A00, // 11A00..11A4F; Zanabazar Square 0x11A50, // 11A50..11AAF; Soyombo @@ -3568,6 +3647,7 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x11DB0, // unassigned 0x11EE0, // 11EE0..11EFF; Makasar 0x11F00, // unassigned + 0x11FB0, // 11FB0..11FBF; Lisu Supplement 0x11FC0, // 11FC0..11FFF; Tamil Supplement 0x12000, // 12000..123FF; Cuneiform 0x12400, // 12400..1247F; Cuneiform Numbers and Punctuation @@ -3591,7 +3671,9 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x16FE0, // 16FE0..16FFF; Ideographic Symbols and Punctuation 0x17000, // 17000..187FF; Tangut 0x18800, // 18800..18AFF; Tangut Components - 0x18B00, // unassigned + 0x18B00, // 18B00..18CFF; Khitan Small Script + 0x18D00, // 18D00..18D8F; Tangut Supplement + 0x18D90, // unassigned 0x1B000, // 1B000..1B0FF; Kana Supplement 0x1B100, // 1B100..1B12F; Kana Extended-A 0x1B130, // 1B130..1B16F; Small Kana Extension @@ -3642,7 +3724,8 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x1F900, // 1F900..1F9FF; Supplemental Symbols and Pictographs 0x1FA00, // 1FA00..1FA6F; Chess Symbols 0x1FA70, // 1FA70..1FAFF; Symbols and Pictographs Extended-A - 0x1FB00, // unassigned + 0x1FB00, // 1FB00..1FBFF; Symbols for Legacy Computing + 0x1FC00, // unassigned 0x20000, // 20000..2A6DF; CJK Unified Ideographs Extension B 0x2A6E0, // unassigned 0x2A700, // 2A700..2B73F; CJK Unified Ideographs Extension C @@ -3652,6 +3735,8 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x2EBF0, // unassigned 0x2F800, // 2F800..2FA1F; CJK Compatibility Ideographs Supplement 0x2FA20, // unassigned + 0x30000, // 30000..3134F; CJK Unified Ideographs Extension G + 0x31350, // unassigned 0xE0000, // E0000..E007F; Tags 0xE0080, // unassigned 0xE0100, // E0100..E01EF; Variation Selectors Supplement @@ -3878,10 +3963,12 @@ class Character implements java.io.Serializable, Comparable, Constabl HANIFI_ROHINGYA, null, RUMI_NUMERAL_SYMBOLS, + YEZIDI, null, OLD_SOGDIAN, SOGDIAN, null, + CHORASMIAN, ELYMAIC, BRAHMI, KAITHI, @@ -3909,6 +3996,7 @@ class Character implements java.io.Serializable, Comparable, Constabl DOGRA, null, WARANG_CITI, + DIVES_AKURU, null, NANDINAGARI, ZANABAZAR_SQUARE, @@ -3924,6 +4012,7 @@ class Character implements java.io.Serializable, Comparable, Constabl null, MAKASAR, null, + LISU_SUPPLEMENT, TAMIL_SUPPLEMENT, CUNEIFORM, CUNEIFORM_NUMBERS_AND_PUNCTUATION, @@ -3947,6 +4036,8 @@ class Character implements java.io.Serializable, Comparable, Constabl IDEOGRAPHIC_SYMBOLS_AND_PUNCTUATION, TANGUT, TANGUT_COMPONENTS, + KHITAN_SMALL_SCRIPT, + TANGUT_SUPPLEMENT, null, KANA_SUPPLEMENT, KANA_EXTENDED_A, @@ -3998,6 +4089,7 @@ class Character implements java.io.Serializable, Comparable, Constabl SUPPLEMENTAL_SYMBOLS_AND_PICTOGRAPHS, CHESS_SYMBOLS, SYMBOLS_AND_PICTOGRAPHS_EXTENDED_A, + SYMBOLS_FOR_LEGACY_COMPUTING, null, CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B, null, @@ -4008,6 +4100,8 @@ class Character implements java.io.Serializable, Comparable, Constabl null, CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT, null, + CJK_UNIFIED_IDEOGRAPHS_EXTENSION_G, + null, TAGS, null, VARIATION_SELECTORS_SUPPLEMENT, @@ -4954,6 +5048,30 @@ class Character implements java.io.Serializable, Comparable, Constabl */ WANCHO, + /** + * Unicode script "Yezidi". + * @since 15 + */ + YEZIDI, + + /** + * Unicode script "Chorasmian". + * @since 15 + */ + CHORASMIAN, + + /** + * Unicode script "Dives Akuru". + * @since 15 + */ + DIVES_AKURU, + + /** + * Unicode script "Khitan Small Script". + * @since 15 + */ + KHITAN_SMALL_SCRIPT, + /** * Unicode script "Unknown". */ @@ -5007,9 +5125,7 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x0530, // 0530 ; UNKNOWN 0x0531, // 0531..0556; ARMENIAN 0x0557, // 0557..0558; UNKNOWN - 0x0559, // 0559..0588; ARMENIAN - 0x0589, // 0589 ; COMMON - 0x058A, // 058A ; ARMENIAN + 0x0559, // 0559..058A; ARMENIAN 0x058B, // 058B..058C; UNKNOWN 0x058D, // 058D..058F; ARMENIAN 0x0590, // 0590 ; UNKNOWN @@ -5061,8 +5177,8 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x086B, // 086B..089F; UNKNOWN 0x08A0, // 08A0..08B4; ARABIC 0x08B5, // 08B5 ; UNKNOWN - 0x08B6, // 08B6..08BD; ARABIC - 0x08BE, // 08BE..08D2; UNKNOWN + 0x08B6, // 08B6..08C7; ARABIC + 0x08C8, // 08C8..08D2; UNKNOWN 0x08D3, // 08D3..08E1; ARABIC 0x08E2, // 08E2 ; COMMON 0x08E3, // 08E3..08FF; ARABIC @@ -5178,8 +5294,8 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x0B47, // 0B47..0B48; ORIYA 0x0B49, // 0B49..0B4A; UNKNOWN 0x0B4B, // 0B4B..0B4D; ORIYA - 0x0B4E, // 0B4E..0B55; UNKNOWN - 0x0B56, // 0B56..0B57; ORIYA + 0x0B4E, // 0B4E..0B54; UNKNOWN + 0x0B55, // 0B55..0B57; ORIYA 0x0B58, // 0B58..0B5B; UNKNOWN 0x0B5C, // 0B5C..0B5D; ORIYA 0x0B5E, // 0B5E ; UNKNOWN @@ -5268,9 +5384,7 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x0CF0, // 0CF0 ; UNKNOWN 0x0CF1, // 0CF1..0CF2; KANNADA 0x0CF3, // 0CF3..0CFF; UNKNOWN - 0x0D00, // 0D00..0D03; MALAYALAM - 0x0D04, // 0D04 ; UNKNOWN - 0x0D05, // 0D05..0D0C; MALAYALAM + 0x0D00, // 0D00..0D0C; MALAYALAM 0x0D0D, // 0D0D ; UNKNOWN 0x0D0E, // 0D0E..0D10; MALAYALAM 0x0D11, // 0D11 ; UNKNOWN @@ -5283,8 +5397,8 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x0D54, // 0D54..0D63; MALAYALAM 0x0D64, // 0D64..0D65; UNKNOWN 0x0D66, // 0D66..0D7F; MALAYALAM - 0x0D80, // 0D80..0D81; UNKNOWN - 0x0D82, // 0D82..0D83; SINHALA + 0x0D80, // 0D80 ; UNKNOWN + 0x0D81, // 0D81..0D83; SINHALA 0x0D84, // 0D84 ; UNKNOWN 0x0D85, // 0D85..0D96; SINHALA 0x0D97, // 0D97..0D99; UNKNOWN @@ -5476,8 +5590,8 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x1A9A, // 1A9A..1A9F; UNKNOWN 0x1AA0, // 1AA0..1AAD; TAI_THAM 0x1AAE, // 1AAE..1AAF; UNKNOWN - 0x1AB0, // 1AB0..1ABE; INHERITED - 0x1ABF, // 1ABF..1AFF; UNKNOWN + 0x1AB0, // 1AB0..1AC0; INHERITED + 0x1AC1, // 1AC1..1AFF; UNKNOWN 0x1B00, // 1B00..1B4B; BALINESE 0x1B4C, // 1B4C..1B4F; UNKNOWN 0x1B50, // 1B50..1B7C; BALINESE @@ -5597,8 +5711,8 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x2900, // 2900..2B73; COMMON 0x2B74, // 2B74..2B75; UNKNOWN 0x2B76, // 2B76..2B95; COMMON - 0x2B96, // 2B96..2B97; UNKNOWN - 0x2B98, // 2B98..2BFF; COMMON + 0x2B96, // 2B96 ; UNKNOWN + 0x2B97, // 2B97..2BFF; COMMON 0x2C00, // 2C00..2C2E; GLAGOLITIC 0x2C2F, // 2C2F ; UNKNOWN 0x2C30, // 2C30..2C5E; GLAGOLITIC @@ -5637,8 +5751,8 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x2DD8, // 2DD8..2DDE; ETHIOPIC 0x2DDF, // 2DDF ; UNKNOWN 0x2DE0, // 2DE0..2DFF; CYRILLIC - 0x2E00, // 2E00..2E4F; COMMON - 0x2E50, // 2E50..2E7F; UNKNOWN + 0x2E00, // 2E00..2E52; COMMON + 0x2E53, // 2E53..2E7F; UNKNOWN 0x2E80, // 2E80..2E99; HAN 0x2E9A, // 2E9A ; UNKNOWN 0x2E9B, // 2E9B..2EF3; HAN @@ -5674,8 +5788,7 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x3131, // 3131..318E; HANGUL 0x318F, // 318F ; UNKNOWN 0x3190, // 3190..319F; COMMON - 0x31A0, // 31A0..31BA; BOPOMOFO - 0x31BB, // 31BB..31BF; UNKNOWN + 0x31A0, // 31A0..31BF; BOPOMOFO 0x31C0, // 31C0..31E3; COMMON 0x31E4, // 31E4..31EF; UNKNOWN 0x31F0, // 31F0..31FF; KATAKANA @@ -5688,11 +5801,10 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x32FF, // 32FF ; COMMON 0x3300, // 3300..3357; KATAKANA 0x3358, // 3358..33FF; COMMON - 0x3400, // 3400..4DB5; HAN - 0x4DB6, // 4DB6..4DBF; UNKNOWN + 0x3400, // 3400..4DBF; HAN 0x4DC0, // 4DC0..4DFF; COMMON - 0x4E00, // 4E00..9FEF; HAN - 0x9FF0, // 9FF0..9FFF; UNKNOWN + 0x4E00, // 4E00..9FFC; HAN + 0x9FFD, // 9FFD..9FFF; UNKNOWN 0xA000, // A000..A48C; YI 0xA48D, // A48D..A48F; UNKNOWN 0xA490, // A490..A4C6; YI @@ -5708,11 +5820,11 @@ class Character implements java.io.Serializable, Comparable, Constabl 0xA788, // A788..A78A; COMMON 0xA78B, // A78B..A7BF; LATIN 0xA7C0, // A7C0..A7C1; UNKNOWN - 0xA7C2, // A7C2..A7C6; LATIN - 0xA7C7, // A7C7..A7F6; UNKNOWN - 0xA7F7, // A7F7..A7FF; LATIN - 0xA800, // A800..A82B; SYLOTI_NAGRI - 0xA82C, // A82C..A82F; UNKNOWN + 0xA7C2, // A7C2..A7CA; LATIN + 0xA7CB, // A7CB..A7F4; UNKNOWN + 0xA7F5, // A7F5..A7FF; LATIN + 0xA800, // A800..A82C; SYLOTI_NAGRI + 0xA82D, // A82D..A82F; UNKNOWN 0xA830, // A830..A839; COMMON 0xA83A, // A83A..A83F; UNKNOWN 0xA840, // A840..A877; PHAGS_PA @@ -5765,8 +5877,9 @@ class Character implements java.io.Serializable, Comparable, Constabl 0xAB5B, // AB5B ; COMMON 0xAB5C, // AB5C..AB64; LATIN 0xAB65, // AB65 ; GREEK - 0xAB66, // AB66..AB67; LATIN - 0xAB68, // AB68..AB6F; UNKNOWN + 0xAB66, // AB66..AB69; LATIN + 0xAB6A, // AB6A..AB6B; COMMON + 0xAB6C, // AB6C..AB6F; UNKNOWN 0xAB70, // AB70..ABBF; CHEROKEE 0xABC0, // ABC0..ABED; MEETEI_MAYEK 0xABEE, // ABEE..ABEF; UNKNOWN @@ -5871,8 +5984,8 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x10137, // 10137..1013F; COMMON 0x10140, // 10140..1018E; GREEK 0x1018F, // 1018F ; UNKNOWN - 0x10190, // 10190..1019B; COMMON - 0x1019C, // 1019C..1019F; UNKNOWN + 0x10190, // 10190..1019C; COMMON + 0x1019D, // 1019D..1019F; UNKNOWN 0x101A0, // 101A0 ; GREEK 0x101A1, // 101A1..101CF; UNKNOWN 0x101D0, // 101D0..101FC; COMMON @@ -6008,11 +6121,19 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x10D30, // 10D30..10D39; HANIFI_ROHINGYA 0x10D3A, // 10D3A..10E5F; UNKNOWN 0x10E60, // 10E60..10E7E; ARABIC - 0x10E7F, // 10E7F..10EFF; UNKNOWN + 0x10E7F, // 10E7F ; UNKNOWN + 0x10E80, // 10E80..10EA9; YEZIDI + 0x10EAA, // 10EAA ; UNKNOWN + 0x10EAB, // 10EAB..10EAD; YEZIDI + 0x10EAE, // 10EAE..10EAF; UNKNOWN + 0x10EB0, // 10EB0..10EB1; YEZIDI + 0x10EB2, // 10EB2..10EFF; UNKNOWN 0x10F00, // 10F00..10F27; OLD_SOGDIAN 0x10F28, // 10F28..10F2F; UNKNOWN 0x10F30, // 10F30..10F59; SOGDIAN - 0x10F5A, // 10F5A..10FDF; UNKNOWN + 0x10F5A, // 10F5A..10FAF; UNKNOWN + 0x10FB0, // 10FB0..10FCB; CHORASMIAN + 0x10FCC, // 10FCC..10FDF; UNKNOWN 0x10FE0, // 10FE0..10FF6; ELYMAIC 0x10FF7, // 10FF7..10FFF; UNKNOWN 0x11000, // 11000..1104D; BRAHMI @@ -6030,13 +6151,11 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x110FA, // 110FA..110FF; UNKNOWN 0x11100, // 11100..11134; CHAKMA 0x11135, // 11135 ; UNKNOWN - 0x11136, // 11136..11146; CHAKMA - 0x11147, // 11147..1114F; UNKNOWN + 0x11136, // 11136..11147; CHAKMA + 0x11148, // 11148..1114F; UNKNOWN 0x11150, // 11150..11176; MAHAJANI 0x11177, // 11177..1117F; UNKNOWN - 0x11180, // 11180..111CD; SHARADA - 0x111CE, // 111CE..111CF; UNKNOWN - 0x111D0, // 111D0..111DF; SHARADA + 0x11180, // 11180..111DF; SHARADA 0x111E0, // 111E0 ; UNKNOWN 0x111E1, // 111E1..111F4; SINHALA 0x111F5, // 111F5..111FF; UNKNOWN @@ -6089,12 +6208,10 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x1136D, // 1136D..1136F; UNKNOWN 0x11370, // 11370..11374; GRANTHA 0x11375, // 11375..113FF; UNKNOWN - 0x11400, // 11400..11459; NEWA - 0x1145A, // 1145A ; UNKNOWN - 0x1145B, // 1145B ; NEWA + 0x11400, // 11400..1145B; NEWA 0x1145C, // 1145C ; UNKNOWN - 0x1145D, // 1145D..1145F; NEWA - 0x11460, // 11460..1147F; UNKNOWN + 0x1145D, // 1145D..11461; NEWA + 0x11462, // 11462..1147F; UNKNOWN 0x11480, // 11480..114C7; TIRHUTA 0x114C8, // 114C8..114CF; UNKNOWN 0x114D0, // 114D0..114D9; TIRHUTA @@ -6124,7 +6241,22 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x118A0, // 118A0..118F2; WARANG_CITI 0x118F3, // 118F3..118FE; UNKNOWN 0x118FF, // 118FF ; WARANG_CITI - 0x11900, // 11900..1199F; UNKNOWN + 0x11900, // 11900..11906; DIVES_AKURU + 0x11907, // 11907..11908; UNKNOWN + 0x11909, // 11909 ; DIVES_AKURU + 0x1190A, // 1190A..1190B; UNKNOWN + 0x1190C, // 1190C..11913; DIVES_AKURU + 0x11914, // 11914 ; UNKNOWN + 0x11915, // 11915..11916; DIVES_AKURU + 0x11917, // 11917 ; UNKNOWN + 0x11918, // 11918..11935; DIVES_AKURU + 0x11936, // 11936 ; UNKNOWN + 0x11937, // 11937..11938; DIVES_AKURU + 0x11939, // 11939..1193A; UNKNOWN + 0x1193B, // 1193B..11946; DIVES_AKURU + 0x11947, // 11947..1194F; UNKNOWN + 0x11950, // 11950..11959; DIVES_AKURU + 0x1195A, // 1195A..1199F; UNKNOWN 0x119A0, // 119A0..119A7; NANDINAGARI 0x119A8, // 119A8..119A9; UNKNOWN 0x119AA, // 119AA..119D7; NANDINAGARI @@ -6178,7 +6310,9 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x11DA0, // 11DA0..11DA9; GUNJALA_GONDI 0x11DAA, // 11DAA..11EDF; UNKNOWN 0x11EE0, // 11EE0..11EF8; MAKASAR - 0x11EF9, // 11EF9..11FBF; UNKNOWN + 0x11EF9, // 11EF9..11FAF; UNKNOWN + 0x11FB0, // 11FB0 ; LISU + 0x11FB1, // 11FB1..11FBF; UNKNOWN 0x11FC0, // 11FC0..11FF1; TAMIL 0x11FF2, // 11FF2..11FFE; UNKNOWN 0x11FFF, // 11FFF ; TAMIL @@ -6229,11 +6363,17 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x16FE0, // 16FE0 ; TANGUT 0x16FE1, // 16FE1 ; NUSHU 0x16FE2, // 16FE2..16FE3; COMMON - 0x16FE4, // 16FE4..16FFF; UNKNOWN + 0x16FE4, // 16FE4 ; KHITAN_SMALL_SCRIPT + 0x16FE5, // 16FE5..16FEF; UNKNOWN + 0x16FF0, // 16FF0..16FF1; HAN + 0x16FF2, // 16FF2..16FFF; UNKNOWN 0x17000, // 17000..187F7; TANGUT 0x187F8, // 187F8..187FF; UNKNOWN - 0x18800, // 18800..18AF2; TANGUT - 0x18AF3, // 18AF3..1AFFF; UNKNOWN + 0x18800, // 18800..18AFF; TANGUT + 0x18B00, // 18B00..18CD5; KHITAN_SMALL_SCRIPT + 0x18CD6, // 18CD6..18CFF; UNKNOWN + 0x18D00, // 18D00..18D08; TANGUT + 0x18D09, // 18D09..1AFFF; UNKNOWN 0x1B000, // 1B000 ; KATAKANA 0x1B001, // 1B001..1B11E; HIRAGANA 0x1B11F, // 1B11F..1B14F; UNKNOWN @@ -6439,12 +6579,8 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x1F0D0, // 1F0D0 ; UNKNOWN 0x1F0D1, // 1F0D1..1F0F5; COMMON 0x1F0F6, // 1F0F6..1F0FF; UNKNOWN - 0x1F100, // 1F100..1F10C; COMMON - 0x1F10D, // 1F10D..1F10F; UNKNOWN - 0x1F110, // 1F110..1F16C; COMMON - 0x1F16D, // 1F16D..1F16F; UNKNOWN - 0x1F170, // 1F170..1F1AC; COMMON - 0x1F1AD, // 1F1AD..1F1E5; UNKNOWN + 0x1F100, // 1F100..1F1AD; COMMON + 0x1F1AE, // 1F1AE..1F1E5; UNKNOWN 0x1F1E6, // 1F1E6..1F1FF; COMMON 0x1F200, // 1F200 ; HIRAGANA 0x1F201, // 1F201..1F202; COMMON @@ -6457,12 +6593,12 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x1F252, // 1F252..1F25F; UNKNOWN 0x1F260, // 1F260..1F265; COMMON 0x1F266, // 1F266..1F2FF; UNKNOWN - 0x1F300, // 1F300..1F6D5; COMMON - 0x1F6D6, // 1F6D6..1F6DF; UNKNOWN + 0x1F300, // 1F300..1F6D7; COMMON + 0x1F6D8, // 1F6D8..1F6DF; UNKNOWN 0x1F6E0, // 1F6E0..1F6EC; COMMON 0x1F6ED, // 1F6ED..1F6EF; UNKNOWN - 0x1F6F0, // 1F6F0..1F6FA; COMMON - 0x1F6FB, // 1F6FB..1F6FF; UNKNOWN + 0x1F6F0, // 1F6F0..1F6FC; COMMON + 0x1F6FD, // 1F6FD..1F6FF; UNKNOWN 0x1F700, // 1F700..1F773; COMMON 0x1F774, // 1F774..1F77F; UNKNOWN 0x1F780, // 1F780..1F7D8; COMMON @@ -6478,33 +6614,39 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x1F860, // 1F860..1F887; COMMON 0x1F888, // 1F888..1F88F; UNKNOWN 0x1F890, // 1F890..1F8AD; COMMON - 0x1F8AE, // 1F8AE..1F8FF; UNKNOWN - 0x1F900, // 1F900..1F90B; COMMON - 0x1F90C, // 1F90C ; UNKNOWN - 0x1F90D, // 1F90D..1F971; COMMON - 0x1F972, // 1F972 ; UNKNOWN - 0x1F973, // 1F973..1F976; COMMON - 0x1F977, // 1F977..1F979; UNKNOWN - 0x1F97A, // 1F97A..1F9A2; COMMON - 0x1F9A3, // 1F9A3..1F9A4; UNKNOWN - 0x1F9A5, // 1F9A5..1F9AA; COMMON - 0x1F9AB, // 1F9AB..1F9AD; UNKNOWN - 0x1F9AE, // 1F9AE..1F9CA; COMMON - 0x1F9CB, // 1F9CB..1F9CC; UNKNOWN + 0x1F8AE, // 1F8AE..1F8AF; UNKNOWN + 0x1F8B0, // 1F8B0..1F8B1; COMMON + 0x1F8B2, // 1F8B2..1F8FF; UNKNOWN + 0x1F900, // 1F900..1F978; COMMON + 0x1F979, // 1F979 ; UNKNOWN + 0x1F97A, // 1F97A..1F9CB; COMMON + 0x1F9CC, // 1F9CC ; UNKNOWN 0x1F9CD, // 1F9CD..1FA53; COMMON 0x1FA54, // 1FA54..1FA5F; UNKNOWN 0x1FA60, // 1FA60..1FA6D; COMMON 0x1FA6E, // 1FA6E..1FA6F; UNKNOWN - 0x1FA70, // 1FA70..1FA73; COMMON - 0x1FA74, // 1FA74..1FA77; UNKNOWN + 0x1FA70, // 1FA70..1FA74; COMMON + 0x1FA75, // 1FA75..1FA77; UNKNOWN 0x1FA78, // 1FA78..1FA7A; COMMON 0x1FA7B, // 1FA7B..1FA7F; UNKNOWN - 0x1FA80, // 1FA80..1FA82; COMMON - 0x1FA83, // 1FA83..1FA8F; UNKNOWN - 0x1FA90, // 1FA90..1FA95; COMMON - 0x1FA96, // 1FA96..1FFFF; UNKNOWN - 0x20000, // 20000..2A6D6; HAN - 0x2A6D7, // 2A6D7..2A6FF; UNKNOWN + 0x1FA80, // 1FA80..1FA86; COMMON + 0x1FA87, // 1FA87..1FA8F; UNKNOWN + 0x1FA90, // 1FA90..1FAA8; COMMON + 0x1FAA9, // 1FAA9..1FAAF; UNKNOWN + 0x1FAB0, // 1FAB0..1FAB6; COMMON + 0x1FAB7, // 1FAB7..1FABF; UNKNOWN + 0x1FAC0, // 1FAC0..1FAC2; COMMON + 0x1FAC3, // 1FAC3..1FACF; UNKNOWN + 0x1FAD0, // 1FAD0..1FAD6; COMMON + 0x1FAD7, // 1FAD7..1FAFF; UNKNOWN + 0x1FB00, // 1FB00..1FB92; COMMON + 0x1FB93, // 1FB93 ; UNKNOWN + 0x1FB94, // 1FB94..1FBCA; COMMON + 0x1FBCB, // 1FBCB..1FBEF; UNKNOWN + 0x1FBF0, // 1FBF0..1FBF9; COMMON + 0x1FBFA, // 1FBFA..1FFFF; UNKNOWN + 0x20000, // 20000..2A6DD; HAN + 0x2A6DE, // 2A6DE..2A6FF; UNKNOWN 0x2A700, // 2A700..2B734; HAN 0x2B735, // 2B735..2B73F; UNKNOWN 0x2B740, // 2B740..2B81D; HAN @@ -6514,7 +6656,9 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x2CEB0, // 2CEB0..2EBE0; HAN 0x2EBE1, // 2EBE1..2F7FF; UNKNOWN 0x2F800, // 2F800..2FA1D; HAN - 0x2FA1E, // 2FA1E..E0000; UNKNOWN + 0x2FA1E, // 2FA1E..2FFFF; UNKNOWN + 0x30000, // 30000..3134A; HAN + 0x3134B, // 3134B..E0000; UNKNOWN 0xE0001, // E0001 ; COMMON 0xE0002, // E0002..E001F; UNKNOWN 0xE0020, // E0020..E007F; COMMON @@ -6571,9 +6715,7 @@ class Character implements java.io.Serializable, Comparable, Constabl UNKNOWN, // 0530 ARMENIAN, // 0531..0556 UNKNOWN, // 0557..0558 - ARMENIAN, // 0559..0588 - COMMON, // 0589 - ARMENIAN, // 058A + ARMENIAN, // 0559..058A UNKNOWN, // 058B..058C ARMENIAN, // 058D..058F UNKNOWN, // 0590 @@ -6625,8 +6767,8 @@ class Character implements java.io.Serializable, Comparable, Constabl UNKNOWN, // 086B..089F ARABIC, // 08A0..08B4 UNKNOWN, // 08B5 - ARABIC, // 08B6..08BD - UNKNOWN, // 08BE..08D2 + ARABIC, // 08B6..08C7 + UNKNOWN, // 08C8..08D2 ARABIC, // 08D3..08E1 COMMON, // 08E2 ARABIC, // 08E3..08FF @@ -6742,8 +6884,8 @@ class Character implements java.io.Serializable, Comparable, Constabl ORIYA, // 0B47..0B48 UNKNOWN, // 0B49..0B4A ORIYA, // 0B4B..0B4D - UNKNOWN, // 0B4E..0B55 - ORIYA, // 0B56..0B57 + UNKNOWN, // 0B4E..0B54 + ORIYA, // 0B55..0B57 UNKNOWN, // 0B58..0B5B ORIYA, // 0B5C..0B5D UNKNOWN, // 0B5E @@ -6832,9 +6974,7 @@ class Character implements java.io.Serializable, Comparable, Constabl UNKNOWN, // 0CF0 KANNADA, // 0CF1..0CF2 UNKNOWN, // 0CF3..0CFF - MALAYALAM, // 0D00..0D03 - UNKNOWN, // 0D04 - MALAYALAM, // 0D05..0D0C + MALAYALAM, // 0D00..0D0C UNKNOWN, // 0D0D MALAYALAM, // 0D0E..0D10 UNKNOWN, // 0D11 @@ -6847,8 +6987,8 @@ class Character implements java.io.Serializable, Comparable, Constabl MALAYALAM, // 0D54..0D63 UNKNOWN, // 0D64..0D65 MALAYALAM, // 0D66..0D7F - UNKNOWN, // 0D80..0D81 - SINHALA, // 0D82..0D83 + UNKNOWN, // 0D80 + SINHALA, // 0D81..0D83 UNKNOWN, // 0D84 SINHALA, // 0D85..0D96 UNKNOWN, // 0D97..0D99 @@ -7040,8 +7180,8 @@ class Character implements java.io.Serializable, Comparable, Constabl UNKNOWN, // 1A9A..1A9F TAI_THAM, // 1AA0..1AAD UNKNOWN, // 1AAE..1AAF - INHERITED, // 1AB0..1ABE - UNKNOWN, // 1ABF..1AFF + INHERITED, // 1AB0..1AC0 + UNKNOWN, // 1AC1..1AFF BALINESE, // 1B00..1B4B UNKNOWN, // 1B4C..1B4F BALINESE, // 1B50..1B7C @@ -7161,8 +7301,8 @@ class Character implements java.io.Serializable, Comparable, Constabl COMMON, // 2900..2B73 UNKNOWN, // 2B74..2B75 COMMON, // 2B76..2B95 - UNKNOWN, // 2B96..2B97 - COMMON, // 2B98..2BFF + UNKNOWN, // 2B96 + COMMON, // 2B97..2BFF GLAGOLITIC, // 2C00..2C2E UNKNOWN, // 2C2F GLAGOLITIC, // 2C30..2C5E @@ -7201,8 +7341,8 @@ class Character implements java.io.Serializable, Comparable, Constabl ETHIOPIC, // 2DD8..2DDE UNKNOWN, // 2DDF CYRILLIC, // 2DE0..2DFF - COMMON, // 2E00..2E4F - UNKNOWN, // 2E50..2E7F + COMMON, // 2E00..2E52 + UNKNOWN, // 2E53..2E7F HAN, // 2E80..2E99 UNKNOWN, // 2E9A HAN, // 2E9B..2EF3 @@ -7238,8 +7378,7 @@ class Character implements java.io.Serializable, Comparable, Constabl HANGUL, // 3131..318E UNKNOWN, // 318F COMMON, // 3190..319F - BOPOMOFO, // 31A0..31BA - UNKNOWN, // 31BB..31BF + BOPOMOFO, // 31A0..31BF COMMON, // 31C0..31E3 UNKNOWN, // 31E4..31EF KATAKANA, // 31F0..31FF @@ -7252,11 +7391,10 @@ class Character implements java.io.Serializable, Comparable, Constabl COMMON, // 32FF KATAKANA, // 3300..3357 COMMON, // 3358..33FF - HAN, // 3400..4DB5 - UNKNOWN, // 4DB6..4DBF + HAN, // 3400..4DBF COMMON, // 4DC0..4DFF - HAN, // 4E00..9FEF - UNKNOWN, // 9FF0..9FFF + HAN, // 4E00..9FFC + UNKNOWN, // 9FFD..9FFF YI, // A000..A48C UNKNOWN, // A48D..A48F YI, // A490..A4C6 @@ -7272,11 +7410,11 @@ class Character implements java.io.Serializable, Comparable, Constabl COMMON, // A788..A78A LATIN, // A78B..A7BF UNKNOWN, // A7C0..A7C1 - LATIN, // A7C2..A7C6 - UNKNOWN, // A7C7..A7F6 - LATIN, // A7F7..A7FF - SYLOTI_NAGRI, // A800..A82B - UNKNOWN, // A82C..A82F + LATIN, // A7C2..A7CA + UNKNOWN, // A7CB..A7F4 + LATIN, // A7F5..A7FF + SYLOTI_NAGRI, // A800..A82C + UNKNOWN, // A82D..A82F COMMON, // A830..A839 UNKNOWN, // A83A..A83F PHAGS_PA, // A840..A877 @@ -7329,8 +7467,9 @@ class Character implements java.io.Serializable, Comparable, Constabl COMMON, // AB5B LATIN, // AB5C..AB64 GREEK, // AB65 - LATIN, // AB66..AB67 - UNKNOWN, // AB68..AB6F + LATIN, // AB66..AB69 + COMMON, // AB6A..AB6B + UNKNOWN, // AB6C..AB6F CHEROKEE, // AB70..ABBF MEETEI_MAYEK, // ABC0..ABED UNKNOWN, // ABEE..ABEF @@ -7435,8 +7574,8 @@ class Character implements java.io.Serializable, Comparable, Constabl COMMON, // 10137..1013F GREEK, // 10140..1018E UNKNOWN, // 1018F - COMMON, // 10190..1019B - UNKNOWN, // 1019C..1019F + COMMON, // 10190..1019C + UNKNOWN, // 1019D..1019F GREEK, // 101A0 UNKNOWN, // 101A1..101CF COMMON, // 101D0..101FC @@ -7572,11 +7711,19 @@ class Character implements java.io.Serializable, Comparable, Constabl HANIFI_ROHINGYA, // 10D30..10D39 UNKNOWN, // 10D3A..10E5F ARABIC, // 10E60..10E7E - UNKNOWN, // 10E7F..10EFF + UNKNOWN, // 10E7F + YEZIDI, // 10E80..10EA9 + UNKNOWN, // 10EAA + YEZIDI, // 10EAB..10EAD + UNKNOWN, // 10EAE..10EAF + YEZIDI, // 10EB0..10EB1 + UNKNOWN, // 10EB2..10EFF OLD_SOGDIAN, // 10F00..10F27 UNKNOWN, // 10F28..10F2F SOGDIAN, // 10F30..10F59 - UNKNOWN, // 10F5A..10FDF + UNKNOWN, // 10F5A..10FAF + CHORASMIAN, // 10FB0..10FCB + UNKNOWN, // 10FCC..10FDF ELYMAIC, // 10FE0..10FF6 UNKNOWN, // 10FF7..10FFF BRAHMI, // 11000..1104D @@ -7594,13 +7741,11 @@ class Character implements java.io.Serializable, Comparable, Constabl UNKNOWN, // 110FA..110FF CHAKMA, // 11100..11134 UNKNOWN, // 11135 - CHAKMA, // 11136..11146 - UNKNOWN, // 11147..1114F + CHAKMA, // 11136..11147 + UNKNOWN, // 11148..1114F MAHAJANI, // 11150..11176 UNKNOWN, // 11177..1117F - SHARADA, // 11180..111CD - UNKNOWN, // 111CE..111CF - SHARADA, // 111D0..111DF + SHARADA, // 11180..111DF UNKNOWN, // 111E0 SINHALA, // 111E1..111F4 UNKNOWN, // 111F5..111FF @@ -7653,12 +7798,10 @@ class Character implements java.io.Serializable, Comparable, Constabl UNKNOWN, // 1136D..1136F GRANTHA, // 11370..11374 UNKNOWN, // 11375..113FF - NEWA, // 11400..11459 - UNKNOWN, // 1145A - NEWA, // 1145B + NEWA, // 11400..1145B UNKNOWN, // 1145C - NEWA, // 1145D..1145F - UNKNOWN, // 11460..1147F + NEWA, // 1145D..11461 + UNKNOWN, // 11462..1147F TIRHUTA, // 11480..114C7 UNKNOWN, // 114C8..114CF TIRHUTA, // 114D0..114D9 @@ -7688,7 +7831,22 @@ class Character implements java.io.Serializable, Comparable, Constabl WARANG_CITI, // 118A0..118F2 UNKNOWN, // 118F3..118FE WARANG_CITI, // 118FF - UNKNOWN, // 11900..1199F + DIVES_AKURU, // 11900..11906 + UNKNOWN, // 11907..11908 + DIVES_AKURU, // 11909 + UNKNOWN, // 1190A..1190B + DIVES_AKURU, // 1190C..11913 + UNKNOWN, // 11914 + DIVES_AKURU, // 11915..11916 + UNKNOWN, // 11917 + DIVES_AKURU, // 11918..11935 + UNKNOWN, // 11936 + DIVES_AKURU, // 11937..11938 + UNKNOWN, // 11939..1193A + DIVES_AKURU, // 1193B..11946 + UNKNOWN, // 11947..1194F + DIVES_AKURU, // 11950..11959 + UNKNOWN, // 1195A..1199F NANDINAGARI, // 119A0..119A7 UNKNOWN, // 119A8..119A9 NANDINAGARI, // 119AA..119D7 @@ -7742,7 +7900,9 @@ class Character implements java.io.Serializable, Comparable, Constabl GUNJALA_GONDI, // 11DA0..11DA9 UNKNOWN, // 11DAA..11EDF MAKASAR, // 11EE0..11EF8 - UNKNOWN, // 11EF9..11FBF + UNKNOWN, // 11EF9..11FAF + LISU, // 11FB0 + UNKNOWN, // 11FB1..11FBF TAMIL, // 11FC0..11FF1 UNKNOWN, // 11FF2..11FFE TAMIL, // 11FFF @@ -7793,11 +7953,17 @@ class Character implements java.io.Serializable, Comparable, Constabl TANGUT, // 16FE0 NUSHU, // 16FE1 COMMON, // 16FE2..16FE3 - UNKNOWN, // 16FE4..16FFF + KHITAN_SMALL_SCRIPT, // 16FE4 + UNKNOWN, // 16FE5..16FEF + HAN, // 16FF0..16FF1 + UNKNOWN, // 16FF2..16FFF TANGUT, // 17000..187F7 UNKNOWN, // 187F8..187FF - TANGUT, // 18800..18AF2 - UNKNOWN, // 18AF3..1AFFF + TANGUT, // 18800..18AFF + KHITAN_SMALL_SCRIPT, // 18B00..18CD5 + UNKNOWN, // 18CD6..18CFF + TANGUT, // 18D00..18D08 + UNKNOWN, // 18D09..1AFFF KATAKANA, // 1B000 HIRAGANA, // 1B001..1B11E UNKNOWN, // 1B11F..1B14F @@ -8003,12 +8169,8 @@ class Character implements java.io.Serializable, Comparable, Constabl UNKNOWN, // 1F0D0 COMMON, // 1F0D1..1F0F5 UNKNOWN, // 1F0F6..1F0FF - COMMON, // 1F100..1F10C - UNKNOWN, // 1F10D..1F10F - COMMON, // 1F110..1F16C - UNKNOWN, // 1F16D..1F16F - COMMON, // 1F170..1F1AC - UNKNOWN, // 1F1AD..1F1E5 + COMMON, // 1F100..1F1AD + UNKNOWN, // 1F1AE..1F1E5 COMMON, // 1F1E6..1F1FF HIRAGANA, // 1F200 COMMON, // 1F201..1F202 @@ -8021,12 +8183,12 @@ class Character implements java.io.Serializable, Comparable, Constabl UNKNOWN, // 1F252..1F25F COMMON, // 1F260..1F265 UNKNOWN, // 1F266..1F2FF - COMMON, // 1F300..1F6D5 - UNKNOWN, // 1F6D6..1F6DF + COMMON, // 1F300..1F6D7 + UNKNOWN, // 1F6D8..1F6DF COMMON, // 1F6E0..1F6EC UNKNOWN, // 1F6ED..1F6EF - COMMON, // 1F6F0..1F6FA - UNKNOWN, // 1F6FB..1F6FF + COMMON, // 1F6F0..1F6FC + UNKNOWN, // 1F6FD..1F6FF COMMON, // 1F700..1F773 UNKNOWN, // 1F774..1F77F COMMON, // 1F780..1F7D8 @@ -8042,33 +8204,39 @@ class Character implements java.io.Serializable, Comparable, Constabl COMMON, // 1F860..1F887 UNKNOWN, // 1F888..1F88F COMMON, // 1F890..1F8AD - UNKNOWN, // 1F8AE..1F8FF - COMMON, // 1F900..1F90B - UNKNOWN, // 1F90C - COMMON, // 1F90D..1F971 - UNKNOWN, // 1F972 - COMMON, // 1F973..1F976 - UNKNOWN, // 1F977..1F979 - COMMON, // 1F97A..1F9A2 - UNKNOWN, // 1F9A3..1F9A4 - COMMON, // 1F9A5..1F9AA - UNKNOWN, // 1F9AB..1F9AD - COMMON, // 1F9AE..1F9CA - UNKNOWN, // 1F9CB..1F9CC + UNKNOWN, // 1F8AE..1F8AF + COMMON, // 1F8B0..1F8B1 + UNKNOWN, // 1F8B2..1F8FF + COMMON, // 1F900..1F978 + UNKNOWN, // 1F979 + COMMON, // 1F97A..1F9CB + UNKNOWN, // 1F9CC COMMON, // 1F9CD..1FA53 UNKNOWN, // 1FA54..1FA5F COMMON, // 1FA60..1FA6D UNKNOWN, // 1FA6E..1FA6F - COMMON, // 1FA70..1FA73 - UNKNOWN, // 1FA74..1FA77 + COMMON, // 1FA70..1FA74 + UNKNOWN, // 1FA75..1FA77 COMMON, // 1FA78..1FA7A UNKNOWN, // 1FA7B..1FA7F - COMMON, // 1FA80..1FA82 - UNKNOWN, // 1FA83..1FA8F - COMMON, // 1FA90..1FA95 - UNKNOWN, // 1FA96..1FFFF - HAN, // 20000..2A6D6 - UNKNOWN, // 2A6D7..2A6FF + COMMON, // 1FA80..1FA86 + UNKNOWN, // 1FA87..1FA8F + COMMON, // 1FA90..1FAA8 + UNKNOWN, // 1FAA9..1FAAF + COMMON, // 1FAB0..1FAB6 + UNKNOWN, // 1FAB7..1FABF + COMMON, // 1FAC0..1FAC2 + UNKNOWN, // 1FAC3..1FACF + COMMON, // 1FAD0..1FAD6 + UNKNOWN, // 1FAD7..1FAFF + COMMON, // 1FB00..1FB92 + UNKNOWN, // 1FB93 + COMMON, // 1FB94..1FBCA + UNKNOWN, // 1FBCB..1FBEF + COMMON, // 1FBF0..1FBF9 + UNKNOWN, // 1FBFA..1FFFF + HAN, // 20000..2A6DD + UNKNOWN, // 2A6DE..2A6FF HAN, // 2A700..2B734 UNKNOWN, // 2B735..2B73F HAN, // 2B740..2B81D @@ -8078,7 +8246,9 @@ class Character implements java.io.Serializable, Comparable, Constabl HAN, // 2CEB0..2EBE0 UNKNOWN, // 2EBE1..2F7FF HAN, // 2F800..2FA1D - UNKNOWN, // 2FA1E..E0000 + UNKNOWN, // 2FA1E..2FFFF + HAN, // 30000..3134A + UNKNOWN, // 3134B..E0000 COMMON, // E0001 UNKNOWN, // E0002..E001F COMMON, // E0020..E007F @@ -8089,7 +8259,7 @@ class Character implements java.io.Serializable, Comparable, Constabl private static final HashMap aliases; static { - aliases = new HashMap<>((int)(153 / 0.75f + 1.0f)); + aliases = new HashMap<>((int)(157 / 0.75f + 1.0f)); aliases.put("ADLM", ADLAM); aliases.put("AGHB", CAUCASIAN_ALBANIAN); aliases.put("AHOM", AHOM); @@ -8113,10 +8283,12 @@ class Character implements java.io.Serializable, Comparable, Constabl aliases.put("CARI", CARIAN); aliases.put("CHAM", CHAM); aliases.put("CHER", CHEROKEE); + aliases.put("CHRS", CHORASMIAN); aliases.put("COPT", COPTIC); aliases.put("CPRT", CYPRIOT); aliases.put("CYRL", CYRILLIC); aliases.put("DEVA", DEVANAGARI); + aliases.put("DIAK", DIVES_AKURU); aliases.put("DOGR", DOGRA); aliases.put("DSRT", DESERET); aliases.put("DUPL", DUPLOYAN); @@ -8152,6 +8324,7 @@ class Character implements java.io.Serializable, Comparable, Constabl aliases.put("KHAR", KHAROSHTHI); aliases.put("KHMR", KHMER); aliases.put("KHOJ", KHOJKI); + aliases.put("KITS", KHITAN_SMALL_SCRIPT); aliases.put("KNDA", KANNADA); aliases.put("KTHI", KAITHI); aliases.put("LANA", TAI_THAM); @@ -8241,6 +8414,7 @@ class Character implements java.io.Serializable, Comparable, Constabl aliases.put("XPEO", OLD_PERSIAN); aliases.put("XSUX", CUNEIFORM); aliases.put("YIII", YI); + aliases.put("YEZI", YEZIDI); aliases.put("ZANB", ZANABAZAR_SQUARE); aliases.put("ZINH", INHERITED); aliases.put("ZYYY", COMMON); diff --git a/src/java.base/share/classes/java/lang/CharacterData.java b/src/java.base/share/classes/java/lang/CharacterData.java index 1cc296fa82a..55cef5a9a06 100644 --- a/src/java.base/share/classes/java/lang/CharacterData.java +++ b/src/java.base/share/classes/java/lang/CharacterData.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 @@ -87,6 +87,8 @@ abstract class CharacterData { return CharacterData01.instance; case(2): return CharacterData02.instance; + case(3): + return CharacterData03.instance; case(14): return CharacterData0E.instance; case(15): // Private Use diff --git a/src/java.base/share/classes/java/util/regex/Grapheme.java b/src/java.base/share/classes/java/util/regex/Grapheme.java index af5bd6b0413..550415e3559 100644 --- a/src/java.base/share/classes/java/util/regex/Grapheme.java +++ b/src/java.base/share/classes/java/util/regex/Grapheme.java @@ -266,6 +266,8 @@ final class Grapheme { case 0x0D4E: case 0x111C2: case 0x111C3: + case 0x1193F: + case 0x11941: case 0x11A3A: case 0x11A84: case 0x11A85: diff --git a/src/java.base/share/classes/jdk/internal/icu/impl/UCharacterProperty.java b/src/java.base/share/classes/jdk/internal/icu/impl/UCharacterProperty.java index 3e6781f4c17..474b169e6e2 100644 --- a/src/java.base/share/classes/jdk/internal/icu/impl/UCharacterProperty.java +++ b/src/java.base/share/classes/jdk/internal/icu/impl/UCharacterProperty.java @@ -372,21 +372,30 @@ public final class UCharacterProperty * Properties in vector word 0 * Bits * 31..24 DerivedAge version major/minor one nibble each - * 23..22 3..1: Bits 7..0 = Script_Extensions index + * 23..22 3..1: Bits 21..20 & 7..0 = Script_Extensions index * 3: Script value from Script_Extensions * 2: Script=Inherited * 1: Script=Common - * 0: Script=bits 7..0 - * 21..20 reserved + * 0: Script=bits 21..20 & 7..0 + * 21..20 Bits 9..8 of the UScriptCode, or index to Script_Extensions * 19..17 East Asian Width * 16.. 8 UBlockCode - * 7.. 0 UScriptCode + * 7.. 0 UScriptCode, or index to Script_Extensions */ + /** * Script_Extensions: mask includes Script */ - public static final int SCRIPT_X_MASK = 0x00c000ff; + public static final int SCRIPT_X_MASK = 0x00f000ff; //private static final int SCRIPT_X_SHIFT = 22; + + // The UScriptCode or Script_Extensions index is split across two bit fields. + // (Starting with Unicode 13/ICU 66/2019 due to more varied Script_Extensions.) + // Shift the high bits right by 12 to assemble the full value. + public static final int SCRIPT_HIGH_MASK = 0x00300000; + public static final int SCRIPT_HIGH_SHIFT = 12; + public static final int MAX_SCRIPT = 0x3ff; + /** * Integer properties mask and shift values for East Asian cell width. * Equivalent to icu4c UPROPS_EA_MASK @@ -409,9 +418,15 @@ public final class UCharacterProperty private static final int BLOCK_SHIFT_ = 8; /** * Integer properties mask and shift values for scripts. - * Equivalent to icu4c UPROPS_SHIFT_MASK + * Equivalent to icu4c UPROPS_SHIFT_LOW_MASK. */ - public static final int SCRIPT_MASK_ = 0x000000ff; + public static final int SCRIPT_LOW_MASK = 0x000000ff; + + public static final int mergeScriptCodeOrIndex(int scriptX) { + return + ((scriptX & SCRIPT_HIGH_MASK) >> SCRIPT_HIGH_SHIFT) | + (scriptX & SCRIPT_LOW_MASK); + } /** * Additional properties used in internal trie data diff --git a/src/java.base/share/classes/jdk/internal/icu/impl/data/icudt64b/nfkc.nrm b/src/java.base/share/classes/jdk/internal/icu/impl/data/icudt64b/nfkc.nrm deleted file mode 100644 index 2dd1940b4b51aa737c0d6355f53f24f1ade78f74..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53856 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 diff --git a/src/java.base/share/classes/jdk/internal/icu/impl/data/icudt64b/uprops.icu b/src/java.base/share/classes/jdk/internal/icu/impl/data/icudt64b/uprops.icu deleted file mode 100644 index 9d1b3e3bf9f418902bd52baf5a34e07e7e438a85..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 133040 zcmeF42e{Nk_wchNWs~e?ceDN83#cF#?4a1OVBuQ8-o@T477$TTQQ%rYMX_T+v7lnb zj$%Qs?X`Cid+*rwJ13Lbnbd8(uiyW9+~1STnbT%cHk-|6GeWO7`wBThhzL<($Dzj_ zB};;!M+EM*!XJXbPX|5>#+V?C+aIP6tCQC6!RQUUt;Pjf;tt0ivbrE-j>{C)L75+; zz2bYu4~QQTKR$j=d}{oP_>B0h_}%db;`8F&@t5Ln#XpFD7XL2(s~8dEqAupdcCokE zPh3u1RU9Y|5(kT0i#v*Yiu;I%h{uSd#Bt(8alCkrc)ob4I9;46-Y(7&=Zf>i7sS`a zcf^mxPsMM=UnD`2q?DAD@=}M?M;ailB&{zEj*pRcl=hUimX45)l1`Kkkj|3Mk)}$g zN;9OJr8}i7qB(d z^7isb`BeEV`DiI2pC?}&A0uBSUoYPZ1*;p9@OTMGBowA$P->XsfRt`d~a+GqSa;kEcavsPR zD_1EuDEET&i1MiNv~n9r&nOF(mzB4bPeJ}xS*-k(ki_|kLZU}v*+eQnCO#&yW@7Ec zMv0XZ!xCG9WfzzZN(@gNl{hgmI&pfUEB**XmDBJ?LnAf2t$2 zxTaO>wqE&5GqsA=L+ec<#T~W&T0d<)vUJ*}@jtb##QEBG+P>Ou+HPWR?NIGl?WFh^ z?KJe)Ci3lRQ?!e<8?>vW1Vr41TT;7MdqkUuTS}X+y#W5NtJi7^HRvnMzvg49tSu&6 zTl>qq)$7yf@%sFjmk#~?ms)E8-b=8>^^7=Q&%xBLFRibjudc6!ar(MJ(fY<<-BRB+ z$ZkdNOsx9eVP0OFzK>Vu)aVC0>r1MpA4M|hC+MfNl2bn&qxG&en{gsy?&X$R!)6&m#HsJCyPSB*nNAZ)oe>PUVl+v zv}7{sZ^E(m^MrkzVLA10^q=FilCu6c>XJsXnCuJne#!pHb&?w=dnSh@w*&od$wQMz zB==1oFLflxB+pRhN=GCwOrD**9BkJmZ%N(-<%7w`lg}hyPQIO7nEW*UXZ%mleal+< zSNeAi{9jrF$zM|Otmu)_Dv)Dfv;QlnDiQWH{>iBIaH)UEL&Qum}DPR&ymrmjp~ z-{Rh*XMW85nC+iEE_+w@OS7MOxOtuVVJ@8;nwy-Po?DpD<#))Rk$=1pFXRea6vh_j z7KP%V;&H|4#f7C(sekD>b*ws96SP6vSapy#7p6t(AcDSh4em#}!`u$-2KD~P6t@QdtlOCZCO5aIy|6BgM z2L3Ouf%Ffp^;#BMA+ts+(Xxig8MMnXHq z$j~+vxQ=O*jiq3|ys?@wz*rw7xM~Sk0rxhx26>pVt8s_{-|&rNU>Zr|oX2LXjeV78 zQb$m`F~JyXbQu>Y3ysU-V~lH!n~gis207*#-NpmPTgD>eCF67B`}ml2)c8%DpBB@} zbUxjY?nC@Qvl8|rJs|#P8hVw6Ub#tcO*QEq(|e}(r!{Tg^l{=}>66okCx)fZNS~cP zKYdgB()2ayTcQ4N`kwTY=~vUwp?CV7^hZ*!^jGOWGqH@8{)uJ~=V#1J8}>J|OlC!@ zwd!kR*0st_GM$<2!M*oyHnneQ?`Wj@P_nLn{LH`xTQ$(FNlb*MS;vlz)P zpIt4xb{6&vMs_2l$l4dy9M7TCKa=R~EurnVp^E){}bc z-#Og&7X6!`8P)8iaCRi&h^c$l3OdcVQ%x>wqWha+fY{i%I%D6U7MKOBR5=|k~=f>p5a&Hyc~e-3Qa7+6CA~?n(5> zEr998oc+rc^zEJ82eb!Ew#$7>sXYP{iBcCn59A9f)&acvXj`}lb`{Fs)|C;<7e2c~~zV^SD^MSwi)z_E&Cau2T zX*>B&DmhCdhL+F-3zU@i*nuxx3NuvUt7#=5NagloGJ)4<-*zq^0udfg4L{gP{2 zHM;Igo^6FUbp00WtJA`wSS-_#tgKFRP)!uJIL0BO zO$6?ZLpwjmdhir%;iFhil=z<17tiNvL?%l|=CoCer>zF{g^&Ah$fDJU#xuu-+En0O zjRbj8yI;v-oYuIN&#CjP!R?CwD0JVz{-TVpxV^6NGljme?~&?p4sRgEiA0lqB6v|B+c<>DIfU-}}%2-aGsEi_xktDn?-2LD$5v_a?HxWt%I^3Bh;^}ms^ zH_ra!c`L8MPb#c4E%wZB`ACm(>xkAiV0*t)5@0K}x(4_j2Fti_{cqMIw&LFp(SHZG zwZZGLm417Bf?E;4pCECoZOQu1LOsbgmh5d!wCLvCa_(AVYuDWt)*D|+zHdS8+bg$@ z0<)z9wjAwmSXqDny?w2td$vn(59oe}TgGo+!mSK_^zd6=TomK`Nh3){YUCCmA8?lGh-_wtfuqHWRAy`)Yr zY9-!$47TsxzPMa;U6cJB{hV76HO?2d61KeXSxK%1kv-ZOY}Ni7`!n4VbdAvE#kR<{ zBwNwBKf60e_B*1*OzySevp>t-Jvv9?JC=dh&73dt&Y|0fWJV9#TWTRu#7>up*YPn- zrqQeDndRm2PXS(PdzLBR;H-8A(>^8@PWv-qCnA%)nTZndyi`drV8Wy`DN|_kJ#6 zd;ESZa_=~jRe45RpmldXt*zPlbmsuPLe0N?meVq0R{zf=679d7e#=4p{VaYuzcqw9 zd^!C|UbZKbHGyjhbvO|Xn>*wEYUG_sa?m+xN3hOASPVUO03o-7T^ z<(1f{BfUbx za(TT`6Q0jM#;GM&eE4RKhh!TVoPxNR8V4zwfg)okwpLMcN@P z(Bl&7(1XEyk-e1m&smZqC+QuF#t6l4|FK&jYl~e+Yed3tPsE?U=0~n#TRRKP$hGcT zS)EIQHMWOhCZ`?iOy{-Nig#uswXl5kw8!UUxp=KpW+!eghuh1cqJ`0)Nj#-k{Cd2Oh%)_7u4Vu7l9^4o!-@tA{c1F}V(akS>& zzEjKg2pYvor>B1nx&9NpM)4Xs!sOY5GK_XGWn0k40A ze@@%|rQbKCPN_@kmNj@b34MnU4`(m2M$Zs}?9K@OeM;^?K@I6WUYid(kFfg(?IGdU zteh>nYc!L)zt{)2Z+&%VMp7e7M7I{!h)jLSmZNr3LofQG-+6KE_^p%rdKTnG_f>y8 z_JLVwkDMj5J0pqkYydS-JMSmYtrLJJ-LnC9FB^SR*g$={*zot^q#{ zS$>vnV|( z+3EX~e&RTnnJ&3gOP9y_=|E~^Pr=WA`tmLx(Xh49iWHPRTKygp>=9;ReR3{)eKopP z(cAAHi6EW3N9gB4DWtf5(7Ua9FU&yeg=n|;dnwmHytWnuE*4%vYz>kncpm(Yr+=B2 z?7v+S>ZsM%sYR!JPxT*Y6(Oy>++PW%*&d1R~K^X&acC^bRxA9$CKPByoYHN<*Yc z(gInPhscxU1&XQ+$t>tGWSTm1NGRs7GxGon>2EPNPg|2YmF@*?IZSq zEFaSZODx_kVGPOR&gQNMWvBf>|DYImtBuy(ZR5KZC$~PRPW#C0jYP93Dg`YkwTGAW zFMW8PU@PB3uvfhnx);`8`ecrFE1J@&bSd2lEzz0iN_4B5+UY&+$=!ZOL%Hr~zgFtr zPiVjS_2=Dps8>+ww|DsIg5rbpwR6z-g-_|Xrt8%Ou0OV(utipDMDpototgY1gLIAb zi22fNOw*Wz@fZ=bMXA1aR`le(Xk>jQzH{sIWL|zT^gOP)(s|y?K0&EO&*6i!<7Y7O zCZEb!qZ8GmhUi!xJbQB5*>d7%I`JpxE?8qP`y8!*r**c*GNKRfM`Ze~FsNjCQNrs* zVK3)*OLi@pW_Mpds#T|PL8Z4Zxb%3Y%Fb4a#Om}M7E5yF7U$HCC4CRkl0`VLmr*^Q zXEV77@wDbGy*+kn_^n*8+{in{*&3_W+ZOuO^9ssGW81uEn2zgLCindTa>)zSA^HN) z;cqmUn|?!SL!CIpv(0eZp bv@|VEzJcqQxbNW$-)s2I5Z{?W`(rIV{?1C`>3VR# z18QZU_WI(iJ%ikHB{}a#quYn(Ypi6wr+JvhDb>hJ`^J8yk-M$!M)TGv-M@tjZEBa= zt!Y}P)}?jpn%=2*>D@^!*_rH0cBi!3xl^5~u2i?78J+N4sP43u?o4;3yE7U*MX4*( z&9=NWp2>|$;uDQV@cxapEZ5iqB(rEO4fP!fHL0#RzF$sRwlX?(tma+=xJ=SuW^Ya! zHC}$AxkwT<($j;+*Ft?;r-!E{XTL{{ch(!Jozzq;ZV?%JB|%vaxTZ%ARtM`2e`9bx zvFIb&)a&o(SI-_p_G}jIt}{z5srg8fSst$jt{oV+;|bi?-0zE8ee$#8mI(s4aJ|r@ zLB0OeFZ`WPy@E^kd!wGM?9PTquzF$ZoJm2kwLQGYkf2;adg%#fajy$z377aB;hxMY z4rX$o-WL5e^c!5GC7wOv znP^xX-pfL+a{K>2==!ge_e>nlr?CzG+lzZC$gf!S&dFIXKX>N~uan|xXjc-o_B$@@b>8S0?b2UIcYX5@kQ$B*Z2$fQu-~N zmQ3T^hl6YMS97I$zHIlzb;m#cBhC4JFgT~vLia8A64KxEasP9_FvjnF$NOQtv!%vr zw0(Dp{iy}t5?Ma{wu)M|B}mPg34Qt4VA&Z*YuH!+R}n09O?ykco)fk{8|fGJf$tB> zsAJ25|G8x~D*3ffZQkogXrZmp7WmS;7Dz7V`X^b)I`eBEv(UB0`rq{gUH@Nj;^Tld+{02UaRiR!FzkRXYK2! z?6}NJ>{&Ft7G?L#ZFkp6|H$6U=J>uLYa?j?pzYA*qjh&l?TwZ+k2B6+>-2HfvO;TQ zgw}BO#;&=)RkLp_wa>5V{wF#=vpSYDND9tfj|G1zul1^x2jjzhYUOv^gL2XHAO2IxPo|$I zq{OSy&R3LfOe0?&%APF<#-A>Lt_1CRX>#m^^oPpz+C;o$;{l^)XnqR)XO+lOu?zcuANpYZdjts}oM`1?86zP}IC*6U6DYI)<Q)}=q zbaqesFX#{VTwz{lX~;B?WN4k-i-qm6+Q>=Mpa$RBkp%>4Qoz1%XRo6OT#Df3vn}L2 z$-6b(n($6Yjc+U5S7=hPOX`xl;rAKu%iWKFdfNi`zBxzbk_AM$W2`zmZnFf9#Jhd* zs7!SpYoW^$03!^)JXy7cwZXTTlJn`P|D* z{b=d7yX(}?Svo)Coi}-=v-1RPWT*uEG9A-hKFMDn7Ra{!LmtiuZt{ z2Ydfw7P4@3UbVr$@kkrg5?J!tgJph=Kq_(+z-4Hp|DxR|d_IZYANGC=Zrf{N3sVgK zKLBOt5uMLuWwxzkRsYLNRTn2jDA>DnV(kbX0w+WJb& zO7hYC{MD2Ca#X!U{B^&%?QZ2Ddl9$aVbAOrw_oyW%?T?+w`BW9R)xS92)&y8qDa&n=gK4AIgBZZ5tWZ3(phPHna3>|s?MBzSure~$Rq{bNz<{=D(8 zJL2g%jrAlc+JE}~ad<+d#^*16KZid>zu1=uskz?qnx*&3 zJ7!N;Tcbm$|q@3Zt>PyX5IY#VF-ePmjaoz>fF{*F2CcUpM%oc}AReZEDqN0BW? zml8|-JPV5F^|igwgLyHD&%$JXyW@RcvtRu3vGvK;k>7S>R?-8^fiD)15_vJ5t#B1+ zC-H2#h=h(P(b8?Fb@y7JQPhqZuod#oA+6CK^CejZ=e|vJRu^inN!A{bFt_*J&2(s^ zF>G)0U*EV*aX+K}!KJrVY=>w`Z^#@o;8~sf<=;N@3T_!K&ek!?+cI0$dL-H&-J@td zsC4##?tQ4mwSaZfs&~oBGS*uD;6Af;6eiWm9~O%?|K%pjMwXH;Gts%1llLL(gZR^S zefo#zy7pQNKI`^h?`)md$nSh^6Lt2KvvVDvmMX?p~V!pIhl8d#+=cY2V){;ouw6(@dzx=cp-qQJw#J2IM zMDc6gXa8hp()5W&&hPZ(Nnmy|(uQ9zsjkue0ps|05-z3lv(RlN9&RnEleu@vY43tc zjPR~srv~>O_seH}I$WIXc|Tj7cE1|m2a=kuAMCMT1br{zdz`K-TrW7ek7s;*Grc46 z*b26adx!Idzhl{iC=K%CyFklG$1_Hl=^q(|vk})K+fd6kgG)3Pl?ta_7aQ~a#`QLUv7hWfK zTA9YOIQ|uH+brGONsn5;xj;1WA>|OrKE(PLy=wiFehB=R-h#DLZ2^ACk*xMngG)Nt zTHXQdw+DW$HX`%;hgbG{#)LDwGsbDFrxy19^6qWkjL!C*HS}ihF8@8i8R4z5c$C=Q zME7}mZz}$~%}b=9L^G0-u2s7B{7bywxY?I?ONMLQ?Sy+%t2@eDC!StC)dXdt`tXuw3HwZDJ}CL+ zLp>S22Cx1QP}j_hzAs3L8JwEhHQdX{{y}{Cy^i*dmUKU&B}P!0&r!QoKC(XV#?}tY z?|+=Ak*(hMc~F{q&H$Y-e(8U%;bOgv_?w*rQ!cC;NN?i#n~cmbhp1-6VxKj=wG_qVXa_( z@?tvT?VpKgoxb6N|WM!+g`9=F{!dlv~T-2UNpdV~-2qCT|rd$uQe+CIH|toHe;yS-XVjsEy@ z#*sR&4O}fAgWtBGPW-qRROc@J&L4=5cshIPJg-BKpm-V=)<5U?5tz&x8^-ahW}1hT zq)+^u?(|?vUi#It2HCLM|FfbrQ{$=zy^++PWS~b=cS-ZR_5OAA_P0=N4SUr0*=ul?ZSSQuvSTacMcWH1 zZ8xh3@~N%ovpD72vHl)3i`Pmmq(pnzi;oZU3$pR?^~>y^Cc!bJMSnZ%jlVri%VJRq z@^pFy*WB@LPq!WG{L5|UZ793#?s{zx7QuW;E6hSAcZ)%O)ZbmY=o%bd!(H_#8 zx8yT;t#Bl3_URSmbD)`LPS8(~R$}2lZR2U4=1b=@Sujtn=dy&^r6=m?iTgi&^~9i0 zb8*c@(LRMmH@x-y_CE4S>Te-hSn?W#Mc1~~$S#ks(K@{{*KA4u>s7m_{vOWrdT-4? zifLQ<*DA{*>~QQMtHYp1yOa~^AoKNTulTF+cjF(&zlPm5B^JaU;1bajZB&oGeZgr;9Vi+r>HJTyehmg7~_)Q2bQt^#Fx3ZbMNOq%zbGt$o-i6(R|Z< z(OhJHZhmk6mW$@pTsBuJUR3<5yh>$!ZiU=xxwUf}<(AHES-i41qj0m6;;iEBFwH8? zDLztsv^c-`Lh)tbHEaG(@#RuS>7DXg+R55!Z4267Y`?KIMqfo=qx6002t=1l$LoDd z59wocLoe#Z^61j6@`m~$`VomA3wIXoO#D%JfT6~vck`M28mgXOSIy-&$#>?rSKHO4 z^1J8vRhLy)EG~(-i_7Pg zFR8>U@#N^z_|k9XZOhx2H?Pdluh6HL?$(blNA;QItIOBv-&FMSUFBQ!pOdFoa+OlD z%lNYVp#FDKuJo#`T3If6LF&uYI;oA@%f@x>Pqsf<8JN7RuwtQKVWq;#g;ffx7FPSW z_V1ebzp@vo+a#||ULRlF8iiPE&>my#Tr&DV!bbN2C6Yr)#3Q^8fz&OU_BoZ*JK!DmgGSwI%YIS6X7n z);|4OkJct>Q?yI8t4k{(+Kt+5?XJ?Er5&|Tl19=@7HJE~p5@1reU0@B@2d;c7mPo& z2TN1+ed3D?iwmC>zAg>W9@n19Y?v9`9x--p`%e0p#|%lP8<<&9@5TO{vEKAe0q-7Z;Y z4wa#mq0(PqdpA9!{nhlWj*Bvn(A=y{K1bz_dorJ7zLq6Y&n&LoUAZ?kBsHwEOJ#WS zRinM_qSV`|4~@s$?rFQ<$fega&ND8QQ_!=i=_}eZ#^uH_#)-zM##z;T%Xak0tdd!) zeMU)g9@?KrSwugt`bojSIWmu){Lonv+)r9Vo4p8h`lYo?s(iJHt2nPW1eGP5)H z$}78l!TLO}>v%3ZsH`@Hq0iADLCQr$f2#dChP)=m-SyJq4GfAOfV z7gOrOqEVEJ#bQUXkNRn8>(bWpZZvb|wbJ^f^|kl(>UJ#dRNPbjwm4k<1EXgvHkPqeabv&8P%E$5=CU?A=-GbGYjMTmw!+06qkA;p@`kh8|%O`YP znRyDMvXyL`de1BGsTWev!as?8T6)v=ap@s2ZI|9Ty*qGs$I2aR zrXT8%(odwH?Kq+1;f{whQ!Pw{6k3P1~Zj&)VK>+o^4@wgcOaY#-KkLfa{+QK@m2 zr;yad_C$Na*vB{oz8BQyQ1Cg{;deZ%CEsmz4{N_KgolYOeR_I)P&*wP{F7w1?%1pm zGE4j%tnz%vkvy3_GY4ds$*$0GrXQJcLF=(ueR1Ufj_g_4p_MC~bez%(*V9~>fh4;;(Zv_#y|Ov#J2y*a|)~NmOj<|jwp@k;;$gl2Ru9+eJc7W@VLj~ z^?gA8M*d8GPJTju5biCzUGA3ekspKFLb$_hzWk;9h&;=Om*xM+Z(4i?F~4*C1b3v> z!#&X6WAexHP4WlwFC5>?^>L5R=$5kj4r71Mpa_E+S0SqU?r}|Ql}y- z5ou#-?dVI=&e2yDRa#ZrM*d6MLfS!E6Id_$0$4Yc)&?2u(i#?nqwg`K;Y_BIQzs4M z>(X#(H)&64&*<9(X}9RxSVs-jQ=RQGj7C^K;2-@$IxzZ0bWz~+skEQh$3I3o9DOkt zZ-@IOkCG0d`KbqK5iKN&Mo0%r$2v99MJ#VfKcQXbN3;3*^Go|t^y}zv0M402G^9?g z)Q%-W^?ydc^TZQ7`VcGirBPo;f3{-K?`J|xhzZdj`FZqD>G;s;Yb!gpK>I*tzWk2l zM4!a_z=w%<9dW#Gh>UU8^nT(kEVb+PTOr$9)wR71MF`LAm}}mpsWy z>Ta7k$uWp@j&zQ;w0?6CaK-)-oMJ1)*1%GL+n!@cVv6WGSe*csb6@q>1oc1vt<;s?jH zYHX!g(1h_D$JW#K(stKw)bH2t)gQun@=o|21yG~XRk7V-d%}d!5+pT>HR*B>S9vsE zAEvoTa&w7Cy90=3! z^6IfemH>yBS6Ak!BId_C^mA#!NE}~_9?xvzz6@;T*E zvtR6**o-RIK&=jpnH1%5KmWwqPP82n=*g4%yySd_xqM;=FR{yGm&7iLT>!(x%t@?i z<-Zl?Gi~bVpI@I^)2W)Ou?!&3fErG|RDEY8b_S1g988K`5St88?ai^9EtzORuRpIp zAG^v6_5n~-MSouHWl>R`6ro-e^6D~bhnj+^3G`PG75>f=N=EeoMn}t&_|(eHlU}|y z>hepFW#L~i9<&GSvDNU21|EzJec0G&l{F1FgN?z)+Q527r?Eu@ewZrnTHd3)N9ij+ zqPtUSeQDNK237;GXcwWfPi6O7@zJBp4~7vvH=J7e!|aJ;6UV}3nU=Bgc>f{Y zkS2M0IIbsGd2;9ej6EHDJ@&fL7JJtTKDh!lv~*fo%^it#^3)6JV`X?oe~YvPa|=sr zwG0t&0naC2CUI;Ydz#9z_hava-}_chh(~>5PcN4JmDnq>7ps7r*{*a^>4Ne=i0Yxg z8~adyU+5A0mLc>Ypavyo@k(y1RsVsTlMJ7L<|~U2V;@%Y+j0!b*yluR%%)aS#(uDX zEHTK+lNj#B%498xF}u7j?`_LV#TEm93rjf~9Nf&jPe|+m`+h^ut!eh)4C$^$+zA(I>H=ms~;r#2H^KmoBlmyaWin<6=A)&q0ZQ z#NrTo6CEvi8!x*fX_WpI^|CT3P!p}Ta4s5mS=wB@XqClyF|MJ+gMPFg?}&HMmf${F z5}k>AN$Fpi0~s{FTJ{zC#(Ty4!Mq$n&$t#L2)#xmZEuTeSmMdA<-2PS~z4f?lLe$cj{%xZSq-K5P?8ldW@9~ZxEEn110JK{jN@yitMZBX9`QYd zRpa|Qp&D8`t<~Bd@$C^~9{52XE7RU_WG8cj;@iTigyMTheEZ_t4tio9V;)9B{H|V% zCmAHtc-nY|A*>;+p$pm%+qn9I)-b>19y-c?8mKK-yyFbA*(6V?Y>(?BRe z!^rDi&}zl3&iowGn(;9$axlc76hD~bNMTJv{DAoBRmQ}}#t-8-802H(C;D(){5YDS z>2mG(`SJ4wmwhqs5*$Aq{rY6{0C4MzS*f7^q z*pNcx_?6+P$MGaTQ;!oirW#>mCKDajna*pk6;Cs}%UW^uw9DsYedM)FuGJpe>jBq* zIm8^2{2=+UdZc=ydYH|LARpu5VATiA0sTFxUW$E$!NTC;(hRJtXRGHm!9?{;VGBf^ z>dX1?pV{+?C2u$pI(gK4IHpEN*F{r$ksz8?%HoP*S?nYB6n0B~PcgT4f?0t*!x7gHWF3*P zzWTlTllHc@2zZZ>{KZHRGJ}NSVZhVt0QD~;n-&S#tBNZYR}}UmNPiRLC_@|toM1B@ zo_J@0KQRdhHi~$yAHpH^qV;JU;qYqAa#blj&vL@y{%9-Kk8qR^$17_ot9ho?l>VTt zXIc&Xobg0MwY1h>pQKL`ju(zkbOQNA9-a)izJ8W4lA>(e9GR8Nsq**2Xl1+F2%{4{ zfTe=b)@lrMAtIbYQFd>ZSgmK#XK?r9c+9tKoFCZRR3TL^=ycAC2MS?KNpX?Ul zI4{%+=lCOjO<{JeAbtnWsr=K!kDv`eIEPtKCUt(!?3VPKl$CUAGNim;Y3^ZmU*4b0EQ(rA)_MpJL7yZfW<6AmmxHgOcrITBJr zZ%f{Uxs(ygc;z&l^qKn1oT0>yu7Xlqt$B zz-`w27Vx`8xm3AWnIc?3ka|cfNImo(QV-!GB4eGKR)FW1E+zE_jbDj6UQg>#3Kv1f zHu)I&IC-LcwtN_r#|f9q+sixIY%gywTrOPVMk^zUSLCgwm86v*;xhRpEBY9ikCBg* z4~BB0JXStYo(9rXAI_9d2M^>jc@KHl=7IhJe0=?N607Y`5Uz4lx*5?9tq0*6O5wzC zv=Q|q%%?;+LAMN50F4Q=LoB3K*#(2)FZuw%!2eHDrJv3w#n+Q9)v9)-*>Aov_;w9h=xTQ1i}_?(j3EVYTnAWPad)d0d*Zk*A=R}I&9 zOog*u%7gGNBee@d_#wBV@B@X&soQF>S1JTyaccKgfcT?R`y;}yWG?(lAX=CoO#r(k z(UR(GmF2C=TVqCeN(@lVeo*RAC*>j3X19MtiZLQJB6X>x{Cr&IUZWx z38zZIbK9=_Hr^Wb)GZb_!qb$d12?9wCqzVo2}5E4nnl!%!o}KXWLE~iH|EyLtrbyt zQg@ig@O8Ir9tmS8gmHN4J$Sm)0(f@Z8>yFoMX6^~uSPV6u^+GvOa~f=@I+wX3dGpc zhog+6j2(>KV1AUbGe};B8E!m2b_=;kuF_s9!vsX2)(rV!xk0%>=5gtRDaI*vGTInz zj5EeXicXA44RD5Gk-0c?aioG6XXSTpl;WUBN9!0DAo)H0iS#li6Y{%7dih~oRGabv zJdtI1(&yQnopv%N?F6l-r^iN?MbhU3XIe~5d$4^-=Be<+LpRgXjGNM4W~FCEmamWW z%Qnvyzl-#9l718Tj~Cu6{fmPy(|&xP{wcDGAL(y0vYYhp47}YAYqX54?uJBzhbs@p zps)S5rf+YnM1A@%^7okhA@oeBxiXV(8Z$C5GB8tUmdLsYJa4iFkqyGg^lY5SMwCo@ zW@&#Sn-Vg8>LaqbKbb3Ru6LDJWG;;ii44hH>)=MH;e_0nxe@F&e)r|=k*&RCo~oP2 zGq+`M;)o2*%*i|onn$fUXR&-A2Y&)u?sgIx3ek6D9`=G3ir1QXnA)(+Jm6qK=2;ui zqdk9D2(u&e&5rD16aKu&fN`9D&3>Ex)~w*%;_uvhxsP&-a*N8V6jk_(+ZB=RDVaqz zcq8*h=IzW!nfEL{itOYh`);#D_CT_+%+DOZWfR#1tw;7YQ<*=#MD`}2U$$?yE!#J; zZ)0S811n^EWS7crXt8#7?d+;B(fP*N^|EV34u~9(UDFHdDb8P^A_o()gPWzAVOX|q zB8O$S$#%LJo~@h6kw|v8?4BG4X6q($OyrpCel8Br)^YG! zew2?yZSLW4vKNFA8Cx0TV3W%F(bIUc_xq7QK7V}Vbi~if>&*FHa@*#%t@I@E=5v6< zCp*uapPh$u^SSKPrK5r%@k?TEj%}Rm=jLbT$B{FG$bRU@8hrwb|azToyU5kWKb=Ibu9xz0#ozpa5mYQ9*HNjllEmRWavhob#k1_x2fZmImc>&a%tRuI zhU(oV@gni0brQvT!sfenMdnU$uz!v+ z0;GcgQa?0zXygVMQ^(5@xlu^@r1FX76C*dcsr6LO+<0G3%bg6I26O@AVf3B}AfFn! z$xZIu#)!-!6n8A{h>=)^f!<;E+@%y4v!_brc0y%ouwEQSrH>ODNy^-XHdo|=xGi@_ z?rz|Y+#KNA-1Ws>in}BEt0H$s?u0RqJmfDg?o-?!p80=J@gVQnVB{X2+yh=5_D6FL zBKJ9g(Q|WVG5Z6|D?o=e^@3Ul0N>tnFZuF#?%5npIA^?&d#bV`dzJx8VgI&|JQ8^% ze@&H{Sa(x|AxxSf@`TO&NK54B`Vr}-_*sdLdXUo34=pe{@4fl^^YijgI*B~zgg&<; zuzWgSC*?7O$bWb$r}@MCgvrH2i|PD}#X{ue{98^UFB2UtomN(JN75+Xqaqhgs6Uf` z(VAX_@X8ZwmWX*`shkRc6|~ z3tp<$$oGZAS|RdN_}!B(>v08}$S)M@X)fm%&M!3kv@<6@DQ(>5$ zwP5S6EHp^uFP_2;wQ>IRTDXotw1vk)xvB6Va1#OlLSoe)DLi6n9xU8mm<8j`KLOkW z+-LDbaa0H=6bU1WBe=h$us^3XDyfC}^$}J5fboHSi6#mDR;HzXv}6`0Q5%*_OC;Xr zXLtK!-5t|Rz3^P&ox;m7GV%w&YlRP@X(xp@z3?6|Dx8;(3oh`7dOr%^6uTOyJQhF9 ziYHr4C{D1YlR4>B`f*nr@55=u(~9R>oK~E|6D_w&@!EQb_C&8}PfBrmmFtTf(WQ&m z<3wN*)i}!l`;F1183iSr;vMx6?Gr@twt8?z7jI#d?)N9UTxC2kq4<)ES4(Fw%Du`R z0sLOJsf>>RhwSY z$@q}`Jh~cRt5aT~4f3oC^e!z`S}MAlmr`FJdXz#SIba0d4f&DAJn|YP z7t#Ja&pD%W@&q(m^Dpsd{+Rx^|(t)MjN;{W!fH6otL^mnz2Gb7Z(<}X> zo3uvwUAN2{-HcE=q&ceblS%<_kD{7VsS@4NN$H$=h;9``dHGg|Zd;Qn(NIcH^F+79 z8kzI@Q2C)!mFRXz=^>ox9HhB0%>$l6os-g&UU&}}nY$^XI}%F2mj1v$vX%ZQ{SETs z=w41rAC{iyc)#?%UHcF$KxLi!i0-CxLs2GkrmaJ|scZwWSC_AbIo7X+={n5EQ@#hd54fEW zJ;F)(PA|Mi;4>y4u`RTGFnY8f<@t5-SoyK?6F_&lJ34}={9JuRPw=PwpN4q3{0{m@ zM^VZP9efZy*-81!I{3Kk$7f~2H)R|CiMy4}8X-E~O=U+X(FxHBPEF0)b`@kxf)$T4 z(Qa4S3gWkgX*;wu4m{&D0Q(uJyTC}*4CcFkWq-@#+{!_%Vm%=>^k^QPQn?TbKIT_0 zCb&In9cA6eC3?J~B|VN|Np-E1m7^<%)*^aw5S1e;CkHU1LKs!?5WSRAIU#yQYm}Fb z&IzT3{P-MNZJqjwPWKXUlju)no9MOS=ok5seI1EjAH6>HRO4V=t7y|3A$p@5?b_yv z-V(hf`&GR}Z}TJkA^zdk=pE5JiZ2vjh~6DcdD(Dcb7Ob8m)b9>alr=^%5J# zX2)h{wlr5USBX98B(tRzJy(A{Hm_-*2g*~*g2ZlKVh`#eb*E*Sf81b7h{}SNN_^f!V(=5n=+@840_!aoW z__djw7)Ph-^Q`Fex7c&Dh(z_YblIhAfEn?3q}kG~z|Ep8%JC;C+P2bN@z11Zr03&* zf%GNtPW+enFVZ#esNsk-GyYoqIp9B4UbdzAVp>d!s;EkHksgxnm+qCGjxUs+ zl%9!;~&RA&|XqMQ@>O{CTI(6UPy{?N&Cy>H`=qwZ)~6j^{2%C z4ptM_l81`@6Za-wSHD5DH?%jBKM^uVWRA`pZ4S+Sn$PCpRa~w#L)-+|U3ym>B)tXF zE>ONJZYS<;u^pA9PsBms^*+qEwQcAz2-r+|OZpJ45c#=PZYk~~ePwxVWykLYwe7?m z3F`0aFG(f&m-e;x9q@(rsm*twA$+8Ln*80+4I>@Rj6kFxq;JLj#e*o)x1d4YLDH}O zh({Bo#a_fiIq37bXgNYW86dS$;s{F`0VM)j=@01-D%)N(l9u??FYCEq(%;|@lLO2` z^VvDY5q8cI+#lWOU*3Mye33=*RM=HT@ig&NCb2r|#B;?is{{|?MSZPED^5HOW3Xt9fZITFiSuN>Ak6GYj!NvhG@hO|f`P{^2HV(wLKq}H-Z*n zqA2bDP`j&qT;53DKztVFtH=Yy$6-DYCRhTPqkaP|t)+GNh;os|dP+_`EWS`DFPU#5 z;!95QJ;e9KPhon`wtXsoYQAH>BYpwAEiQry=Py+!7LVF0-prP5krh|>}}daZc$ zqdvUM>F}9@LBLvL?O_ZT=de*f!_v}u-m|sB*OqfzVy*U8tDTWNrI0<-&|SxNNETXR zjhDmQAl@uLAL(79W;D2uvyY>xI2oSN=$YWD zh}^Rft1^9#qWhVNRPQd`Io$S!>vFD6+<#PLJ>?DMRpo8vC3$aoUpLA}pluOlk+MiWK>1PmS@~1xsjQgDD$6NfD4$x>cgoia zPFU{)cB;3_gpf$!!5f~8c>~AQa(x^L&&)hnK2JU$p4fRE$CYw@kobxEu?l=OZk6ma z6eSJIx}2ND76fHwWn~!ZoIV0uSC&?O)A}R&8TvK)RoZsS3-+^>@!8A#QN*#xxpPnd)E9t3s5Cbphf-E->2_krq2uV`%(=;LOP%K~ogX;ZdT zw$jh3{jBC19y`{s2R#jXFQqAx=O@okJ*w=I=yyJs^lgY0z#FGJ2y0cJ?A|{bt0$+zI69MUCRyb**8H5rC5fx5T$7lT zxCkZ$$KD|lna@ag;q6q$QF|~Nr^^!;Skujkn-ll9$U}+Nn44&grxVRHFEKCiOba}j zc(R4oNxxfZA7h`VPr7fgY%)&WTix6E0q4NJR5m_WcU8Bx*+bphcng90P|$C0yl;F3 zpza547cc4oz)m(KGnwz9LN3VmgAL~7?aj!Jafj+1hp5(AMRnwZr>{FxaNQXf-o}Ns#xrBLI0kGztdGo=oXGg zt-}Mq;CH+SU?Rk!#7Ryo*=w@bSeLiSMeah%G*%$wmQGi4OPdFq2kV3DV5EM$ZcmvN zGs~rWr91R3YS5{-#y0vkz8Qw;$j`YHNot3)|$A`z|5X$#Hf!FY__Er8(x`XK)x z{cs%#vewq`X~+8Bhs$4K373<_uYI)M!h?g=Ybi?bz5XelCe>e zvO#iti>>XF)YzQqH&1S!9BQ*^k}@RK9zfZt56BeJNvsr7N}3r2dCD%@xq{Ky(qu8x;M$IWQ8ayA6Gq6z@8kDA_TA?d-Zd0%}FHHq=amvYssVmYOqz9%qPY=MT z^Z+Pv{DzjEyne z7;YSI919b2tR-R1n$o)>nG4fHp&V-4j)fXw`}9tk3o{oQBaM;i!_xZ(PWy(~Ag<2Q zEP_Y9ILBB5)E?7pG$enVhA z&;GS{dJh2hAoE1?xZ*lE&#j+ZC%+A_gLm@8hwZa|wgX^4cEY?+IubZ8eNqb?XXPMy zh9q&?)eWK_o|Ij>2HjWkl9bXgj?(wbkLzB+wfi@;bWzTBR^A$?E! zPG6gUgs;{dW1f_rpMK1DdLpw~`aX+Ca$7k`KL|XM?)Hrf%IBlc@0TBLO$X)=EN+t9 z${LO3wRH2)@m$>H$7#kpY0APhkXa}FnPU_e=a?>}_CeYU%UDxt<~BA*Ou!#lYmI(V zwJ&XtQ?i!-cqKKped-&>B+$#gPb2$^liaJtN8R`>YUcU|z%f&%19Z$3tT!+Yim&fe zb&rGM?^$C!_R!JVU&y>#V-%5Eql_%dd|C^0natPbvYD@KzQ`b77dIsg<%T zS<*_NK^gUJfpJ0k+*|QpA5_sbj46~jA z+0V$1v_bil?C9(`U^0$H5;mGhUA9ZI$VC=(Y?6!YNYvv*^^KJzD~<6Twlo97 z)Ux*y%n!`RvU6eXfsJ*7J)=FWmUFW<<`d5R)@UhQi!gr5SFM5Pv+gOkKAhPC#jneI zTjlyiWG$S^`N- zF~2Mqo5%d6ZhkU<;(V!$C7o!l->ZJaLVc;7FEJ~FxA@7-lSzJlM8|v_QvQ_uDb*eZ zN7u0AC*{uoCb=m-j_~>OllWSra(-5};MO2He$Sr+ zfR*$a=kBGU_1e8AEf;=*2x!~R_*BuRc6^uz_8%tfKQ6Pi9G>#O*9ZaV_*o3O=@v#M+H@#0plCGq68*8UmQIqsEMn?$!T zNRvtsS2)xIOMb#AY9kqPZ?ih_bk_abDg0jey||#b zfDAxuXQ~cHTR15kI>t|nB{y17Kqm6Hsp^Z>{J^yR1ap?l=S|MlC&^R6LQ8l2>#?v>wwmM;4G8pL-7b*a9-fg2vSvVdC@x&r}%CVj@3A1sj2)N$IjeBTOr} zX>gPa&!`xWg^p8E+X~|*v;>Zm5C)E?@D7Zsz`)u<0O!wz#)jpkwl52<@qM8s{633N zSL{y+vJ-v93>$;3E}LV#27c^@2IPy27uNKyG2T)5Xh>kaqDAT&MRgs1Gg4$Op96Yzfb;Y>AiXI1{CDK{!U5sE#i|Mv$;>&#*6umzpW7 zH+aw+JsK?OllE(u_=Nu9))V^iDgBh%ap4~PT05gO&atjwoQu*KI0^dc z`OMN=fF0j#Sr+S|^lfQz=?4M~eWOsh^mkdT%C;Tr_2jgDTDazET`hHvVCucd?QICH78%o$=7l63{JkDlW*YUnVfthC*Nert;^@)w-^B`1Hy$zOBwH=O((C;!07KXLM6 zPX3vbf8pd`Ir%qBCd>Ofr~iYK|K#Mqm>h|4a+H%}oE+z5(UPsUA`+*UIa%T41ShMU ztZ}l=$=tb0ggaM>7@SXwrR+`-8` zIJqY$_u}NGIC*JKUWSuSmn0 zIVW$+$$N3~-kkgdC;x}Z8kb+Q&n=;?j1VE`Q4Uc|3xmREnBe?EH5mvwOmyh{Hcuj zC0Gw4t_LRDv6g;&s!s|6(L-C7zmb728jw955pvKUl&!WbSsE*(g&$nxn$wzVx=>n))`kL~r7 zP*~rpGW6M&t(;XE^lFU7QW@8kE%(L!M~$(ZRT=te%T`X5VHvG;tC`WUeFWj6-orD3 zX0rTLPD4&xw*A2;if;&859^%B*lu*cfuPrgv9O53QWGJk9*vG&%Fd5+@2bq&(xWIx zR=*HqZFw4#hhly`3fmWah~8R8t3P_wmSO!=WmsO6=`w=+0=(}mes;XMuBv;#|0k1~aAuO337L===0BM;5G2&e z5zC_l{)eWu4Ho7c6nwQkV`AIugB*&|fEE7(2*mOjpb(%027)M*HYX4QurpROJCSF+Ty2ik%ullVIaV{9E62yq{ ztv5349J9vktY!vuS(|-}|7SPMwd@+sWpXXynaI@lW3l=;@Q5pXS*v&TaRaC~yDB@I zc34+-mDd^Q9c8?r@-?fhUb5D^W|i4ov&w9Oqs_>evt+doj`oioqQ0NMfhCW<#@jqNZF0J@!iboEClOwflnwh3k>^-v)qai~C3ZG({jHTECy&)ikr!;&cJ5m? zy2AP-WB*hiynu3W9`fo561QmAvQZZq>$@=89_3_{&nEI&lf!?tlY>=%Lt=*v`D^`r zk^TwXX1_&7TTaXzl>M4`BG!vM_q<7chJIw|M}~c2`YbvFJtw9p2Pg83dxOPZ4xZqi ziaKD~Cq$->k70@V$cUwrygwtZKXNXtF%O$3d7j`tA+Xs08I2{#g@bRAVc)agqrQ&% zK_@bFBBQRrFSG5Qvv%YSo~M#}J$w7Y!G7Rbmi6r8b8}L*p786n9~O=!}Ow%yD&!6$$oE|`#rW7F*bd)nds88#!sW@OmB z0B1b}1OALwDzw?>8n6jQ+xb`h2@iY5-;5yFi4K@~58Pi4L5}?}xaP}7&I)gza@orT z9f|qCGG3l@x)ki>LC5#)@;>^Y{Y)L@EHd*zC7%0IhE9~j=XeG*9nO8qxgX{^w33_$ zE6JIz63%PV56RgLa@kiSaz=%5MiU;ev8zO$8CCua_9T^fZbI3>(w2DkfjlzW63;#+ z=bBsb>zePwz&ZOfGTIfm;CKaond7MZNMt`=BCjMiE12F|w&LCxx!=iHi@skgy-n~Y z)eqw`9V9bl$EytQt*<|~Z zN?0$(*l)>tq0IH764r&~jEBHuQ>sl|JK_BBN}=lrPC_FYURvn)e1^$=e(wG^!+4e1?05eV<;V$Vs2y;jJR73f!ij z!rq^1IF}vWSB{cDi*uQ<&j}|lK)(vc+;X!xX9dPsfc>03nRQhq&KXN7S16Y;_43hy z-XhEw(E;Nu$$f8i%kp?HQ9W~opGVY*jJiBm&R03h9>LH#OXncUMvijK#~^3fBN#fx zVqY))Y3Lk>|6ue9<~Vq(&k53&t;^BlY%k@?i@+FD2C4#`PLHh;R}q9{XH44oOZT+DvYTc-Fo3ca9_rp@0tA>8GWLR z_IehZSC^DOy9jr-*>Sb^kOz88ova1hwj8XX`(ek828JDF+K-&bXB55 z&o!{vTo4^{CCiOhm|X2s$KNMx+XCOvKeu8oD8C^5sW?x!o%!qlq9e(v5g(v;lzZ^ax=8barXCq%Z z;Ev>=|FJE-DF4`*&qnSYW%t0nqn4O_2=|sq%3PazL&wYbGH>^Wcba_U1IDAfjF4aw!#$1a!xSLXDtOl0(7`f-=+D6LdzVsI-3(xQZclG4ZcCiyU z%k>TrcY3+q|3K#)^bf{mj`rV_@UJBN{-h5tGOkeW|Kt_Q16Q|6&d*-yJDdluEb4oH z+=cyN2hSxH+aFHp8ywc+gtN$4mlKBE&Tdo5TN_#5LBNak&1=fuvtZ{a+|cDRj%4W{ zsW&q0+gU7O$mQ)x&O}pqbJ1}pYoAZKr5iMsJl8^9l>2z2+{y}%&?U-KJ2FRVrN~Q% zKX_xBa?2*o&az32EkzbY|(BXU^HcJevqx*$M6kbhodzkvQUu1r;bPUYY;V5bZ^;7s+m=-wDQKOgt!Q`KLL`{b$WFP$J` z@dA7h_GgNz>Mx%lW6gSt$(zA`e3d!A;5c5z#{JO2cOdHqr?%NXa4Ok*O!e07))?6A z^Rs+E5E*xOn_V-mHJjaAUn4%`&XF}{HoLbiHGcb1!pN?hU0}@X&F&qXgEDrT-8vF8znZ}JX8x$tBk#H*jeADD%ykvYYv>ZR7iA->JXg8S)4B`yejECR>&ZN=C-ao7;}SUM z+^_rhrcjs6-(WxTV(LiWVlGEUKi89YpSr%?h|e~!>wb<0oA!oMclK7I%=_(nnB%^U zcIT#Y&V6OCAMVX&Dfi5^qwborm%!b^lDggJLp~GtCy`}L-}PF}$#q9=OWcxe9Jiln zI%L(^exm8@*kn38Hkth0Cz<@+Cz<>=IM$(mely|U`U&>!{U3=uu(aK?Z~J=^oydsu z$dx*CAoD+RVBPLfUA^+YOxFcv&ZByAH>ixdM(az0|MVfS_^>4LEwIR|e%yH{Q?D|A zW^%_;x4V=PUK{8dA#3PR8R6}o%a&{-X^P8->Y|+xzPL|I+iP<9J#kZe$W{3 zjFA`nl>2=w<@6H~fx0~N-hiwzLoTUMz*r{twQ1RTgA6G?jI^e*c&kB1IrvK zlKh~|oS^LWZOtl@HLK7y0(q=(JEv?c$m;*jDf4sZRDX#+!TFl{)^9tfY%F$8=^9{jP;_C%=gG5x4l6l*&8(Eo&*g?pLiaREcJFBY+8OGQ_j0_vc?!b zO^M$PqG^5F|Bd8ZwT7N6rL65e8nzD^Zs4q^F;CXElg(z_d%%al=&Oe9H>F=IG3Ss`-eud=WitYd1c0Jda+1XPxKTvM^SH*Rt;jSJq{lLarMz;T&_vR>zYJ*$FImcAsW#Cu+{6Q+T)``7QT$l#%Ni zNluHr0DmlxEovn1ERAFj)2QC;b7|>DA|t0ozBb`*!Y>=+eK6|deK6rfjs()!cBS5L zyGD6cJi9fJ4|VLOlN=Zsv4pL)juF`MUS!d+@585)+%=7FS#>PP+PBk54w+8QCg2zY z(|VtPIG;}PN#LAuIGyB{=_H3l#`$GBISWJPL^)%d`!}-n=Pegnd&yYSvEooi?`p`J^QYadXIfv8)rVWpw7LQpY`d_`DYDf| z&fx!K;pM^&&s(G1e7p6`z*vTEJyYlVwEO*JECNfv-4^ly+j9Hc#W$=$WV3nu+pS%D z-eLX=2cP%6!}RZXxAC3thJMhw)8xfnK87*w%_Jrx!?$L#wvt&d*Ve!iGi0r+nZ&AR zKSs@DFWto6SjVNAtiR3V`*5iz_r^`! z>(V!V%k3HOeUbfLDCN=*CHsMQ#eT2rIg>kNwOy+e{=dzRy=Y45o;04;Z@A{g!FS5R}vwTzMveaesx2b!ES=#Y(?h~5Hybc^< zz}EVv%y&40J)7rRV4M5RWDSa3(0*8(q~5R|C35eBty4k2;!vGujkg=oTZs9CCFC~m z5?+?@aAfHRn~zO*o6|f4j`KHRlnrtji@;*%4=%Pi|AUJyPRN<$jiw`SjcoC7cgxC> zwGYWBh5o#|g)x=i_;haw5<8?@npU~m~z}#H{B=RYh^$A zTgDH)&+2{XeI|cc?DQ>guKl5La+lRi?y{Q6w>QmX&(^H^v-ZiHvsG{NWZEq5|DNoJ z3vjZ(YL+J+(7kuFXYcsUp2bNE>yGvtS^I~q{R zC3~k9&NUi`WT{K^?Yz^%c|qc&WW9EFXlY&*KW*>Pa<-Rfxks+he)jC=xaXS8cQV>5 z@0(<6?;}@8?A1!t`$tJX{PBA@E?h%fj;wY(o4g%$U|-Hb)Yq8zoP}|roIF`jP9M0Q zdd53ZVEU6?O@F#qiO^*+2#V1+yA3xXX5)O4eey+8h?B{#Sk+(|TAe%prpKJaciu;q6JA`=F z7(Nu=vMFay_I>rlM{JD9{{6S*p7;oT%S!fx@Q5<&)w0aD#%6P1L3N(I#M(~Y5n}1d zORSA#Z6g^qW53;UPhMheeDV@&|I}NJdll0;yvybqc|7z9xt8#b z$Z1*YtHZm@e&np>4)3zQI=l-*DEHni_h)Z3{lJ(VD$jnN{O6h*7q#?z^%3N&@AIR^DaSl#&9!U5><46A@#z5hj=bcvZ=;sspKN~;(ecgAplJE3d<^Ee^ zjFtO;KjFI)zB}Q2BKIEqX2Rc9-`dGJk!*5Xm)ps@Og0_+IpucpGq%Qy+ijfVbdHdv zjXmecX2TDDJ`9;XRc3q^;{R*4)TgquY8`5*@p@ zY`eKL^sbC7J{PoO=ZMH+C+uUzzU^t-VLqPTc|+NDpLw(94Ki%XT1>Wn_{+0QhwO7p z+x_KP8XIKIA)etF@-5lyd^X;Zw%z9%W{2FCyhOR#6b}A;uA#Y|I#$=`8fO1<4b4$) z_dny>+IIg-=33tZ`|9(Wi(K3CK*~$K+~>HJK)#oDSkaoxkcpF`+%skMp{?!U;;|tXJtN87DyXxBo9mxM$+U5NToXCB>f8%vT z?%B)#cOv)f<^LzUs2Yv>5#`%8s?fnAYju8n=|f9?@V>{96jTn+hgs0ZjZDpXS)JR8=u=_ zZ6s?O$y-BvpW9>hl^3J`pW94UcpHA`?(80Q?ebSNdX|Zp|`+Fz(&a?Gg3b&@qPvb53O`a8*;VaM59VMork<1%)h{Wx}#yb-ye4Iw**chy*7h(rYbEsm=^BlBvg!QOH9CJg?w{|~c}g~&1x&^~jP*i%59+w* zuhqSZXZ7d#Yt7E{*P5N@ueG|qa-GRvi2H<&dvUk5i>z_=BEIv48_2!X3Ec3!HOkHA zi@Pi;6qfxD^{p+tg`|eHV&v$P!n=jvJ@|SNk`S;#t z?fTx^O#c5la-q*XXF2;YFwP?#_sTieZ?BwV`of`~UpdEoe&rmqPxku++OhV2f6nZD zf6ny(_2b4r_>k!chdBSihfL>(4_dp(wJ=`f9g)S3#L^ER1k2ABbsX700g!DRBV(Ta z@WHe$^Z(z+#isPte<7wZ zjgE}IiY)eRjV_bDeTng$;{K=1D);xHUYElrINHe;#e1p}9P7&Z z-emfHZxVgXg%WaMj%n84iG2<>ePPLC)QL8ey?U9<9p%gC&{xUaDU-QV4!U?QE(aGo z*2OcpGUwD>@-59=@?8O0+dG%+ljo9s>|FBRJ*Ruuf;R0fcn0(A|JfEUT{VVD~nH7;)KM=!`- z#C&)I<(QJSE%V6#+Hamw0{L)0Iahk#5#-^0vrRj8ewzNZ)-jp~$F@XX+@8-?cFhhM=X178>Aa$&?Cb-)r2 zWQ_r`)urs~(s-E9j@e*3s}ATKpU=qS!3VPXuXSM%?}RVuJJZMxIE_7`N5;(o#*`E7<7Cb z&KLXtSl>9h`nzzk7Ig7lH+|;st;MI9_&I$v9OKf(cVgNPUAgyA`AXd4;t%?vn|wFb zO=7I;?E71?_D@&i4W=R&k!5_l_-@dA@ZTb4ZR*$^LS)SAuDeUt5yom4dk-B`vej$v zZryO+?-PB?`CYji%+U79f^22|d6r|;P1f{o#ykci?5iXWyP5xeq@tg#c{KVXTnqY? z?}!}x89EwQU2yavTRUXD?lH4TRy*q+(>d79$e}G@D|_rAy>IMh#~w2MV-KY|df(X1 zUSoY5IODiy>kpa_>knF8>kpcp^#>*XYbEsa#LoER)?Q&h?%DX`QkF5P%<%>5JnCi} zp0u(Xp0v6qp3wEBn@v1nIulQ%I?p8lY$?uYN%mcmbM6?cnQZ7u+817}8p0T<% zJwtuw8Op7$P0z%-lGx}~eNNyWpqIpnGGn7RI4Cin<(@TH_mY_D4W1ymnm;E9Udg)n zJCu5ZeoYtq#s0TM9}b^bYP$~GJMz+US-ILRDc^?kX9fR0760zXzgN3Of;%t~}43Ql5(+ VQ{G&j?_O7K##jx&$1BQf{~ImUn_&O| diff --git a/src/java.base/share/classes/jdk/internal/icu/impl/data/icudt64b/nfc.nrm b/src/java.base/share/classes/jdk/internal/icu/impl/data/icudt67b/nfc.nrm similarity index 50% rename from src/java.base/share/classes/jdk/internal/icu/impl/data/icudt64b/nfc.nrm rename to src/java.base/share/classes/jdk/internal/icu/impl/data/icudt67b/nfc.nrm index 08195f58dd35aa0815b90bfa80085c4e99dd5a2a..45c260858f9aea1031520e13b6087be76b6c9301 100644 GIT binary patch delta 6578 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 delta 6327 zcmb_AXLuCl*1Mawvwe4F>&*7P+0D%C^qByO5Fi3Kv`_>@gaDxkh)8#-0wNF?Q9!vg z1(B+On=2Rr=~p_^QGzrP6p?mwY2R#O(EEJfkMHqu&-1?T>F3OQ-uCSFd5W3}MFrGX zBbWX0*H$KbzD6dS#>!;V|BoiyE|XUvkg>0E zWtwk1Y06QAOpIxOX_e_J7y`S4Z;1v)eiGbVZ`jalsudydm?8w38aNFj)E;^p`j=T% zX;3WB5HYzjWiB>PGp}lpn=hs@i_=nK8L!k>D(a}EmYRAwc-iW)My!~XwFazlEBO~t zslUd}pZ1daOTOYyhqs#ldlCmJLe{m`Yf^bK<&Z6G>t|bKyJipD``K67uQ^nX=S7bk z@;C-G)T@5Xrm~x5zmPpTdv+bn6DyPxa~7v%j&*4RF%E>~)#6flB-61stE7vFyp za$I)&(%>o+lGGo<>Uuiow~{MDFkH`pMX%gU!-)ocn1x#?@57~;|7(%Ky>k{cXi4_N z;Ym_xN4D}L{1&`O{6%F^z#od8R8jddiBF1~RC9n$_4>MPQf@W{{JA8E8{mELY4|F9 zNAmF$(IQUqyt*(eflx?ON$gQb%1h;l_>v~5@9=v#MF{CBIk7ZDh9D_q4zdK2{*dCe9LPPv;P4$~nim#JRz_&3V{)!FkL1)TMX1U8t*xtHjmQHN=%l z?=CT>)$0djzL~iqb6e*5%-Sql79~#5#uU;-)@bwNS$$=@{u{D}WzGI0Cu@DyS7|!y zgk(^VnRPGQEDkk|78mQDq^6kOQhjHtP~BBM$-1jnn%*^ipf;J7n?5$JH*Hc!WOCCM z({|GybyD3@{en!M^~iLiKo1yFA5vdd-L6iVpckPsXdpBcdRfZ8O}$~B zVt&h9VSd;AfqA+4WAjGy7V|FiA@gbT_vV{sY2GX{i^>97T$ZpUk&a_YT3AbCOEYa! zn{R1j>1^p~DYFc$&)qWA@_L=lILjosDI>7px^$qKE?JL?*)_K+stRGrG zsT^wRAqPVF@y7@9lliQ8670zw{iAU`9zF3p&-$sgDtg9RZQW_zF9ka+wG-BJ)=T0b zh|u1!-qudCKG42xeQe7T*FuE(UG2vrHSiA+Jd%RncRk_1v#(T zn1&FxMz*H5Vu?4ZPBKBlrsP!QEXeu5RwBM(ZXz!gzclAMyV-h4*8S2t%7|_7Gwb2D z(YBNnASPm#tc!_++7{bZ*jC#%r0r~*ZCjP3lC|xy z?X?}W9k-paU8v(OH@)>vg1`$UOyWh%Sdr&Y%7mlW1n4QZ!G zWq-RU^@HpS#Sl`cKOg-*`a|^R=-udlVzOAawA)9CM}nE+uZTTkiTxvSX+9+W>{cmb znwUu@kJ%*G`QlJ#d5$aXEEW)JoK4iR7#5@JXi4^)gClWBtchof+g<&DHEEgsQ+t(& zx!oDh#ac>Unq@1eNX%*pZ7)TzX6>}^w;!&H=kj!xpAeTuY~pOsRO>mJTzaNR4y3F< zuwS%algYKa?6<_2cXieS`(sDOZ#M14#y+nKkfetkMu+{8I59k|@~p2+PL$MJ|FMsi zHc+u{&#+$4uzpfjwq)#Cz3T-}6;Cts3!WT*D=WPs$-NR<(TT2 z>6q(S=vd+S#Ie!w562gduN?avhaD#zXB{<;9~{3r9>LkL4u)U{?17^&0Sj;;+#GHV zw}-pHFT#D`0q{_GBs?CT1W$)&!|%W!z$@YP@FsW*ydB;HAJCrGeh+^Ge<$6BH{oC5 zf5T6Z%ua|3F(6jNiTIERl82B8j}#!yk=95@KrZ{Ii7dV$YKXGn!RynJk zUpe`Yao^{qZuR3o!?>K9v%QDNQb{Sn37vl1{BGR=Oz!I0 zFxxsv=X3RO4RF2c8s~b`RpDCX`p~uB^-tGVt^=-no%u{g?U!`m_2U^!E*!27~mx zZ)|97c)`%$@Va4&p~A4-yTrTNTj{O#?oD}*8a5gBc+YvScyD=YeHlKj;k4nZ&+7B~ za(z_Vq2aDk;cMb6_I2>}NYh4x(dX;u8|EA9o9dh6TPSfzncTNRYU`v{Wo&NjZhXx+ z$yj0hyK${?i*b+fyz#C{VKSIprnreWH5X?4wh8Z=+6sU7rFIJ|eP0XfeMg0Vm|hUR zOb76t_I>ZW?U(zFey<<*7y4WKJNe7}Bm7hS^Zg(BH~Y8y|K&g9zwWOM00Da-8XyCW z18o950)qqN1G55)10M%I3+xCS4O|S|4$6bZAQB7(sbEpCG*}iK5u6&F6PzDh9Q-gS zrJFMK304KS1$PI(7WM>>NTY8O5kgHm*^m%w8fq147wRnhC{aB^y+h@pA)yhW@xtBE)X>b(+|a_%ve2r~I^jvE zGW202an2BIW?3ilree-KPK>ZUp2@cvGMtTr7?w6CFx`mSO3D1zH1b>-8G?aJO); zaKG^2@Nl3b&?P)NoC3N7FNLRuX99hI{=gt$Xr0%&;rD>ofKlPa;T6C*U_y9xc!T(e zEXvs&-WuK!-Yd4G+Q0|H$HQmBbvNiU?^nV%!neZ@q!im{#;RglC4^PPwn=9hfNvrMa5};P=Oay|@2H6s z0hc4KfFC058e&P@n~~0u9>Cp5??^fDC^956LX{aA8=0umM5aY%i5MF-OBZcDJTg2o zq%jo~St!23!o8QMJdux7fyf$FB=V^$9;s4ck!lqg*{Nb9`&Ido!>WSF301SmIaSNZ zMaiypqgK_>s59zUjfzI2sPyqZQOBvx zb-OSsL<^%WqHXH3sEBqDEBrmhZ4p46-c&CxNo0uyOn%*R`5TXjZJ8pm6+cjV%S3*g zx4=9mAgOc|e+gz*4iH+&Q|C>S{|u=9BD?x5;LI4?<5To zTUu5R4OqQ)dgCF&G-fj2(@gh@FXj8@njMmDu&zPvWu0OI5kXI3B0sT)dGu zuE_)>J~~mDC`uG3+9cW~N)ufZJ>p!VSE4LYo)|3J3Otg2;?u@wtLLRlG3I zndi+5=0(LZ1>FnMdE{M@+Vwi@r@Y&F_ws7<9;0$J3k6UuYLv-Qv()PLHtIyZ^_inV zG>RrrT(lInPbJLg8T4E9B6mi$2EWSQZ9gTGWXdF*9bzoR}92ryXFq z7>W@Xg9%s@tSQz4EyY@4C0K{ND_Cc&8`cx+jrGF@VneXu*hp+Fmck~Zqp@k|cx)y% z2NSXPu=n$>=aykhuoc*;ZZOdx$;7Gw>W-jn?9N)Q*Gb<2a66F*y!n0Pe>9co@&c zQOt+}IDwgQ2D9Tr>>}O-FTz{l?eJ2(E8ati_r}ZdA^32qx~;SE*PoF1I0=QG$0y;_ z@d|tqz8wD;UypCXx8U3HJ@^6qm`skJ#=pZa<3Hlkp^x8}+M}dGCQmApI;n?}j-)3U zO2(7PB%5rUOuy1!mNuDD9BWmHE1JIJ?5bK6?Ok7rbgx?aJ02Y@c5FsujEqhc-)c4| zYi4x*6O*_!W)-QT{G27x)sJM+N^w+CFrzxUS6o_@FFq>r%yZ?4jhef(&nG)3`zI$P z7bG_(_lfsVg<2^SVL^UP@1;v_|K zWFxW>Rzen%MPxDA2JK3=BTLDydF#j?WG}LeEGGw(!^jcjXmUI`nVd$>BSGOApH!PGEnBsHFzNKK_? zP_wAH)O>0owU}Cl4x>Jz)=(R$N-RZHQdQ_^YAdyk+DYw2$H(qbUsH#vOXf>^;LE1{gw43&$6X`IWOXD;}b95tg23<%O(ZzHdx*c6g zccpuz_YB>OE~Cro!Srx?Bt4c+p|j}8^bC3yJr{3B&!-pCi|J+bNAwzc16@g1(be=0 zdN;j4KAt{EAEi&x-_n=pYxGa_Z8~+2uB9KNa}#G6Ig`ZzjFtfzD+4obYy;zG!c2m} z8Hy2@LZ%3-WQv(KOgpBO>B{tAdNKW&fy^*w1Tz-f%A}ad%nW80GnaXfSm>M;*^KREK4+?#9n5ZKKXaHl9xr0fFc+9h%ys5gin+(sV&|C0Yz7Okde+R^Svz(C z@5(w^FB@c|ESkFxyT%eMgI2SR*rsR}Tg5$J7h zG&i1`$W7&DaC5l%-22=TZUwiBTf=?IZRWOe+qj+Fe(o@LJa-{?iaW<$;4X33xEpu| zcPqu+;T~`gxu<*vpTnzpJrDAB-pPCUARpxuJi&8(Bfb!~;xJ#t7xN{22fj1kjqk~q z@dNoG{BV9GKOT4U6ZvWUEPgIOpI^u?;aBjh_%-|nzLKxvxAHsq-TZ$3Ab*@c#h>FZ z@R#`O{4M?t|A2oe6v>4wTq?1k7W9HyunSJXD+Gn8kPvWO5Ewxang~sW7D6kbolq)t z6M6~#gn_~kVYo0-7%QZN$?40ka$l<&Rpt6l_gt0hMl3VQqhiVQS(!Wf)=UtGO^=J3 H8QA{-Td20F diff --git a/src/java.base/share/classes/jdk/internal/icu/impl/data/icudt67b/nfkc.nrm b/src/java.base/share/classes/jdk/internal/icu/impl/data/icudt67b/nfkc.nrm new file mode 100644 index 0000000000000000000000000000000000000000..2c0587b6d455a6221287faf70600adcea6a7ef7b GIT binary patch literal 54144 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 Ky!El*-@gEZFs|AF literal 0 HcmV?d00001 diff --git a/src/java.base/share/classes/jdk/internal/icu/impl/data/icudt64b/ubidi.icu b/src/java.base/share/classes/jdk/internal/icu/impl/data/icudt67b/ubidi.icu similarity index 73% rename from src/java.base/share/classes/jdk/internal/icu/impl/data/icudt64b/ubidi.icu rename to src/java.base/share/classes/jdk/internal/icu/impl/data/icudt67b/ubidi.icu index 9e790108d3d29dffd665f3bf8759f938b904bdd3..bec7b093064530bb5049258a4280cf55a113ec8a 100644 GIT binary patch delta 2335 zcmcIkeN0tl7(bVD-tPkHKP~NtKfeftw)*>joKg& z@`3NrgRpKvTW#Eq_JFkyeGco_=mh#6&9(hMqF>N8bXyO~J$gn28qkB-Pz0bUKhe_z z*z1~p>_;&u28a}#g$+Cf=Yy2v3OvD$sK#}!)_@!F^APzGZh^HGH9^-B+=i-fhY^k6 z1>ZJ!b~w?X?ZNv)x{bZK+qGqNm^W|~pTTEwAHIz*;2u0c3_{U45=nd{Sr3v7Xa+(i zkSU~`RFb)5K3Pa|$r7?0*jLC}hsTX*Eop_gHdPug3VHvIq+{4ew&2D9ByAK+xub^}3LONds()!&moUVfP4Z0!3(sr9~uy*O49vwjKR`SI`y#!J z7~nNTDO@Z&`>un`}V)p7}5+&Xq^Q+!q>Qor@azcD{8LmGOgAN&RF&8 z@ld(S!F`OahK z-rM>%{fDD^y+7NlYu*2nHEm(8rd7^HFjLcLx~B0KO_#VH=m&k$(zcX)^-Wu9AbQ#S z&g?LMG4Bwa2qKA(gh&SJEHc#5W5`6rpCCmTFEwK18B$5ANex*>Rw2HItS7peLh3M2 zH)0sy=Ik-D%h9{ZUc~m1{kR_>N65Eirh}g)KaqBF(}=-GMrIP}G-A|a2T)7cYYd1| zU&0O15DAa~2GVIJ_0S14jFL~M(a{OUELxthDrgmb0huf4YTVb_D9NXFq?B$mQ|OzB zy@Tt$I2*0K^i$V%bUSTH`0%vHA3aRl=t+8w-lXT~McTV&Mr-#bJ4$Rwyg_eFnr4cD^9s;g#^$#3&N&F%jz!t2I_Uj#+E$Q0RPWE>M?#bd@sQ6P%r zMa67uY4R3xU}gMhM78~uNa8lTeZ|rQc_rTN0$BP`kHJxMSa%WY#0J+F+Xa}z#7^56 zdqg9&r23mSLd^+asN_%GR#PB~YseljL$F zy)2`09TMwoC@5dEIdZ3bBhHn3q=o(`81(x{y<5N`9hA-Z$tHQ^QB=89o1D#dwfjsTP~V)N+(ncuwKu#Lcn~7jKw2 zzcrK^UE>~#t8uXP&O@tFn-%apwcYp<$9Su&k8QD)uJ3U1=lmDpdAX_~k?6c`)kv4v z?Nt-5R-W&)a{l?KuMjz=PPlA!T3xokgGXIJwK}RUs9UPTk=x1Ef@pKA?C~}a+!+zHBKbZK ze3MVDR|~Efc1Ul88*|3MwE5X^FI~bPITD%*eDGjKwl#EGwFeCetwpa`4aF;TxHmN5 zl-*n=t&$m6Jeb0vqQqzInYGY>=6M+y4OoR`nL2jvh0`TFlhhCDZ>^Yf-GCQIWWke@ zvoRRL0EM!t0n`$5#(ClTyw7lS4l}0)AvKZ=gDbsIG1c!BNyVR(8u7xJ@+3Hvn}uEc jhEMZB{iGb2Tk3~*%aUQo{IGR={xQR&Y1Z!Nt37`Kjc9rY diff --git a/src/java.base/share/classes/jdk/internal/icu/impl/data/icudt67b/uprops.icu b/src/java.base/share/classes/jdk/internal/icu/impl/data/icudt67b/uprops.icu new file mode 100644 index 0000000000000000000000000000000000000000..ee08ff5b011d49d5866413c5856f37f58b0ab8cc GIT binary patch literal 135664 zcmeF42e=bO_wYAmOR~G!B%7XluUN37h@hgVh@!}~U~h<6P*iN7zF@_I0#|&oV@E~B zj);oAH?9RcV(%S$Z{ImPnapfWR0i5?X_J~}CSY4qyoP0`z<_eCFzc1K@~z8-x)`g!!b=r3YOjEN~RBesbvh^vcz z#R1}a;y`hTI85A0+*2GS9wHtgP7qHLr-)~X7mDYJmx@=4*Nbz+`Qn4(lj1^gk@$}I ziTI`XgZQ%~NQ#t{a#DxXF7=dpN&Te3(uUI3(oWH7(kSU*X;0}`>3C_9G)_8Cx>&kO znkL;Q-6cIF-5@gY82CV8HGFO-kUPs=aKugUMqpU7WFr-_T?pA|t-l%zOH z>7f*$w=R^G#YIYQrLQso%0Vyz7L94KjJPPaLTvR|-&k90v*@(gR4v6gqmP27WK6Z3$Qfyl6tk{LID?~kZUF^o#+}K^Q8^yk{hhTeJ#Ga~@uf^Vt zeH!~F_Dk%KxEOmr-X8B6*W=lEuXw-shVjAiJ>y%)cZ!dS9}+(f;y1+S#OH(jK>YsrbMY6TuUh;GoD<^j#y^d}R*{!bZKeKw{P&oqMpf0WhYXeW zR5LzBEvd`WIxQh;6}7k8S6!b(ilfw_>L7J{vUKY1qOR^EE>cIUP_l>>g`eyA|AsnsXn8=tiFa@N_`8~tfqb#zf1j6{SKrr)!+D7 zDr*t4wKdhf)$7w}srvkwmzHDlzmoqNz-^>;h>NskVOm97Q(ITtSlbN!wIO~{+O}Zb zSsU(Wx1#qWR&7j>m)oYnyEPciI!XllG-K6{BT?EZT30jiG)9|_k~V|ZTPw9oT8nQc zTD!cND0hr@rCaB((PsPG{%=^cInDM%yS>@Sr5mT+P4a0EEZw}VX49U~p4DEc^v(Kg zX*J{0i&vi2K3+Q6w720{`&Dd`Gn@9k_Iva`UDKmz(KC9RzB<&`();Th>s#n6=-cYM zfPOFiFnz3kfPReBOFvnkqC6`dt6!*}rC$NI>-1aoyP$kXe@cH|e@%Z^|4{!@)PY6% z56<@ft^d0Q{{L75`X7l{A{3q08i`bk6chjQe`pPmeK&z;tcw#XCwf)t{jgMCi%v^) zCN@ZHinYWJi9LwbK2MBHz&Du$oSP=bCXP;=kT@+dEpZ<4NnD(`EqZ+7p2Q=GCzU0M zs}eV~xc8*eeSss>^U~j&tD9rY8_f?gD`bXcre_vr-pTgJ?wCC{`)Dqj+bp+ZZgTFy zypSK5pO~MQf2Yu+uxsJS!o2vz_=BpT4pb+`2dWRk^j>@*L0c~Ldgyg+AMMJj<~==( zvOWktBOXqK6N3^bCmv4xf__H3u^r4OplsEzp;D!OH(0+-_6fb7+>mIJn1P@WYR87mrVzLTlkX?LOMY&}{hA6(y;Jd2Db*vjaw<(*5ErF- zr`AgigmOq~7}a9`Q@f@{TIJ}};i>UZpPZT)ou&*)!PPhh=x2}`tVumJGc_l5M+(+N zbXw~1)PmIgsrOPZq!xqMx2ezI6Yx0}Nu;!r)>FTx!|C>P7B%VB)4kIxqz9(g!`7Un z;R-4x-I?Aay@PxE)ThDEVkCWVdR+S0^uByl`V`tm?UIjcPEL2#ZY9{Go_5pc_~)n{ z57)Psq%Xz{iP7n+#6{`b()XkvN#Ed~(`muIBi&83*k1a@^rG}zSWkacyZ!&AM|#Q9 z%&shk_b9xd8^PJWvIN%3_vzo9dQxxwJBPDxB(E7VB{Si))l;X}(n+aa8`I1jOzmb* zb2TW}LcQ6aW->Rydi)-9%c^EKbEG-SJlGs(9&4Ur?rCR1$t;JTC7C{%RU6HnSwAy0GYF$HyJu{lL79UxV>8EOPR>ltoDEj% zbBNC#(=r#~T30X6T%Nf~y*6_L-3ID);D1}@p3DQ8CoK|a(0dE+SCrV4PZaKKXn|xEX~MS>-$_5 zKD&|Z_AtTc_1}j!(P|fdH*=FcC_C1zZAG)RuFqyCw9S0-b`-`&2wz2yG(dZV?h?TodVcQ|b^JA+F061UR-5_@a))$pE-rA2mj zb|yme!CfRA**R4IzbgOPYn<8n(J_M2BANgf&wyg3%m`VK3NV?LW=mm;@Kh)k+A=gH z^i((&-ZDJJ(igx7z4CBNQR8GFE-RFT98BRR$Uxg!m<;EANPl~MX{`SutbL>mYo!Ep zQD}o@OM-;8LZma&WvwS%+ogyK_V&KreLDwqH@x->j&0TGx-Yo472Z(xcTVos+?u7^ zA3htdFWlQ{n?xcSVxd;Mg+;MgrXyKdo#vpLFl=#*L&ORpxHk{&{2c54lfQ+JVmVRb zds1IKpQ{m>EFGECRxzHo>em-O?tdYRRv#MA92II)f_F9I=Sl5eC5y3JqgFn<&Z`Eu zO#Y+LeFOW8GQOgfb&a1X^o4y7RgZIc11nA>n(Pz)bK+^YH?}3|9!OfmSlaJ;OWGd# zugs&?sC#-mfH_KT+7ZDmlx=HQ>GU zd596LwN6`Twv1Lksrd}vt$Jzw&bx7mF{9*}pKt5$k+C=S{^NNoufb0$tTQe4%xn2b zk8$gW);3^!zg-ewE48`?_#XPpxNrSE>k(V=?uY2TgIBcv>#>!7yL*CL5x<`xQLAmq z`p!Z<$u^cM+nQ+6&A#QFwZ_)2vn{MQzLb35{MxUq+&T)(mh{qI#_1o@!rS)S`x#=;3@3 zD{5&=yocBF;<_O1;%Bhe3q3F|?H$QXJgLmvoU%O<`%I$vIW8|*IvGTG)t zOST>LVA)Y3wV>^bSFY?Y`yNBuaxO1fCfXJ)ol9!>qE_O~$6)*J?TgDr*EMcuvYhU1 z?Cd@1KWe?UFMKwVYd>U0Fl*5MP5nrj7dyo+v0GBf9M%MBAGZSQACcV4@AR&L3>DndxHQm-&qszeh zMtoQuGm@;-*LVN6y`%B$mw~aEnQ5p*drV8JZ=}TR?$0G`54SHV(SyC?NOt9Eb%EO5 z`INd&=Tn{i@QO75@>ovGjQPAjlh91pZaw`ct<~d+K3;1Gb@;O9uvE|!`l4%qY(dl$ z4V&BJy=vs0i5VC)Kc0s$=s7g=^E*f5*CNJ~rD2(z%f&2C$r;J)Uj4?NIoBIrsbI$d z^uU+jKEU#mBf9e&fxV93IEWwSWuF0Mul(?fNatpqTXpW(IlObf&M}=wcCL<}9ORoP zmiXHiPPp}0KZsQS8l#ccV#17VEw{uz9qAPj8cmO;&Y0kQPH(R|xx&M*EBl%wcDA0W zCu-P>^^=!y&CxcQgc?$#cJJ@^tWEpTn?;efNDK71ggW$K@Lpsu<@?BFazr7$W6>C) zcH z{p)Fu&&S&4wRV~L)Ym_IG^t@E*?ahX&5|Q3{*D^yj;hhlXjimbRORk?r`BzBrn)no zx$a_T8P7GlFa^B4vhzCnuHj1(N#^|auO(vyzdvBztl0y;H(oLxJH7OFomPjBJpyZZ z6eTaW4K>ypk4=p&h{s*|D}jOWn1gKtvPJE2wC3HuUCZ_e8pTSxr*{qG{a)S?sHOcU zdt~GB_RQD^`w^EM-Pmyrtym*V>ztGK1N}__&pU!Yrz`!X-#4UAsY~jXRd^l>eTNVa zdoQs@&k+3V_6YucO71v84e32zi}yQ^sPqroLxQha*;{nhXeMWWu@6q)`s((Kq(+vA zZY``4nfj6~NA0ABUi3xJz;W$(t&{qC=I2HCRc|}?fmvve>?O0?CF*6@de^8gmLAIp zcfODpf6Q%G_U?h7mToVyJ@|c=$nG%y}jphLwgo^U)wWbe!us-dmnPfVzkHl zt*l*A)Uwm_a{KzXw}dsj9c$#p_H0|TbysLh?lXD6ZD`k%^~bW%_al2B+Wl$Ayw(f9 zKj66~%SvRb!Hiz@v|jblJ$BKx2lDL_T8&r#D`?{veWjk5`GM*14Cr9b<`w^^{2V?DTz3Ke6n~OqblQrORXg zbRjjer{K8*eYuy9XxLh4Me@rYu6~d4_Xx7EKG~POz8YPt=?> zuUGyE+;Pa`jNxr4GrN2JhOKo>?*Mk&aSPCR+84U~LM1jwzH7j}RpicP=ld1wc%L%$ zv)i@mJtBCnN$(fo%5XQl6X3;vZ-jgZwigvNPgn*MzR6Lr?KYtuBHOB^y+3()C}V=_ z2faI+_reUco(p%ozt?j8!)tSX;9?2ZZ}{~7<7P^d#eeSqj;DX|mMVW0_w)46jTU-- z5dw)#WG^Yh-b42ncIRx^ioyK~ZDd>GoV{1zp6iNFxnI{haE-ff*Lq$3)c)#*>LzNx z&cU7ix;N||+`V6uRTplVH zwa~q={?a3JxLZ+`PNhrfj;XQESXZn&uEsmv$33~*>u4y~9qrXh-TMjcH^2Ve`wsQ; zE4}s(FP&e!pT2eu`o8cez1DQSI^Xrj))ThKYK=%9eXTQ-SEQe=ksdK$nvH21lQ145 z{I)37*UpNbycdnEuf%t5eV)wAD}tWKHCNitd)X%_mFPLVe|G!~Cf?*z8EbT+dejgd z%Y$c6b~{^6{7fhQ{U5O>)UCat+9;g!}}4Lek=4VSzeUzdQ;HL{@s#Yi>BH6 z>v^cFRi|-&rMoY<^mwMq&Q^)U>hv5IOLFBG=hTiReGk!+McA*mQ9Yh#GdU0OwB{~x zD+aAYek<22d+qmrvF@~jE@S7pNGaHHJeeri%5>MBI^Bur@2g&ut zS$hV#XG^l*&4%j+@p}ce4K|vS{W>FeS2EJffu-{|P@x>}ig&B3+NpM_-I}U(YF%2l zuIin7m)@OFYv+b133esA4b|v0x{U6mn(Rz=CA(8SkL^n#ANrCGoLFBY6MD zT9#{U0g_p?mWKL{hniGZ9N#ayEL$1vI#zS80bC|&Ftax&O_(G<)?6fs8t>{s<7=V5 zt<&LZ$=>e?lkD|IYR5Dci(5p7UP(~a1Fq@ugX4oWo4+x*o>=seD%9)mUB=Ira*PQQ*T7B}ezqk`v9&$i#}L0Ab8582vo<^f42r{hP{`F~@89Jd|8a7k0mFGL zw!wdEa4rS;^{C!CIosst&V2rLTvGD8C%c9%T4%sP>wtcf4e~)7ynK6%vypybANc;Dj5@X~_}^Goqmozq)aJe} zgBIEfZGkV{Yk}mluYZz-tTV6nF$-N=tS{b@eVNFo54i`1Uv}?U(hs^sq{jCYmyGN? z?&S*BU@r1W=G`*AFNf?M_Bd~?-N#-_3$2k7TEpI(O3nGLn0@1@ zeSS>$Kk2dhziZMMzGQ9kTAPe(+q3^RZNXNv`}6TAlR7`Q``517_g=a`I7{ZmEY43M z|F&wK)v=s@l7H@cEcgp`tyir)7$4+QE5Fn3my4eN@SjRvGW|RuC0+%#Uw!wA;dS^M zfeCl<Z*b!R>X?+-F7zmTCHc}5Ifezx4f>y!EUNthAu zGP38Xzix$E_v;kk3>?oq@t^PPw>|vq^?H$ek(iaNoo1i+$nMBu@3GnveO@EkK6ER2 ztttEYgqKHc9l5ga?Pp*6-abrQuQ&0l<&9g1<#tQ8?CuDvsc!c<>U?#4=fuv*ozpvK zbk6LY-8rXoKK!d`V%OxZ>0L9rW_Hc)n$tC({)fYUwE$~m@2KSS`gOtmpDAl7RCR_r zQ=P5K3n&`gk3{GgIypY03f{3KO-(K6+u65sy)Jl$rMnLmjo8_jT7!OBv-;Y1L0`C6 z3iCosLuY^_L+j)oDr}F{#!sCAHTcetEFefzecn6O^;%Q#T?+r@t60c+7TuEmWpEdy z#SLtC3VT&@cWGW<=-QlrM$qoZ_kf&$!xw(Pe+{{_gR8Q;+?*DRHr(ck=ALM z$Gri6-Ru}jU2J8oV;s%XOoI zyXvfJgMZFx)g6n(okhi4*h(~X}ggB$9z(9^G4MN%i%Vn3d$C`T46a z^f-V(LdQ$jr5f9Uq- zmMbU&UEt>8tI?J~`)}7)YxW*i)qaAz*M6SfdgteecilS{wa(8Q@479Xp3_)QkfQyk z?;o2dRBC+w()V-l(*vBx131TpKyIqABymGtOe`R0Io9sjE4rTwV$^Q)4Bdon|3t!>0NTan3sAM3jkUG1rDTiKSC zTSjgX3hg zI$QUCAMpJq*?CPfGWqS+-8w$MiRPm{rOQLEd3&uN@+%hcr_sTseXG(IaBr+0+4(#6 z+~29;nRnhVzjpZ+$sR?v7+p#%@$=L#p4Zp*LJ#J}Bt8q1z3o2737;PF%g5FyTSs2o zjaf+#FbBR^JWAxnbQOi8Ks$+N%S9w~M2VJ8JFPp{0*#_}%z&+scMfTd_LwipGT8TR zqO-c-v;J5sP6>0n-`z}yHX6hBCa?94R{X9_{YihCo6{EkN_VfZpF~TRhRiV@&q|#y zum1Bse(e&yy>*Opx6Ia6JrZq??vb?aSK50(_g>WETEIGK)xG3oDQhjif1mla&d<4Ny`J~)!pRZ9IxnyxQ`3KhZP(;4_^{GSY@uFR8B4{Q=|ncRntq{j=X`B_2*K zsgt>T$!YKWN{n!?U%LkP4d=^aecD{??bZ7(=A-yNkkoYjV2^oED%1BrzQ^gh!u5ia z^Y}|+uxzGxBpzGAR&npB@8#@=GYWsNu7xv()$`A&PpjSPLU{V^bMXAzh42L2b-UN? zUI(5C@Koo<-ThR&KM+S|d&d1w8SCi^eHZi_3cppsuT_1gt~b>fnp(jB_a7Rf?=hd{ zbv`Y?{_Frg7yh1Mw=#`ou|0L5VzYD)PJPJwZ49D`4=IO2_Mz5O3gXt23Wmb73M^PV z)fV6vH_2)rHMpdMt>x{)dC;jYzM26u#A!`erQ?Tz$3L+@e6fB$*CJlBu)6!)$P>V&Ri)MNavhS~c;Ype}R z&)b=lQ?G#`5#gp#|T)3_T#p*M)nZ@xzj(mPLJ?GUet${ zUe919qax6|{c4}LI@_zY)aZ{ddmO3rTL1Opw0La`>cfvuLUqp4>->S}h^M`$_VY9J z@QbH$LH)z0?6G)EW{u%vd!{zcLrT&oeopsqyB`^e5B-AL$L)*zJv8$9GTYJgL*|Bb3QM>VzWN#&?bH_Dn9&=kq&%VXx<2SG;2=@Lt$5-nqnY4Y_+d z+|4=>?&Ip)*{||ToV)M*^402}_fm0Md_q&ui|#-Edm{DlE=e5D@kOu6IDJ`m>cjVm zU0WgX)CaSWNTQ*7XGx=oFN%!^9Qn`+!8>p!vaF}&=Kr2ZrWJ(@a8n%}AS zuA{fNg=%Zq!=BH$gR|_;8hKfM+T$861?FQpoDyxP(URtI$59I@(H`{TEhe9alp+fa7evChAocHV}v)9zKLe$H6F?iClT z3vN5uYR^pjN3^6@yll6l#r?8p^s3oo>>hR-U#sP3xBJ!n*M`{aQ&GqnR5Q;qA(5>< zAF00Q64AE2OZ&5a(5Ke(euC`MW8SUUwa)*V+O7Vz=Hi-*qP+-;Zg|V{dv)Wo-}yjA zFHfR<_9^L=zGh2$e_!K0ClU7V3GQ00ysiA}najQ7*aQ2(U{*7W7sLl;`QQO@ow>9_?OlT z;$rbV@iXyT@mDD%#iW!}l$MoNk=By>OB+d>OIu4jNqb78q(h{mq~oPY(izgZ(k0R? z=|*Xubg%TN^tAMn^oI07X+3>JqM!7Is3a~)%qo8ie=1F;e>N5QF}YiQQGQ*1U;b47 zM*c+!DY9ZHd1V=;r_xL5r);PUR<>4lRE8`2C%(fGv!<5*H}2WdaiFQ9!tkcvE^c`#@5Q6ojW-s3)mY)H4h3YGbr< zg)OyMX^4KPezbmqewwj`F{IePxREwnn^U}{cxO44*s%D3_O147@rmS*sq>AM^fL~=Bwsg=11ld^GEZ~Oehn{eUX17|6XyGj0!(S zCbB)Vt7dy;`(@1RhS?1>%V)}&)iP^mHppz6>CEhq*(0-W{- znmIUgcK+M^FS+mS6heh4Ore5SFbmm2TVaL5%D`&Yd@YzCQCzForJk=|(zZ_9M(x?c z^V*i$*2T>W4IJ|wRdm(^17VL2(MXK%}8b8XpsvJYez0gJOw zWS;{T=2pmO{^kGZ8pszW6eeWf`8gQ(EPfNYix96A1_gospcg^>T zk1P!rzrL>C2UlES*|9PQN+vQ(|yp>$XY8?DjtGeM)EOcjS)D z9hEye_n+MO+=SdQ|JMFp6aT;L1@Y1P{rW?q(i*v~S|dC7U;a<6fp4;Qe$4(^=%2o? z2(R=*=_lid$H&JfX69z@$~+XGoOvqqD{y7z`pom0Z!+Iz!Wq_ zpQX*r#^X1}=VjB`Lbg4AZ~W=(KG}n^TW7bAzZ8EX{%CGMlWdl=$n*e4W@cvI$@a*O z%+Acdk!#Bh$xY5ZnOE{d@{{vV!uPq&3a1txE&N>UTRgHjulRkbcj@rboYL3j-sQvN z6XOr6f;v#07$2B83MRNNK~Nt|znOkB@v0_Jjgi-Sp{yOE-K2e~_e%8BuTHnuhp|g~ z&*a(37t)s|-!$71;{xMO<0o@ZbI;_uAT>pDd)l|=N_|vwaWv}Rc)BKdltev$apZ)}z%~>J92`>OF;%5cLuGGr_ZkTMO4|A$?VS4ZRO- zL0`XA&<7bC=ljJ!h<}z8)K?0hYR8I7erSHf{Gh@V^)2>*oc4y9S8S#nZT+J`2uZy%JL+mT4!NOQAN|FmQO^jTQ%SR?gP>UFsw zDso$TNb3D^v0P5-ACjY~7W(>Oa^+<2Q!&p;Z z9rBD%PGnxtA1QUF+!rBbs7g?L}=dQal*Z z-fLf@rk@E=8=aR>$W}9_E=I$CguHVWoGt{6+1doPm_9Ex-D%O zZE+)y^_0|pcSGFYakM|_{nKO8r=_PL@)*{Bb5h$V#29AmBp=yKhWz$C@o)3{#DC52 zo8LWuaQ=w=1T|c^qHu+L9L=11v~X78EcF-dGpfm7pTAX&=jW+uwWKbWzgb;X?W3-r zzb$_cTJksL=jHFs-;kdRmQC^}<)`GQ=P$^gnm;3dPW~cw%lwt?`_y3j_MO_dZy%mq zAfHOxT$*L_Px%Z!U&rRDzvOdy4U;=|P7h?Yr6aXn$}kqe`}?AHIR9!iw>+aGmzsxB zX*sRPGg*A%#>BkDy@^K?PbXeVyq=YAuH?edQz^6iAe zg*@_oRR2$vr5^hBrIkx7>pLgLB#ulRSNgQ{eCeCgFQs=Ap@f*w5}8Cfv3z2+L@z>l z_wqh4jV>Qv-k?0bJQ3u{<>}=M%9ocn1$kDvv%G!z#`4^@ZQ6Ef+q`^t`Qh?{@(XSE zl^2)aOPrcGqr4iDIJfPnwxf(u#v!G9>)?LydEDmr6szgKw7O@t_Y7cFVoOd=PW5Z2 zeeOR=YEXIY_K$c{LsQ$Qlj(f>pI)R6^;?c+_4%j&KGF-*7nVbI+J9_?^cCp~|5@@c z1(RO%KkeVu9fvkf`lkPBpK5QBtL^*1-%(4yQ~r#R{-ph&f0FdqUVD9Rzkie+b7THd zhX12WkL&)QUH&nD-;vn6rN85S7}Ul;`Hr;O{zuOR;5?+I&%)ND8~-F(x)ITjk?<2P z7KC36KLaduS=_!)$iK-y$cyFY8_r)(l*lI@Y~Y9;rEoBG(g&2iAy_5Bc(yWknkH|?UV+C40dT_i|xXn zGo&$0rjlI;cSLeN(imxf=|Jhg@FxUm|L`YRM-A0eUBzQh8e#c>fA}Y9Z1|_}65r{2 z=`gpCcZ@V1eK8krmkyJTm5!qMsRwBhEhLIYNMofF?3(ZrmN%fE&@S_%**yLErTr%S zYeb4jIA;>kkUF(eJC;aQ9}EBCj3;)>$Ffpi8UMdrA4%e027~~66J){c zbi)2qnJdAA~9Ts=#cR@+! zP$qs&{80fV+Y~XRQzJ$Ywd_H$U`yAqSKE$#P0{Yw?vAYFq9ejnj+7&XNI{wk^A2fR zWLaq%f+hM%(<3XOog$r1h-9VHBL%f5m%Zu}`vv$h_Fe2p?Y>$_=lsK*FP$IjlyJU{ zy0Q~(jDCup#QhZ>(oaLA3#ALy)wFqj7_*J5af+-R8Gxk_6Jn7;hJZv?&HRCNOSf^P zS7f_LZ$T|_f3FA8>gVh7n{nWYIBie)7<2cvv)gM6Os&qqS-^l(jA+!W3u3}A^ z?cxTP#_hv2S4vK+k!)sa0TBVj^l2~u3NYWsq=-f4e`@bcX~wo7dH*nrr8 z)V8s|Vt=XktM|l}co-*7f3F

ngp%RM_Lo+r~Rk8fO=eo^~3vttUsnd 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 { /** @@ -45,16 +44,14 @@ public abstract class CodePointMap implements Iterable { * Most users should use NORMAL. * * @see #getRange - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public enum RangeOption { /** * getRange() enumerates all same-value ranges as stored in the map. * Most users should use this option. * - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ NORMAL, /** @@ -71,8 +68,7 @@ public abstract class CodePointMap implements Iterable { * or for special error behavior for unpaired surrogates, * but those values are not to be associated with the lead surrogate code *points*. * - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ FIXED_LEAD_SURROGATES, /** @@ -89,8 +85,7 @@ public abstract class CodePointMap implements Iterable { * or for special error behavior for unpaired surrogates, * but those values are not to be associated with the lead surrogate code *points*. * - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ FIXED_ALL_SURROGATES } @@ -106,8 +101,7 @@ public abstract class CodePointMap implements Iterable { * * @see #getRange * @see #iterator - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public interface ValueFilter { /** @@ -115,8 +109,7 @@ public abstract class CodePointMap implements Iterable { * * @param value map value * @return modified value - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public int apply(int value); } @@ -129,8 +122,7 @@ public abstract class CodePointMap implements Iterable { * * @see #getRange * @see #iterator - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public static final class Range { private int start; @@ -140,8 +132,7 @@ public abstract class CodePointMap implements Iterable { /** * Constructor. Sets start and end to -1 and value to 0. * - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public Range() { start = end = -1; @@ -150,20 +141,17 @@ public abstract class CodePointMap implements Iterable { /** * @return the start code point - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public int getStart() { return start; } /** * @return the (inclusive) end code point - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public int getEnd() { return end; } /** * @return the range value - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public int getValue() { return value; } /** @@ -173,8 +161,7 @@ public abstract class CodePointMap implements Iterable { * @param start new start code point * @param end new end code point * @param value new value - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public void set(int start, int end, int value) { this.start = start; @@ -223,8 +210,7 @@ public abstract class CodePointMap implements Iterable { * *

This class is not intended for public subclassing. * - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public class StringIterator { /** @@ -269,8 +255,7 @@ public abstract class CodePointMap implements Iterable { * * @param s string to iterate over * @param sIndex string index where the iteration will start - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public void reset(CharSequence s, int sIndex) { this.s = s; @@ -286,8 +271,7 @@ public abstract class CodePointMap implements Iterable { * * @return true if the string index was not yet at the end of the string; * otherwise the iterator did not advance - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public boolean next() { if (sIndex >= s.length()) { @@ -306,8 +290,7 @@ public abstract class CodePointMap implements Iterable { * * @return true if the string index was not yet at the start of the string; * otherwise the iterator did not advance - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public boolean previous() { if (sIndex <= 0) { @@ -320,22 +303,19 @@ public abstract class CodePointMap implements Iterable { } /** * @return the string index - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public final int getIndex() { return sIndex; } /** * @return the code point - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public final int getCodePoint() { return c; } /** * @return the map value, * or an implementation-defined error value if * the code point is an unpaired surrogate - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public final int getValue() { return value; } } @@ -343,8 +323,7 @@ public abstract class CodePointMap implements Iterable { /** * Protected no-args constructor. * - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ protected CodePointMap() { } @@ -357,8 +336,7 @@ public abstract class CodePointMap implements Iterable { * @return the map value, * or an implementation-defined error value if * the code point is not in the range 0..U+10FFFF - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public abstract int get(int c); @@ -395,8 +373,7 @@ public abstract class CodePointMap implements Iterable { * or null if the values from the map are to be used unmodified * @param range the range object that will be set to the code point range and value * @return true if start is 0..U+10FFFF; otherwise no new range is fetched - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public abstract boolean getRange(int start, ValueFilter filter, Range range); @@ -419,8 +396,7 @@ public abstract class CodePointMap implements Iterable { * or null if the values from the map are to be used unmodified * @param range the range object that will be set to the code point range and value * @return true if start is 0..U+10FFFF; otherwise no new range is fetched - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public boolean getRange(int start, RangeOption option, int surrogateValue, ValueFilter filter, Range range) { @@ -477,8 +453,7 @@ public abstract class CodePointMap implements Iterable { *

The iterator always returns the same Range object. * * @return a Range iterator - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ @Override public Iterator iterator() { @@ -492,8 +467,7 @@ public abstract class CodePointMap implements Iterable { * @param s string to iterate over * @param sIndex string index where the iteration will start * @return the iterator - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public StringIterator stringIterator(CharSequence s, int sIndex) { return new StringIterator(s, sIndex); diff --git a/src/java.base/share/classes/jdk/internal/icu/util/CodePointTrie.java b/src/java.base/share/classes/jdk/internal/icu/util/CodePointTrie.java index f1277e78795..74dae2089a0 100644 --- a/src/java.base/share/classes/jdk/internal/icu/util/CodePointTrie.java +++ b/src/java.base/share/classes/jdk/internal/icu/util/CodePointTrie.java @@ -48,8 +48,7 @@ import static jdk.internal.icu.impl.NormalizerImpl.UTF16Plus; *

This class is not intended for public subclassing. * * @see MutableCodePointTrie - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ @SuppressWarnings("deprecation") public abstract class CodePointTrie extends CodePointMap { @@ -63,8 +62,7 @@ public abstract class CodePointTrie extends CodePointMap { * @see MutableCodePointTrie#buildImmutable(CodePointTrie.Type, CodePointTrie.ValueWidth) * @see #fromBinary * @see #getType - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public enum Type { /** @@ -72,16 +70,14 @@ public abstract class CodePointTrie extends CodePointMap { * The {@link Fast} subclasses have additional functions for lookup for BMP and supplementary code points. * * @see Fast - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ FAST, /** * Small/slower BMP data structure. * * @see Small - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ SMALL } @@ -92,31 +88,27 @@ public abstract class CodePointTrie extends CodePointMap { *

Use null for {@link #fromBinary} to accept any data value width; * {@link #getValueWidth} will return the actual data value width. * - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public enum ValueWidth { /** * The trie stores 16 bits per data value. * It returns them as unsigned values 0..0xffff=65535. * - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ BITS_16, /** * The trie stores 32 bits per data value. * - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ BITS_32, /** * The trie stores 8 bits per data value. * It returns them as unsigned values 0..0xff=255. * - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ BITS_8 } @@ -162,8 +154,7 @@ public abstract class CodePointTrie extends CodePointMap { * @see MutableCodePointTrie#MutableCodePointTrie(int, int) * @see MutableCodePointTrie#buildImmutable(CodePointTrie.Type, CodePointTrie.ValueWidth) * @see #toBinary(OutputStream) - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public static CodePointTrie fromBinary(Type type, ValueWidth valueWidth, ByteBuffer bytes) { ByteOrder outerByteOrder = bytes.order(); @@ -306,23 +297,20 @@ public abstract class CodePointTrie extends CodePointMap { * Returns the trie type. * * @return the trie type - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public abstract Type getType(); /** * Returns the number of bits in a trie data value. * * @return the number of bits in a trie data value - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public final ValueWidth getValueWidth() { return data.getValueWidth(); } /** * {@inheritDoc} - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ @Override public int get(int c) { @@ -334,8 +322,7 @@ public abstract class CodePointTrie extends CodePointMap { * * @param c the input code point; must be U+0000..U+007F * @return The ASCII code point's trie value. - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public final int asciiGet(int c) { return ascii[c]; @@ -357,8 +344,7 @@ public abstract class CodePointTrie extends CodePointMap { /** * {@inheritDoc} - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ @Override public final boolean getRange(int start, ValueFilter filter, Range range) { @@ -515,8 +501,7 @@ public abstract class CodePointTrie extends CodePointMap { * * @param os the output stream * @return the number of bytes written - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public final int toBinary(OutputStream os) { try { @@ -781,8 +766,7 @@ public abstract class CodePointTrie extends CodePointMap { /** * A CodePointTrie with {@link Type#FAST}. * - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public static abstract class Fast extends CodePointTrie { private Fast(char[] index, Data data, int highStart, @@ -800,8 +784,7 @@ public abstract class CodePointTrie extends CodePointMap { * use null to accept any data value width * @param bytes a buffer containing the binary data of a CodePointTrie * @return the trie - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public static Fast fromBinary(ValueWidth valueWidth, ByteBuffer bytes) { return (Fast) CodePointTrie.fromBinary(Type.FAST, valueWidth, bytes); @@ -809,8 +792,7 @@ public abstract class CodePointTrie extends CodePointMap { /** * @return {@link Type#FAST} - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ @Override public final Type getType() { return Type.FAST; } @@ -822,8 +804,7 @@ public abstract class CodePointTrie extends CodePointMap { * * @param c the input code point, must be U+0000..U+FFFF * @return The BMP code point's trie value. - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public abstract int bmpGet(int c); @@ -833,8 +814,7 @@ public abstract class CodePointTrie extends CodePointMap { * * @param c the input code point, must be U+10000..U+10FFFF * @return The supplementary code point's trie value. - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public abstract int suppGet(int c); @@ -857,8 +837,7 @@ public abstract class CodePointTrie extends CodePointMap { /** * {@inheritDoc} - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ @Override public final StringIterator stringIterator(CharSequence s, int sIndex) { @@ -925,8 +904,7 @@ public abstract class CodePointTrie extends CodePointMap { /** * A CodePointTrie with {@link Type#SMALL}. * - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public static abstract class Small extends CodePointTrie { private Small(char[] index, Data data, int highStart, @@ -944,8 +922,7 @@ public abstract class CodePointTrie extends CodePointMap { * use null to accept any data value width * @param bytes a buffer containing the binary data of a CodePointTrie * @return the trie - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public static Small fromBinary(ValueWidth valueWidth, ByteBuffer bytes) { return (Small) CodePointTrie.fromBinary(Type.SMALL, valueWidth, bytes); @@ -953,8 +930,7 @@ public abstract class CodePointTrie extends CodePointMap { /** * @return {@link Type#SMALL} - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ @Override public final Type getType() { return Type.SMALL; } @@ -978,8 +954,7 @@ public abstract class CodePointTrie extends CodePointMap { /** * {@inheritDoc} - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ @Override public final StringIterator stringIterator(CharSequence s, int sIndex) { @@ -1046,8 +1021,7 @@ public abstract class CodePointTrie extends CodePointMap { /** * A CodePointTrie with {@link Type#FAST} and {@link ValueWidth#BITS_16}. * - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public static final class Fast16 extends Fast { private final char[] dataArray; @@ -1065,8 +1039,7 @@ public abstract class CodePointTrie extends CodePointMap { * * @param bytes a buffer containing the binary data of a CodePointTrie * @return the trie - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public static Fast16 fromBinary(ByteBuffer bytes) { return (Fast16) CodePointTrie.fromBinary(Type.FAST, ValueWidth.BITS_16, bytes); @@ -1074,8 +1047,7 @@ public abstract class CodePointTrie extends CodePointMap { /** * {@inheritDoc} - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ @Override public final int get(int c) { @@ -1084,8 +1056,7 @@ public abstract class CodePointTrie extends CodePointMap { /** * {@inheritDoc} - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ @Override public final int bmpGet(int c) { @@ -1095,8 +1066,7 @@ public abstract class CodePointTrie extends CodePointMap { /** * {@inheritDoc} - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ @Override public final int suppGet(int c) { @@ -1108,8 +1078,7 @@ public abstract class CodePointTrie extends CodePointMap { /** * A CodePointTrie with {@link Type#FAST} and {@link ValueWidth#BITS_32}. * - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public static final class Fast32 extends Fast { private final int[] dataArray; @@ -1127,8 +1096,7 @@ public abstract class CodePointTrie extends CodePointMap { * * @param bytes a buffer containing the binary data of a CodePointTrie * @return the trie - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public static Fast32 fromBinary(ByteBuffer bytes) { return (Fast32) CodePointTrie.fromBinary(Type.FAST, ValueWidth.BITS_32, bytes); @@ -1136,8 +1104,7 @@ public abstract class CodePointTrie extends CodePointMap { /** * {@inheritDoc} - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ @Override public final int get(int c) { @@ -1146,8 +1113,7 @@ public abstract class CodePointTrie extends CodePointMap { /** * {@inheritDoc} - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ @Override public final int bmpGet(int c) { @@ -1157,8 +1123,7 @@ public abstract class CodePointTrie extends CodePointMap { /** * {@inheritDoc} - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ @Override public final int suppGet(int c) { @@ -1170,8 +1135,7 @@ public abstract class CodePointTrie extends CodePointMap { /** * A CodePointTrie with {@link Type#FAST} and {@link ValueWidth#BITS_8}. * - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public static final class Fast8 extends Fast { private final byte[] dataArray; @@ -1189,8 +1153,7 @@ public abstract class CodePointTrie extends CodePointMap { * * @param bytes a buffer containing the binary data of a CodePointTrie * @return the trie - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public static Fast8 fromBinary(ByteBuffer bytes) { return (Fast8) CodePointTrie.fromBinary(Type.FAST, ValueWidth.BITS_8, bytes); @@ -1198,8 +1161,7 @@ public abstract class CodePointTrie extends CodePointMap { /** * {@inheritDoc} - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ @Override public final int get(int c) { @@ -1208,8 +1170,7 @@ public abstract class CodePointTrie extends CodePointMap { /** * {@inheritDoc} - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ @Override public final int bmpGet(int c) { @@ -1219,8 +1180,7 @@ public abstract class CodePointTrie extends CodePointMap { /** * {@inheritDoc} - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ @Override public final int suppGet(int c) { @@ -1232,8 +1192,7 @@ public abstract class CodePointTrie extends CodePointMap { /** * A CodePointTrie with {@link Type#SMALL} and {@link ValueWidth#BITS_16}. * - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public static final class Small16 extends Small { Small16(char[] index, char[] data16, int highStart, @@ -1248,8 +1207,7 @@ public abstract class CodePointTrie extends CodePointMap { * * @param bytes a buffer containing the binary data of a CodePointTrie * @return the trie - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public static Small16 fromBinary(ByteBuffer bytes) { return (Small16) CodePointTrie.fromBinary(Type.SMALL, ValueWidth.BITS_16, bytes); @@ -1259,8 +1217,7 @@ public abstract class CodePointTrie extends CodePointMap { /** * A CodePointTrie with {@link Type#SMALL} and {@link ValueWidth#BITS_32}. * - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public static final class Small32 extends Small { Small32(char[] index, int[] data32, int highStart, @@ -1275,8 +1232,7 @@ public abstract class CodePointTrie extends CodePointMap { * * @param bytes a buffer containing the binary data of a CodePointTrie * @return the trie - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public static Small32 fromBinary(ByteBuffer bytes) { return (Small32) CodePointTrie.fromBinary(Type.SMALL, ValueWidth.BITS_32, bytes); @@ -1286,8 +1242,7 @@ public abstract class CodePointTrie extends CodePointMap { /** * A CodePointTrie with {@link Type#SMALL} and {@link ValueWidth#BITS_8}. * - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public static final class Small8 extends Small { Small8(char[] index, byte[] data8, int highStart, @@ -1302,8 +1257,7 @@ public abstract class CodePointTrie extends CodePointMap { * * @param bytes a buffer containing the binary data of a CodePointTrie * @return the trie - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. + * @stable ICU 63 */ public static Small8 fromBinary(ByteBuffer bytes) { return (Small8) CodePointTrie.fromBinary(Type.SMALL, ValueWidth.BITS_8, bytes); diff --git a/src/java.base/share/classes/jdk/internal/icu/util/VersionInfo.java b/src/java.base/share/classes/jdk/internal/icu/util/VersionInfo.java index 8b85c70d868..d79ee84731b 100644 --- a/src/java.base/share/classes/jdk/internal/icu/util/VersionInfo.java +++ b/src/java.base/share/classes/jdk/internal/icu/util/VersionInfo.java @@ -54,7 +54,7 @@ public final class VersionInfo * @deprecated This API is ICU internal only. */ @Deprecated - public static final String ICU_DATA_VERSION_PATH = "64b"; + public static final String ICU_DATA_VERSION_PATH = "67b"; // public methods ------------------------------------------------------ diff --git a/src/java.base/share/legal/icu.md b/src/java.base/share/legal/icu.md index a6b09cbcb79..ab850bf143e 100644 --- a/src/java.base/share/legal/icu.md +++ b/src/java.base/share/legal/icu.md @@ -1,11 +1,11 @@ -## International Components for Unicode (ICU4J) v64.2 +## International Components for Unicode (ICU4J) v67.1 ### ICU4J License ``` COPYRIGHT AND PERMISSION NOTICE (ICU 58 and later) -Copyright © 1991-2019 Unicode, Inc. All rights reserved. +Copyright © 1991-2020 Unicode, Inc. All rights reserved. Distributed under the Terms of Use in https://www.unicode.org/copyright.html. Permission is hereby granted, free of charge, to any person obtaining @@ -80,314 +80,61 @@ of the copyright holder. All trademarks and registered trademarks mentioned herein are the property of their respective owners. -2. Chinese/Japanese Word Break Dictionary Data (cjdict.txt) - # The Google Chrome software developed by Google is licensed under - # the BSD license. Other software included in this distribution is - # provided under other licenses, as set forth below. - # - # The BSD License - # http://opensource.org/licenses/bsd-license.php - # Copyright (C) 2006-2008, Google Inc. - # - # All rights reserved. - # - # Redistribution and use in source and binary forms, with or without - # modification, are permitted provided that the following conditions are met: - # - # Redistributions of source code must retain the above copyright notice, - # this list of conditions and the following disclaimer. - # Redistributions in binary form must reproduce the above - # copyright notice, this list of conditions and the following - # disclaimer in the documentation and/or other materials provided with - # the distribution. - # Neither the name of Google Inc. nor the names of its - # contributors may be used to endorse or promote products derived from - # this software without specific prior written permission. - # - # - # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - # CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - # - # - # The word list in cjdict.txt are generated by combining three word lists - # listed below with further processing for compound word breaking. The - # frequency is generated with an iterative training against Google web - # corpora. - # - # * Libtabe (Chinese) - # - https://sourceforge.net/project/?group_id=1519 - # - Its license terms and conditions are shown below. - # - # * IPADIC (Japanese) - # - http://chasen.aist-nara.ac.jp/chasen/distribution.html - # - Its license terms and conditions are shown below. - # - # ---------COPYING.libtabe ---- BEGIN-------------------- - # - # /* - # * Copyright (c) 1999 TaBE Project. - # * Copyright (c) 1999 Pai-Hsiang Hsiao. - # * All rights reserved. - # * - # * Redistribution and use in source and binary forms, with or without - # * modification, are permitted provided that the following conditions - # * are met: - # * - # * . Redistributions of source code must retain the above copyright - # * notice, this list of conditions and the following disclaimer. - # * . Redistributions in binary form must reproduce the above copyright - # * notice, this list of conditions and the following disclaimer in - # * the documentation and/or other materials provided with the - # * distribution. - # * . Neither the name of the TaBE Project nor the names of its - # * contributors may be used to endorse or promote products derived - # * from this software without specific prior written permission. - # * - # * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - # * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - # * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - # * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - # * REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - # * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - # * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - # * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - # * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - # * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - # * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - # * OF THE POSSIBILITY OF SUCH DAMAGE. - # */ - # - # /* - # * Copyright (c) 1999 Computer Systems and Communication Lab, - # * Institute of Information Science, Academia - # * Sinica. All rights reserved. - # * - # * Redistribution and use in source and binary forms, with or without - # * modification, are permitted provided that the following conditions - # * are met: - # * - # * . Redistributions of source code must retain the above copyright - # * notice, this list of conditions and the following disclaimer. - # * . Redistributions in binary form must reproduce the above copyright - # * notice, this list of conditions and the following disclaimer in - # * the documentation and/or other materials provided with the - # * distribution. - # * . Neither the name of the Computer Systems and Communication Lab - # * nor the names of its contributors may be used to endorse or - # * promote products derived from this software without specific - # * prior written permission. - # * - # * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - # * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - # * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - # * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - # * REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - # * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - # * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - # * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - # * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - # * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - # * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - # * OF THE POSSIBILITY OF SUCH DAMAGE. - # */ - # - # Copyright 1996 Chih-Hao Tsai @ Beckman Institute, - # University of Illinois - # c-tsai4@uiuc.edu http://casper.beckman.uiuc.edu/~c-tsai4 - # - # ---------------COPYING.libtabe-----END-------------------------------- - # - # - # ---------------COPYING.ipadic-----BEGIN------------------------------- - # - # Copyright 2000, 2001, 2002, 2003 Nara Institute of Science - # and Technology. All Rights Reserved. - # - # Use, reproduction, and distribution of this software is permitted. - # Any copy of this software, whether in its original form or modified, - # must include both the above copyright notice and the following - # paragraphs. - # - # Nara Institute of Science and Technology (NAIST), - # the copyright holders, disclaims all warranties with regard to this - # software, including all implied warranties of merchantability and - # fitness, in no event shall NAIST be liable for - # any special, indirect or consequential damages or any damages - # whatsoever resulting from loss of use, data or profits, whether in an - # action of contract, negligence or other tortuous action, arising out - # of or in connection with the use or performance of this software. - # - # A large portion of the dictionary entries - # originate from ICOT Free Software. The following conditions for ICOT - # Free Software applies to the current dictionary as well. - # - # Each User may also freely distribute the Program, whether in its - # original form or modified, to any third party or parties, PROVIDED - # that the provisions of Section 3 ("NO WARRANTY") will ALWAYS appear - # on, or be attached to, the Program, which is distributed substantially - # in the same form as set out herein and that such intended - # distribution, if actually made, will neither violate or otherwise - # contravene any of the laws and regulations of the countries having - # jurisdiction over the User or the intended distribution itself. - # - # NO WARRANTY - # - # The program was produced on an experimental basis in the course of the - # research and development conducted during the project and is provided - # to users as so produced on an experimental basis. Accordingly, the - # program is provided without any warranty whatsoever, whether express, - # implied, statutory or otherwise. The term "warranty" used herein - # includes, but is not limited to, any warranty of the quality, - # performance, merchantability and fitness for a particular purpose of - # the program and the nonexistence of any infringement or violation of - # any right of any third party. - # - # Each user of the program will agree and understand, and be deemed to - # have agreed and understood, that there is no warranty whatsoever for - # the program and, accordingly, the entire risk arising from or - # otherwise connected with the program is assumed by the user. - # - # Therefore, neither ICOT, the copyright holder, or any other - # organization that participated in or was otherwise related to the - # development of the program and their respective officials, directors, - # officers and other employees shall be held liable for any and all - # damages, including, without limitation, general, special, incidental - # and consequential damages, arising out of or otherwise in connection - # with the use or inability to use the program or any product, material - # or result produced or otherwise obtained by using the program, - # regardless of whether they have been advised of, or otherwise had - # knowledge of, the possibility of such damages at any time during the - # project or thereafter. Each user will be deemed to have agreed to the - # foregoing by his or her commencement of use of the program. The term - # "use" as used herein includes, but is not limited to, the use, - # modification, copying and distribution of the program and the - # production of secondary products from the program. - # - # In the case where the program, whether in its original form or - # modified, was distributed or delivered to or received by a user from - # any person, organization or entity other than ICOT, unless it makes or - # grants independently of ICOT any specific warranty to the user in - # writing, such person, organization or entity, will also be exempted - # from and not be held liable to the user for any such damages as noted - # above as far as the program is concerned. - # - # ---------------COPYING.ipadic-----END---------------------------------- +—————————————————————————————————————————————————————————————————————— -3. Lao Word Break Dictionary Data (laodict.txt) - # Copyright (c) 2013 International Business Machines Corporation - # and others. All Rights Reserved. - # - # Project: http://code.google.com/p/lao-dictionary/ - # Dictionary: http://lao-dictionary.googlecode.com/git/Lao-Dictionary.txt - # License: http://lao-dictionary.googlecode.com/git/Lao-Dictionary-LICENSE.txt - # (copied below) - # - # This file is derived from the above dictionary, with slight - # modifications. - # ---------------------------------------------------------------------- - # Copyright (C) 2013 Brian Eugene Wilson, Robert Martin Campbell. - # All rights reserved. - # - # Redistribution and use in source and binary forms, with or without - # modification, - # are permitted provided that the following conditions are met: - # - # - # Redistributions of source code must retain the above copyright notice, this - # list of conditions and the following disclaimer. Redistributions in - # binary form must reproduce the above copyright notice, this list of - # conditions and the following disclaimer in the documentation and/or - # other materials provided with the distribution. - # - # - # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - # OF THE POSSIBILITY OF SUCH DAMAGE. - # -------------------------------------------------------------------------- +From: https://www.unicode.org/copyright.html: -4. Burmese Word Break Dictionary Data (burmesedict.txt) + Unicode® Copyright and Terms of Use - # Copyright (c) 2014 International Business Machines Corporation - # and others. All Rights Reserved. - # - # This list is part of a project hosted at: - # github.com/kanyawtech/myanmar-karen-word-lists - # - # -------------------------------------------------------------------------- - # Copyright (c) 2013, LeRoy Benjamin Sharon - # All rights reserved. - # - # Redistribution and use in source and binary forms, with or without - # modification, are permitted provided that the following conditions - # are met: Redistributions of source code must retain the above - # copyright notice, this list of conditions and the following - # disclaimer. Redistributions in binary form must reproduce the - # above copyright notice, this list of conditions and the following - # disclaimer in the documentation and/or other materials provided - # with the distribution. - # - # Neither the name Myanmar Karen Word Lists, nor the names of its - # contributors may be used to endorse or promote products derived - # from this software without specific prior written permission. - # - # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - # CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS - # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - # TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF - # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - # SUCH DAMAGE. - # -------------------------------------------------------------------------- + For the general privacy policy governing access to this site, see the Unicode Privacy Policy. -5. Time Zone Database + Unicode Copyright + Copyright © 1991-2020 Unicode, Inc. All rights reserved. + Definitions - ICU uses the public domain data and code derived from Time Zone -Database for its time zone support. The ownership of the TZ database -is explained in BCP 175: Procedure for Maintaining the Time Zone -Database section 7. + Unicode Data Files ("DATA FILES") include all data files under the directories: + https://www.unicode.org/Public/ + https://www.unicode.org/reports/ + https://www.unicode.org/ivd/data/ - # 7. Database Ownership - # - # The TZ database itself is not an IETF Contribution or an IETF - # document. Rather it is a pre-existing and regularly updated work - # that is in the public domain, and is intended to remain in the - # public domain. Therefore, BCPs 78 [RFC5378] and 79 [RFC3979] do - # not apply to the TZ Database or contributions that individuals make - # to it. Should any claims be made and substantiated against the TZ - # Database, the organization that is providing the IANA - # Considerations defined in this RFC, under the memorandum of - # understanding with the IETF, currently ICANN, may act in accordance - # with all competent court orders. No ownership claims will be made - # by ICANN or the IETF Trust on the database or the code. Any person - # making a contribution to the database or code waives all rights to - # future claims in that contribution or in the TZ Database. + Unicode Data Files do not include PDF online code charts under the directory: + https://www.unicode.org/Public/ + + Unicode Software ("SOFTWARE") includes any source code published in the Unicode Standard + or any source code or compiled code under the directories: + https://www.unicode.org/Public/PROGRAMS/ + https://www.unicode.org/Public/cldr/ + http://site.icu-project.org/download/ + + Terms of Use + Certain documents and files on this website contain a legend indicating that "Modification is permitted." Any person is hereby authorized, without fee, to modify such documents and files to create derivative works conforming to the Unicode® Standard, subject to Terms and Conditions herein. + Any person is hereby authorized, without fee, to view, use, reproduce, and distribute all documents and files, subject to the Terms and Conditions herein. + Further specifications of rights and restrictions pertaining to the use of the Unicode DATA FILES and SOFTWARE can be found in the Unicode Data Files and Software License. + Each version of the Unicode Standard has further specifications of rights and restrictions of use. For the book editions (Unicode 5.0 and earlier), these are found on the back of the title page. + The Unicode PDF online code charts carry specific restrictions. Those restrictions are incorporated as the first page of each PDF code chart. + All other files, including online documentation of the core specification for Unicode 6.0 and later, are covered under these general Terms of Use. + No license is granted to "mirror" the Unicode website where a fee is charged for access to the "mirror" site. + Modification is not permitted with respect to this document. All copies of this document must be verbatim. + Restricted Rights Legend + Any technical data or software which is licensed to the United States of America, its agencies and/or instrumentalities under this Agreement is commercial technical data or commercial computer software developed exclusively at private expense as defined in FAR 2.101, or DFARS 252.227-7014 (June 1995), as applicable. For technical data, use, duplication, or disclosure by the Government is subject to restrictions as set forth in DFARS 202.227-7015 Technical Data, Commercial and Items (Nov 1995) and this Agreement. For Software, in accordance with FAR 12-212 or DFARS 227-7202, as applicable, use, duplication or disclosure by the Government is subject to the restrictions set forth in this Agreement. + Warranties and Disclaimers + This publication and/or website may include technical or typographical errors or other inaccuracies. Changes are periodically added to the information herein; these changes will be incorporated in new editions of the publication and/or website. Unicode, Inc. may make improvements and/or changes in the product(s) and/or program(s) described in this publication and/or website at any time. + If this file has been purchased on magnetic or optical media from Unicode, Inc. the sole and exclusive remedy for any claim will be exchange of the defective media within ninety (90) days of original purchase. + EXCEPT AS PROVIDED IN SECTION E.2, THIS PUBLICATION AND/OR SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND EITHER EXPRESS, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. UNICODE, INC. AND ITS LICENSORS ASSUME NO RESPONSIBILITY FOR ERRORS OR OMISSIONS IN THIS PUBLICATION AND/OR SOFTWARE OR OTHER DOCUMENTS WHICH ARE REFERENCED BY OR LINKED TO THIS PUBLICATION OR THE UNICODE WEBSITE. + Waiver of Damages + In no event shall Unicode, Inc. or its licensors be liable for any special, incidental, indirect or consequential damages of any kind, or any damages whatsoever, whether or not Unicode, Inc. was advised of the possibility of the damage, including, without limitation, those resulting from the following: loss of use, data or profits, in connection with the use, modification or distribution of this information or its derivatives. + Trademarks & Logos + The Unicode Word Mark and the Unicode Logo are trademarks of Unicode, Inc. “The Unicode Consortium” and “Unicode, Inc.” are trade names of Unicode, Inc. Use of the information and materials found on this website indicates your acknowledgement of Unicode, Inc.’s exclusive worldwide rights in the Unicode Word Mark, the Unicode Logo, and the Unicode trade names. + The Unicode Consortium Name and Trademark Usage Policy (“Trademark Policy”) are incorporated herein by reference and you agree to abide by the provisions of the Trademark Policy, which may be changed from time to time in the sole discretion of Unicode, Inc. + All third party trademarks referenced herein are the property of their respective owners. + Miscellaneous + Jurisdiction and Venue. This website is operated from a location in the State of California, United States of America. Unicode, Inc. makes no representation that the materials are appropriate for use in other locations. If you access this website from other locations, you are responsible for compliance with local laws. This Agreement, all use of this website and any claims and damages resulting from use of this website are governed solely by the laws of the State of California without regard to any principles which would apply the laws of a different jurisdiction. The user agrees that any disputes regarding this website shall be resolved solely in the courts located in Santa Clara County, California. The user agrees said courts have personal jurisdiction and agree to waive any right to transfer the dispute to any other forum. + Modification by Unicode, Inc. Unicode, Inc. shall have the right to modify this Agreement at any time by posting it to this website. The user may not assign any part of this Agreement without Unicode, Inc.’s prior written consent. + Taxes. The user agrees to pay any taxes arising from access to this website or use of the information herein, except for those based on Unicode’s net income. + Severability. If any provision of this Agreement is declared invalid or unenforceable, the remaining provisions of this Agreement shall remain in effect. + Entire Agreement. This Agreement constitutes the entire agreement between the parties. ``` diff --git a/src/java.base/share/legal/unicode.md b/src/java.base/share/legal/unicode.md index a8cf4982b1d..cff0c82a873 100644 --- a/src/java.base/share/legal/unicode.md +++ b/src/java.base/share/legal/unicode.md @@ -1,4 +1,4 @@ -## The Unicode Standard, Unicode Character Database, Version 12.1.0 +## The Unicode Standard, Unicode Character Database, Version 13.0.0 ### Unicode Character Database ``` @@ -18,7 +18,7 @@ THE DATA FILES OR SOFTWARE. COPYRIGHT AND PERMISSION NOTICE -Copyright © 1991-2019 Unicode, Inc. All rights reserved. +Copyright © 1991-2020 Unicode, Inc. All rights reserved. Distributed under the Terms of Use in https://www.unicode.org/copyright.html. Permission is hereby granted, free of charge, to any person obtaining diff --git a/test/jdk/java/lang/Character/UnicodeBlock/OptimalMapSize.java b/test/jdk/java/lang/Character/UnicodeBlock/OptimalMapSize.java index 1d384b6ba78..8883f0d8263 100644 --- a/test/jdk/java/lang/Character/UnicodeBlock/OptimalMapSize.java +++ b/test/jdk/java/lang/Character/UnicodeBlock/OptimalMapSize.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 @@ -23,7 +23,7 @@ /** * @test - * @bug 8080535 8191410 8215194 8221431 + * @bug 8080535 8191410 8215194 8221431 8239383 * @summary Expected size of Character.UnicodeBlock.map is not optimal * @library /test/lib * @modules java.base/java.lang:open @@ -47,13 +47,14 @@ import jdk.test.lib.util.OptimalCapacity; // // As of Unicode 11, 667 entries are expected. // As of Unicode 12.1, 676 entries are expected. +// As of Unicode 13.0, 684 entries are expected. // // Initialization of the map and this test will have to be adjusted // accordingly then. // // Note that HashMap's implementation aligns the initial capacity to // a power of two size, so it will end up 1024 (and thus succeed) in -// cases, such as 638, 667, and 676. +// cases, such as 638, 667, 676, and 684. public class OptimalMapSize { public static void main(String[] args) throws Throwable { @@ -62,7 +63,7 @@ public class OptimalMapSize { Field f = Character.UnicodeBlock.class.getDeclaredField("NUM_ENTITIES"); f.setAccessible(true); int num_entities = f.getInt(null); - assert num_entities == 676; + assert num_entities == 684; int initialCapacity = (int)(num_entities / 0.75f + 1.0f); OptimalCapacity.ofHashMap(Character.UnicodeBlock.class, diff --git a/test/jdk/java/text/Normalizer/ConformanceTest.java b/test/jdk/java/text/Normalizer/ConformanceTest.java index f84494ff9e7..111510f6a85 100644 --- a/test/jdk/java/text/Normalizer/ConformanceTest.java +++ b/test/jdk/java/text/Normalizer/ConformanceTest.java @@ -22,7 +22,7 @@ */ /* * @test - * @bug 4221795 6565620 6959267 7070436 7198195 8032446 8174270 8221431 + * @bug 4221795 6565620 6959267 7070436 7198195 8032446 8174270 8221431 8239383 * @summary Confirm Normalizer's fundamental behavior * @library /lib/testlibrary/java/lang * @modules java.base/sun.text java.base/jdk.internal.icu.text @@ -126,7 +126,7 @@ public class ConformanceTest { * * This testdata is for sun.text.Normalize(UNICODE_LATEST) */ - static final String DATA_LATEST = "NormalizationTest-Latest.txt"; + static final String DATA_LATEST = "NormalizationTest.txt"; /* * Conformance test datafile in ICU4J 3.2. diff --git a/test/jdk/java/util/regex/GraphemeTest.java b/test/jdk/java/util/regex/GraphemeTest.java index de91b6d6f46..27c1a9d777c 100644 --- a/test/jdk/java/util/regex/GraphemeTest.java +++ b/test/jdk/java/util/regex/GraphemeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 7071819 8221431 + * @bug 7071819 8221431 8239383 * @summary tests Unicode Extended Grapheme support * @library /lib/testlibrary/java/lang * @run main GraphemeTest @@ -278,6 +278,8 @@ public class GraphemeTest { case 0x0D4E: case 0x111C2: case 0x111C3: + case 0x1193F: + case 0x11941: case 0x11A3A: case 0x11A84: case 0x11A85: @@ -295,90 +297,90 @@ public class GraphemeTest { // from generated java.util.regex.EmojiData.java static boolean isExtendedPictographic(int cp) { return - cp == 0x00A9 || - cp == 0x00AE || - cp == 0x203C || - cp == 0x2049 || - cp == 0x2122 || - cp == 0x2139 || - (cp >= 0x2194 && cp <= 0x2199) || - cp == 0x21A9 || - cp == 0x21AA || - cp == 0x231A || - cp == 0x231B || - cp == 0x2328 || - cp == 0x2388 || - cp == 0x23CF || - (cp >= 0x23E9 && cp <= 0x23F3) || - (cp >= 0x23F8 && cp <= 0x23FA) || - cp == 0x24C2 || - cp == 0x25AA || - cp == 0x25AB || - cp == 0x25B6 || - cp == 0x25C0 || - (cp >= 0x25FB && cp <= 0x25FE) || - (cp >= 0x2600 && cp <= 0x2605) || - (cp >= 0x2607 && cp <= 0x2612) || - (cp >= 0x2614 && cp <= 0x2685) || - (cp >= 0x2690 && cp <= 0x2705) || - (cp >= 0x2708 && cp <= 0x2712) || - cp == 0x2714 || - cp == 0x2716 || - cp == 0x271D || - cp == 0x2721 || - cp == 0x2728 || - cp == 0x2733 || - cp == 0x2734 || - cp == 0x2744 || - cp == 0x2747 || - cp == 0x274C || - cp == 0x274E || - (cp >= 0x2753 && cp <= 0x2755) || - cp == 0x2757 || - (cp >= 0x2763 && cp <= 0x2767) || - (cp >= 0x2795 && cp <= 0x2797) || - cp == 0x27A1 || - cp == 0x27B0 || - cp == 0x27BF || - cp == 0x2934 || - cp == 0x2935 || - (cp >= 0x2B05 && cp <= 0x2B07) || - cp == 0x2B1B || - cp == 0x2B1C || - cp == 0x2B50 || - cp == 0x2B55 || - cp == 0x3030 || - cp == 0x303D || - cp == 0x3297 || - cp == 0x3299 || - (cp >= 0x1F000 && cp <= 0x1F0FF) || - (cp >= 0x1F10D && cp <= 0x1F10F) || - cp == 0x1F12F || - (cp >= 0x1F16C && cp <= 0x1F171) || - cp == 0x1F17E || - cp == 0x1F17F || - cp == 0x1F18E || - (cp >= 0x1F191 && cp <= 0x1F19A) || - (cp >= 0x1F1AD && cp <= 0x1F1E5) || - (cp >= 0x1F201 && cp <= 0x1F20F) || - cp == 0x1F21A || - cp == 0x1F22F || - (cp >= 0x1F232 && cp <= 0x1F23A) || - (cp >= 0x1F23C && cp <= 0x1F23F) || - (cp >= 0x1F249 && cp <= 0x1F3FA) || - (cp >= 0x1F400 && cp <= 0x1F53D) || - (cp >= 0x1F546 && cp <= 0x1F64F) || - (cp >= 0x1F680 && cp <= 0x1F6FF) || - (cp >= 0x1F774 && cp <= 0x1F77F) || - (cp >= 0x1F7D5 && cp <= 0x1F7FF) || - (cp >= 0x1F80C && cp <= 0x1F80F) || - (cp >= 0x1F848 && cp <= 0x1F84F) || - (cp >= 0x1F85A && cp <= 0x1F85F) || - (cp >= 0x1F888 && cp <= 0x1F88F) || - (cp >= 0x1F8AE && cp <= 0x1F8FF) || - (cp >= 0x1F90C && cp <= 0x1F93A) || - (cp >= 0x1F93C && cp <= 0x1F945) || - (cp >= 0x1F947 && cp <= 0x1FFFD); - + cp == 0x00A9 || + cp == 0x00AE || + cp == 0x203C || + cp == 0x2049 || + cp == 0x2122 || + cp == 0x2139 || + (cp >= 0x2194 && cp <= 0x2199) || + cp == 0x21A9 || + cp == 0x21AA || + cp == 0x231A || + cp == 0x231B || + cp == 0x2328 || + cp == 0x2388 || + cp == 0x23CF || + (cp >= 0x23E9 && cp <= 0x23F3) || + (cp >= 0x23F8 && cp <= 0x23FA) || + cp == 0x24C2 || + cp == 0x25AA || + cp == 0x25AB || + cp == 0x25B6 || + cp == 0x25C0 || + (cp >= 0x25FB && cp <= 0x25FE) || + (cp >= 0x2600 && cp <= 0x2605) || + (cp >= 0x2607 && cp <= 0x2612) || + (cp >= 0x2614 && cp <= 0x2685) || + (cp >= 0x2690 && cp <= 0x2705) || + (cp >= 0x2708 && cp <= 0x2712) || + cp == 0x2714 || + cp == 0x2716 || + cp == 0x271D || + cp == 0x2721 || + cp == 0x2728 || + cp == 0x2733 || + cp == 0x2734 || + cp == 0x2744 || + cp == 0x2747 || + cp == 0x274C || + cp == 0x274E || + (cp >= 0x2753 && cp <= 0x2755) || + cp == 0x2757 || + (cp >= 0x2763 && cp <= 0x2767) || + (cp >= 0x2795 && cp <= 0x2797) || + cp == 0x27A1 || + cp == 0x27B0 || + cp == 0x27BF || + cp == 0x2934 || + cp == 0x2935 || + (cp >= 0x2B05 && cp <= 0x2B07) || + cp == 0x2B1B || + cp == 0x2B1C || + cp == 0x2B50 || + cp == 0x2B55 || + cp == 0x3030 || + cp == 0x303D || + cp == 0x3297 || + cp == 0x3299 || + (cp >= 0x1F000 && cp <= 0x1F0FF) || + (cp >= 0x1F10D && cp <= 0x1F10F) || + cp == 0x1F12F || + (cp >= 0x1F16C && cp <= 0x1F171) || + cp == 0x1F17E || + cp == 0x1F17F || + cp == 0x1F18E || + (cp >= 0x1F191 && cp <= 0x1F19A) || + (cp >= 0x1F1AD && cp <= 0x1F1E5) || + (cp >= 0x1F201 && cp <= 0x1F20F) || + cp == 0x1F21A || + cp == 0x1F22F || + (cp >= 0x1F232 && cp <= 0x1F23A) || + (cp >= 0x1F23C && cp <= 0x1F23F) || + (cp >= 0x1F249 && cp <= 0x1F3FA) || + (cp >= 0x1F400 && cp <= 0x1F53D) || + (cp >= 0x1F546 && cp <= 0x1F64F) || + (cp >= 0x1F680 && cp <= 0x1F6FF) || + (cp >= 0x1F774 && cp <= 0x1F77F) || + (cp >= 0x1F7D5 && cp <= 0x1F7FF) || + (cp >= 0x1F80C && cp <= 0x1F80F) || + (cp >= 0x1F848 && cp <= 0x1F84F) || + (cp >= 0x1F85A && cp <= 0x1F85F) || + (cp >= 0x1F888 && cp <= 0x1F88F) || + (cp >= 0x1F8AE && cp <= 0x1F8FF) || + (cp >= 0x1F90C && cp <= 0x1F93A) || + (cp >= 0x1F93C && cp <= 0x1F945) || + (cp >= 0x1F947 && cp <= 0x1FAFF) || + (cp >= 0x1FC00 && cp <= 0x1FFFD); } } diff --git a/test/jdk/lib/testlibrary/java/lang/UCDFiles.java b/test/jdk/lib/testlibrary/java/lang/UCDFiles.java index 7310ace296f..10c6243f615 100644 --- a/test/jdk/lib/testlibrary/java/lang/UCDFiles.java +++ b/test/jdk/lib/testlibrary/java/lang/UCDFiles.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 @@ -55,5 +55,5 @@ public class UCDFiles { public static Path UNICODE_DATA = UCD_DIR.resolve("UnicodeData.txt"); public static Path EMOJI_DATA = - UCD_DIR.resolve("emoji-data.txt"); + UCD_DIR.resolve("emoji").resolve("emoji-data.txt"); } From be7771b2b9bf1bb5f8ea205a9ec66958e1cf0f51 Mon Sep 17 00:00:00 2001 From: Jesper Wilhelmsson Date: Thu, 14 May 2020 04:25:42 +0200 Subject: [PATCH 051/143] Added tag jdk-15+23 for changeset f143729ca00e --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index aef3a9b21aa..3631a8c5dad 100644 --- a/.hgtags +++ b/.hgtags @@ -633,3 +633,4 @@ dd5198db2e5b1ebcafe065d987c03ba9fcb50fc3 jdk-15+17 46bca5e5e6fb26efd07245d26fe96a9c3260f51e jdk-15+20 12b55fad80f30d24b1f8fdb3b947ea6465ef9518 jdk-15+21 7223c6d610343fd8323af9d07d501e01fa1a7696 jdk-15+22 +f143729ca00ec14a98ea5c7f73acba88da97746e jdk-15+23 From 17dd7dc38c6035f21a05c20e570bed2700ca20cf Mon Sep 17 00:00:00 2001 From: David Holmes Date: Wed, 13 May 2020 22:29:54 -0400 Subject: [PATCH 052/143] 8240588: _threadObj cannot be used on an exiting JavaThread Reviewed-by: rehn, dcubed, kbarrett --- src/hotspot/share/memory/universe.cpp | 1 + src/hotspot/share/prims/whitebox.cpp | 55 ++++++++ src/hotspot/share/runtime/thread.cpp | 12 +- src/hotspot/share/runtime/thread.hpp | 1 + src/hotspot/share/runtime/threadSMR.cpp | 52 ++++++++ src/hotspot/share/runtime/threadSMR.hpp | 28 ++++- .../runtime/Thread/ThreadObjAccessAtExit.java | 117 ++++++++++++++++++ test/lib/sun/hotspot/WhiteBox.java | 3 + 8 files changed, 266 insertions(+), 3 deletions(-) create mode 100644 test/hotspot/jtreg/runtime/Thread/ThreadObjAccessAtExit.java diff --git a/src/hotspot/share/memory/universe.cpp b/src/hotspot/share/memory/universe.cpp index d4793465d4b..d987a8f462b 100644 --- a/src/hotspot/share/memory/universe.cpp +++ b/src/hotspot/share/memory/universe.cpp @@ -205,6 +205,7 @@ void Universe::oops_do(OopClosure* f) { f->do_oop((oop*)&_vm_exception); f->do_oop((oop*)&_reference_pending_list); debug_only(f->do_oop((oop*)&_fullgc_alot_dummy_array);) + ThreadsSMRSupport::exiting_threads_oops_do(f); } void LatestMethodCache::metaspace_pointers_do(MetaspaceClosure* it) { diff --git a/src/hotspot/share/prims/whitebox.cpp b/src/hotspot/share/prims/whitebox.cpp index b749201c131..fead188888a 100644 --- a/src/hotspot/share/prims/whitebox.cpp +++ b/src/hotspot/share/prims/whitebox.cpp @@ -2222,6 +2222,60 @@ WB_ENTRY(jint, WB_GetKlassMetadataSize(JNIEnv* env, jobject wb, jclass mirror)) return k->size() * wordSize; WB_END +// See test/hotspot/jtreg/runtime/Thread/ThreadObjAccessAtExit.java. +// It explains how the thread's priority field is used for test state coordination. +// +WB_ENTRY(void, WB_CheckThreadObjOfTerminatingThread(JNIEnv* env, jobject wb, jobject target_handle)) + oop target_oop = JNIHandles::resolve_non_null(target_handle); + jlong tid = java_lang_Thread::thread_id(target_oop); + JavaThread* target = java_lang_Thread::thread(target_oop); + + // Grab a ThreadsListHandle to protect the target thread whilst terminating + ThreadsListHandle tlh; + + // Look up the target thread by tid to ensure it is present + JavaThread* t = tlh.list()->find_JavaThread_from_java_tid(tid); + if (t == NULL) { + THROW_MSG(vmSymbols::java_lang_RuntimeException(), "Target thread not found in ThreadsList!"); + } + + tty->print_cr("WB_CheckThreadObjOfTerminatingThread: target thread is protected"); + // Allow target to terminate by boosting priority + java_lang_Thread::set_priority(t->threadObj(), ThreadPriority(NormPriority + 1)); + + // Now wait for the target to terminate + while (!target->is_terminated()) { + ThreadBlockInVM tbivm(thread); // just in case target is involved in a safepoint + os::naked_short_sleep(0); + } + + tty->print_cr("WB_CheckThreadObjOfTerminatingThread: target thread is terminated"); + + // Now release the GC inducing thread - we have to re-resolve the external oop that + // was passed in as GC may have occurred and we don't know if we can trust t->threadObj() now. + oop original = JNIHandles::resolve_non_null(target_handle); + java_lang_Thread::set_priority(original, ThreadPriority(NormPriority + 2)); + + tty->print_cr("WB_CheckThreadObjOfTerminatingThread: GC has been initiated - checking threadObj:"); + + // The Java code should be creating garbage and triggering GC, which would potentially move + // the threadObj oop. If the exiting thread is properly protected then its threadObj should + // remain valid and equal to our initial target_handle. Loop a few times to give GC a chance to + // kick in. + for (int i = 0; i < 5; i++) { + oop original = JNIHandles::resolve_non_null(target_handle); + oop current = t->threadObj(); + if (original != current) { + tty->print_cr("WB_CheckThreadObjOfTerminatingThread: failed comparison on iteration %d", i); + THROW_MSG(vmSymbols::java_lang_RuntimeException(), "Target thread oop has changed!"); + } else { + tty->print_cr("WB_CheckThreadObjOfTerminatingThread: successful comparison on iteration %d", i); + ThreadBlockInVM tbivm(thread); + os::naked_short_sleep(50); + } + } +WB_END + #define CC (char*) static JNINativeMethod methods[] = { @@ -2447,6 +2501,7 @@ static JNINativeMethod methods[] = { {CC"clearInlineCaches0", CC"(Z)V", (void*)&WB_ClearInlineCaches }, {CC"handshakeWalkStack", CC"(Ljava/lang/Thread;Z)I", (void*)&WB_HandshakeWalkStack }, + {CC"checkThreadObjOfTerminatingThread", CC"(Ljava/lang/Thread;)V", (void*)&WB_CheckThreadObjOfTerminatingThread }, {CC"addCompilerDirective", CC"(Ljava/lang/String;)I", (void*)&WB_AddCompilerDirective }, {CC"removeCompilerDirective", CC"(I)V", (void*)&WB_RemoveCompilerDirective }, diff --git a/src/hotspot/share/runtime/thread.cpp b/src/hotspot/share/runtime/thread.cpp index 843aff78b92..67a7a3398fc 100644 --- a/src/hotspot/share/runtime/thread.cpp +++ b/src/hotspot/share/runtime/thread.cpp @@ -2169,6 +2169,14 @@ void JavaThread::exit(bool destroy_vm, ExitType exit_type) { JvmtiExport::cleanup_thread(this); } + // We need to cache the thread name for logging purposes below as once + // we have called on_thread_detach this thread must not access any oops. + char* thread_name = NULL; + if (log_is_enabled(Debug, os, thread, timer)) { + ResourceMark rm(this); + thread_name = os::strdup(get_thread_name()); + } + // We must flush any deferred card marks and other various GC barrier // related buffers (e.g. G1 SATB buffer and G1 dirty card queue buffer) // before removing a thread from the list of active threads. @@ -2187,17 +2195,17 @@ void JavaThread::exit(bool destroy_vm, ExitType exit_type) { if (log_is_enabled(Debug, os, thread, timer)) { _timer_exit_phase4.stop(); - ResourceMark rm(this); log_debug(os, thread, timer)("name='%s'" ", exit-phase1=" JLONG_FORMAT ", exit-phase2=" JLONG_FORMAT ", exit-phase3=" JLONG_FORMAT ", exit-phase4=" JLONG_FORMAT, - get_thread_name(), + thread_name, _timer_exit_phase1.milliseconds(), _timer_exit_phase2.milliseconds(), _timer_exit_phase3.milliseconds(), _timer_exit_phase4.milliseconds()); + os::free(thread_name); } } diff --git a/src/hotspot/share/runtime/thread.hpp b/src/hotspot/share/runtime/thread.hpp index 22ec223c342..9903352110e 100644 --- a/src/hotspot/share/runtime/thread.hpp +++ b/src/hotspot/share/runtime/thread.hpp @@ -1017,6 +1017,7 @@ class JavaThread: public Thread { friend class VMStructs; friend class JVMCIVMStructs; friend class WhiteBox; + friend class ThreadsSMRSupport; // to access _threadObj for exiting_threads_oops_do private: bool _on_thread_list; // Is set when this JavaThread is added to the Threads list oop _threadObj; // The Java level thread object diff --git a/src/hotspot/share/runtime/threadSMR.cpp b/src/hotspot/share/runtime/threadSMR.cpp index 7560b41404f..2cfac944fa3 100644 --- a/src/hotspot/share/runtime/threadSMR.cpp +++ b/src/hotspot/share/runtime/threadSMR.cpp @@ -41,6 +41,9 @@ #include "utilities/resourceHash.hpp" #include "utilities/vmError.hpp" +// List of exiting threads +ThreadsSMRSupport::Holder* ThreadsSMRSupport::_exiting_threads = NULL; + // The '_cnt', '_max' and '_times" fields are enabled via // -XX:+EnableThreadSMRStatistics: @@ -923,10 +926,14 @@ void ThreadsSMRSupport::release_stable_list_wake_up(bool is_nested) { } void ThreadsSMRSupport::remove_thread(JavaThread *thread) { + + ThreadsSMRSupport::add_exiting_thread(thread); + if (ThreadIdTable::is_initialized()) { jlong tid = SharedRuntime::get_java_tid(thread); ThreadIdTable::remove_thread(tid); } + ThreadsList *new_list = ThreadsList::remove_thread(ThreadsSMRSupport::get_java_thread_list(), thread); if (EnableThreadSMRStatistics) { ThreadsSMRSupport::inc_java_thread_list_alloc_cnt(); @@ -991,6 +998,7 @@ void ThreadsSMRSupport::wait_until_not_protected(JavaThread *thread) { // This is the common case. ThreadsSMRSupport::clear_delete_notify(); ThreadsSMRSupport::delete_lock()->unlock(); + ThreadsSMRSupport::remove_exiting_thread(thread); break; } if (!has_logged_once) { @@ -1180,3 +1188,47 @@ void ThreadsSMRSupport::print_info_elements_on(outputStream* st, ThreadsList* t_ cnt++; } } + +void ThreadsSMRSupport::add_exiting_thread(JavaThread* thread) { + assert(thread == JavaThread::current(), "invariant"); + assert(Threads_lock->owned_by_self(), "invariant"); + assert(!contains_exiting_thread(thread), "invariant"); + Holder* h = new Holder(thread, _exiting_threads); + _exiting_threads = h; +} + +void ThreadsSMRSupport::remove_exiting_thread(JavaThread* thread) { + assert(thread == JavaThread::current(), "invariant"); + assert(Threads_lock->owned_by_self(), "invariant"); + // If a thread fails to initialize fully it can be deleted immediately + // so we won't remove it from the ThreadsList and so never add it to the + // exiting thread list - so we can't assert(contains_exiting_thread(p)) here. + + for (Holder* current = _exiting_threads, **prev_next = &_exiting_threads; + current != NULL; + prev_next = ¤t->_next, current = current->_next) { + if (current->_thread == thread) { + *prev_next = current->_next; + delete current; + break; + } + } +} + +#ifdef ASSERT +bool ThreadsSMRSupport::contains_exiting_thread(JavaThread* thread) { + for (Holder* current = _exiting_threads; current != NULL; current = current->_next) { + if (current->_thread == thread) { + return true; + } + } + return false; +} +#endif + +void ThreadsSMRSupport::exiting_threads_oops_do(OopClosure* f) { + assert_locked_or_safepoint(Threads_lock); + for (Holder* current = _exiting_threads; current != NULL; current = current->_next) { + f->do_oop((oop*) ¤t->_thread->_threadObj); + } +} diff --git a/src/hotspot/share/runtime/threadSMR.hpp b/src/hotspot/share/runtime/threadSMR.hpp index 5ca21de3191..6b68353de2a 100644 --- a/src/hotspot/share/runtime/threadSMR.hpp +++ b/src/hotspot/share/runtime/threadSMR.hpp @@ -81,7 +81,16 @@ class ThreadClosure; // remains in scope. The target JavaThread * may have logically exited, // but that target JavaThread * will not be deleted until it is no // longer protected by a ThreadsListHandle. - +// +// Once a JavaThread has removed itself from the main ThreadsList it is +// no longer visited by GC. To ensure that thread's threadObj() oop remains +// valid while the thread is still accessible from a ThreadsListHandle we +// maintain a special list of exiting threads: +// - In remove() we add the exiting thread to the list (under the Threads_lock). +// - In wait_until_not_protected() we remove it from the list (again under the +// Threads_lock). +// - Universe::oops_do walks the list (at a safepoint so VMThread holds +// Threads_lock) and visits the _threadObj oop of each JavaThread. // SMR Support for the Threads class. // @@ -89,6 +98,17 @@ class ThreadsSMRSupport : AllStatic { friend class VMStructs; friend class SafeThreadsListPtr; // for _nested_thread_list_max, delete_notify(), release_stable_list_wake_up() access + // Helper class for the exiting thread list + class Holder : public CHeapObj { + public: + JavaThread* _thread; + Holder* _next; + Holder(JavaThread* thread, Holder* next) : _thread(thread), _next(next) {} + }; + + // The list of exiting threads + static Holder* _exiting_threads; + // The coordination between ThreadsSMRSupport::release_stable_list() and // ThreadsSMRSupport::smr_delete() uses the delete_lock in order to // reduce the traffic on the Threads_lock. @@ -150,6 +170,12 @@ class ThreadsSMRSupport : AllStatic { static void smr_delete(JavaThread *thread); static void update_tlh_stats(uint millis); + // Exiting thread list maintenance + static void add_exiting_thread(JavaThread* thread); + static void remove_exiting_thread(JavaThread* thread); + DEBUG_ONLY(static bool contains_exiting_thread(JavaThread* thread);) + static void exiting_threads_oops_do(OopClosure* f); + // Logging and printing support: static void log_statistics(); static void print_info_elements_on(outputStream* st, ThreadsList* t_list); diff --git a/test/hotspot/jtreg/runtime/Thread/ThreadObjAccessAtExit.java b/test/hotspot/jtreg/runtime/Thread/ThreadObjAccessAtExit.java new file mode 100644 index 00000000000..f34124eac2f --- /dev/null +++ b/test/hotspot/jtreg/runtime/Thread/ThreadObjAccessAtExit.java @@ -0,0 +1,117 @@ +/* + * 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 8240588 + * @summary Use the WhiteBox API to ensure that we can safely access the + * threadObj oop of a JavaThread during termination, after it has + * removed itself from the main ThreadsList. + * @library /testlibrary /test/lib + * @build sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox + * @comment run with a small heap, but we need at least 7M for ZGC + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xmx7m -XX:-DisableExplicitGC ThreadObjAccessAtExit + */ + +import sun.hotspot.WhiteBox; + +// We need to coordinate the actions of the target thread, the GC thread +// and the WB main test method. To simplify things we use the target +// thread's priority field to indicate the state of the test as follows: +// - Start the target thread with priority 5 (NORM_PRIORITY), it will run +// until its priority is boosted by 1 +// - Start the GC thread, which will spin until the target thread's priority +// has been boosted by 2 +// - Call into the WB test method and: +// - Grab a ThreadsListHandle and ensure it contains the target +// - Increase the target priority by one so it will terminate +// - Wait until we see the JavaThread has terminated +// - Increase the target thread priority by one again to release the GC thread +// - Check the original Thread oop with the target->threadObj to see if they +// are the same (looping a few times to improve the chances of GC having +// time to move the underlying object). +// - If the oop has changed throw an exception + +public class ThreadObjAccessAtExit { + + static class GCThread extends Thread { + + // Allocate a moderate-size array + static Object[] arr = new Object[64*1024]; + + // Wait till we see the main thread is ready then clear the storage + // we consumed at class initialization and run an explicit GC cycle. + // This is sufficient (via experimentation) to cause the oop to be + // relocated. + public void run() { + System.out.println("GCThread waiting ... "); + try { + while (target.getPriority() != Thread.NORM_PRIORITY + 2) { + Thread.sleep(10); + } + } + catch(InterruptedException ie) { + throw new RuntimeException(ie); + } + + System.out.println("GCThread running ... "); + + arr = null; + System.gc(); + } + } + + static Thread target; // for easy access from GCThread + + public static void main(String[] args) throws Throwable { + WhiteBox wb = WhiteBox.getWhiteBox(); + + // Create the GCThread, which performs the initial large + // allocation that will later be released when it runs. + GCThread g = new GCThread(); + g.setName("GCThread"); + + // Create the target thread (hopefully in a region that will cause + // it to move when GC happens later). + target = new Thread("Target") { + public void run() { + Thread current = Thread.currentThread(); + // Wait until we are told to terminate by the main thread + try { + while (current.getPriority() != Thread.NORM_PRIORITY + 1) { + Thread.sleep(10); + } + } + catch(InterruptedException ie) { + throw new RuntimeException(ie); + } + System.out.println("Target is terminating"); + } + }; + g.start(); + target.setPriority(Thread.NORM_PRIORITY); // just to be explicit + target.start(); + wb.checkThreadObjOfTerminatingThread(target); + } +} diff --git a/test/lib/sun/hotspot/WhiteBox.java b/test/lib/sun/hotspot/WhiteBox.java index 66e1abdc6d9..67235798bb4 100644 --- a/test/lib/sun/hotspot/WhiteBox.java +++ b/test/lib/sun/hotspot/WhiteBox.java @@ -613,4 +613,7 @@ public class WhiteBox { public native int aotLibrariesCount(); public native int getKlassMetadataSize(Class c); + + // ThreadSMR GC safety check for threadObj + public native void checkThreadObjOfTerminatingThread(Thread target); } From 587505f14a883f5754b0f6c22b6e83d91e2d95d2 Mon Sep 17 00:00:00 2001 From: Jie Fu Date: Thu, 14 May 2020 09:25:49 +0800 Subject: [PATCH 053/143] 8244971: Zero VM is broken after JDK-8241825 (COMPRESSED_CLASS_POINTERS_DEPENDS_ON_COMPRESSED_OOPS not defined) Reviewed-by: dholmes --- src/hotspot/cpu/zero/globalDefinitions_zero.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hotspot/cpu/zero/globalDefinitions_zero.hpp b/src/hotspot/cpu/zero/globalDefinitions_zero.hpp index fa6aae8f34f..1ac536f4cdf 100644 --- a/src/hotspot/cpu/zero/globalDefinitions_zero.hpp +++ b/src/hotspot/cpu/zero/globalDefinitions_zero.hpp @@ -36,4 +36,6 @@ // 32-bit integer argument values are extended to 64 bits. const bool CCallingConventionRequiresIntsAsLongs = false; +#define COMPRESSED_CLASS_POINTERS_DEPENDS_ON_COMPRESSED_OOPS true + #endif // CPU_ZERO_GLOBALDEFINITIONS_ZERO_HPP From 5b6f81de071d53a8786f8d90ee18e3d11397fd23 Mon Sep 17 00:00:00 2001 From: Thomas Stuefe Date: Thu, 14 May 2020 08:48:36 +0200 Subject: [PATCH 054/143] 8244777: ClassLoaderStats VM Op uses constant hash value Reviewed-by: coleenp, jbachorik --- src/hotspot/share/classfile/classLoaderStats.hpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/hotspot/share/classfile/classLoaderStats.hpp b/src/hotspot/share/classfile/classLoaderStats.hpp index f7c27c33d9c..6970b5fc957 100644 --- a/src/hotspot/share/classfile/classLoaderStats.hpp +++ b/src/hotspot/share/classfile/classLoaderStats.hpp @@ -102,8 +102,17 @@ protected: } static unsigned oop_hash(oop const& s1) { - unsigned hash = (unsigned)((uintptr_t)&s1); - return hash ^ (hash >> LogMinObjAlignment); + // Robert Jenkins 1996 & Thomas Wang 1997 + // http://web.archive.org/web/20071223173210/http://www.concentric.net/~Ttwang/tech/inthash.htm + uintptr_t tmp = cast_from_oop(s1); + unsigned hash = (unsigned)tmp; + hash = ~hash + (hash << 15); + hash = hash ^ (hash >> 12); + hash = hash + (hash << 2); + hash = hash ^ (hash >> 4); + hash = hash * 2057; + hash = hash ^ (hash >> 16); + return hash; } typedef ResourceHashtable Date: Thu, 14 May 2020 08:24:36 -0400 Subject: [PATCH 055/143] 8244684: G1 abuses StarTask to also include partial objarray scan tasks New ScannerTask and PartialArrayScanTask, initially used by G1 Reviewed-by: tschatzl, sjohanss --- src/hotspot/share/gc/g1/g1CollectedHeap.cpp | 25 +++--- src/hotspot/share/gc/g1/g1CollectedHeap.hpp | 15 ++-- .../share/gc/g1/g1CollectedHeap.inline.hpp | 4 +- .../share/gc/g1/g1OopClosures.inline.hpp | 4 +- .../share/gc/g1/g1ParScanThreadState.cpp | 56 ++++++------- .../share/gc/g1/g1ParScanThreadState.hpp | 56 +++---------- .../gc/g1/g1ParScanThreadState.inline.hpp | 70 +++++++--------- src/hotspot/share/gc/shared/taskqueue.hpp | 84 +++++++++++++++++++ 8 files changed, 179 insertions(+), 135 deletions(-) diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp index aac26cd340a..b8696c42918 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp @@ -1542,12 +1542,12 @@ G1CollectedHeap::G1CollectedHeap() : _filler_array_max_size = _humongous_object_threshold_in_words; uint n_queues = ParallelGCThreads; - _task_queues = new RefToScanQueueSet(n_queues); + _task_queues = new ScannerTasksQueueSet(n_queues); _evacuation_failed_info_array = NEW_C_HEAP_ARRAY(EvacuationFailedInfo, n_queues, mtGC); for (uint i = 0; i < n_queues; i++) { - RefToScanQueue* q = new RefToScanQueue(); + ScannerTasksQueue* q = new ScannerTasksQueue(); q->initialize(); _task_queues->register_queue(i, q); ::new (&_evacuation_failed_info_array[i]) EvacuationFailedInfo(); @@ -3399,7 +3399,7 @@ public: // When the queue is drained (after each phase of reference processing) // the object and it's followers will be copied, the reference field set // to point to the new location, and the RSet updated. - _par_scan_state->push_on_queue(p); + _par_scan_state->push_on_queue(ScannerTask(p)); } } }; @@ -3436,14 +3436,14 @@ class G1STWRefProcTaskExecutor: public AbstractRefProcTaskExecutor { private: G1CollectedHeap* _g1h; G1ParScanThreadStateSet* _pss; - RefToScanQueueSet* _queues; + ScannerTasksQueueSet* _queues; WorkGang* _workers; public: G1STWRefProcTaskExecutor(G1CollectedHeap* g1h, G1ParScanThreadStateSet* per_thread_states, WorkGang* workers, - RefToScanQueueSet *task_queues) : + ScannerTasksQueueSet *task_queues) : _g1h(g1h), _pss(per_thread_states), _queues(task_queues), @@ -3463,14 +3463,14 @@ class G1STWRefProcTaskProxy: public AbstractGangTask { ProcessTask& _proc_task; G1CollectedHeap* _g1h; G1ParScanThreadStateSet* _pss; - RefToScanQueueSet* _task_queues; + ScannerTasksQueueSet* _task_queues; TaskTerminator* _terminator; public: G1STWRefProcTaskProxy(ProcessTask& proc_task, G1CollectedHeap* g1h, G1ParScanThreadStateSet* per_thread_states, - RefToScanQueueSet *task_queues, + ScannerTasksQueueSet *task_queues, TaskTerminator* terminator) : AbstractGangTask("Process reference objects in parallel"), _proc_task(proc_task), @@ -3801,7 +3801,7 @@ class G1EvacuateRegionsBaseTask : public AbstractGangTask { protected: G1CollectedHeap* _g1h; G1ParScanThreadStateSet* _per_thread_states; - RefToScanQueueSet* _task_queues; + ScannerTasksQueueSet* _task_queues; TaskTerminator _terminator; uint _num_workers; @@ -3839,7 +3839,10 @@ protected: virtual void evacuate_live_objects(G1ParScanThreadState* pss, uint worker_id) = 0; public: - G1EvacuateRegionsBaseTask(const char* name, G1ParScanThreadStateSet* per_thread_states, RefToScanQueueSet* task_queues, uint num_workers) : + G1EvacuateRegionsBaseTask(const char* name, + G1ParScanThreadStateSet* per_thread_states, + ScannerTasksQueueSet* task_queues, + uint num_workers) : AbstractGangTask(name), _g1h(G1CollectedHeap::heap()), _per_thread_states(per_thread_states), @@ -3890,7 +3893,7 @@ class G1EvacuateRegionsTask : public G1EvacuateRegionsBaseTask { public: G1EvacuateRegionsTask(G1CollectedHeap* g1h, G1ParScanThreadStateSet* per_thread_states, - RefToScanQueueSet* task_queues, + ScannerTasksQueueSet* task_queues, G1RootProcessor* root_processor, uint num_workers) : G1EvacuateRegionsBaseTask("G1 Evacuate Regions", per_thread_states, task_queues, num_workers), @@ -3938,7 +3941,7 @@ class G1EvacuateOptionalRegionsTask : public G1EvacuateRegionsBaseTask { public: G1EvacuateOptionalRegionsTask(G1ParScanThreadStateSet* per_thread_states, - RefToScanQueueSet* queues, + ScannerTasksQueueSet* queues, uint num_workers) : G1EvacuateRegionsBaseTask("G1 Evacuate Optional Regions", per_thread_states, queues, num_workers) { } diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp index 7b2463d4c94..e78480aece0 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp @@ -54,6 +54,7 @@ #include "gc/shared/plab.hpp" #include "gc/shared/preservedMarks.hpp" #include "gc/shared/softRefPolicy.hpp" +#include "gc/shared/taskqueue.hpp" #include "memory/memRegion.hpp" #include "utilities/stack.hpp" @@ -97,8 +98,8 @@ class G1HeapSizingPolicy; class G1HeapSummary; class G1EvacSummary; -typedef OverflowTaskQueue RefToScanQueue; -typedef GenericTaskQueueSet RefToScanQueueSet; +typedef OverflowTaskQueue ScannerTasksQueue; +typedef GenericTaskQueueSet ScannerTasksQueueSet; typedef int RegionIdx_t; // needs to hold [ 0..max_regions() ) typedef int CardIdx_t; // needs to hold [ 0..CardsPerRegion ) @@ -814,7 +815,7 @@ public: G1ConcurrentRefine* _cr; // The parallel task queues - RefToScanQueueSet *_task_queues; + ScannerTasksQueueSet *_task_queues; // True iff a evacuation has failed in the current collection. bool _evacuation_failed; @@ -951,7 +952,7 @@ public: G1CMSubjectToDiscoveryClosure _is_subject_to_discovery_cm; public: - RefToScanQueue *task_queue(uint i) const; + ScannerTasksQueue* task_queue(uint i) const; uint num_task_queues() const; @@ -1478,18 +1479,18 @@ private: protected: G1CollectedHeap* _g1h; G1ParScanThreadState* _par_scan_state; - RefToScanQueueSet* _queues; + ScannerTasksQueueSet* _queues; TaskTerminator* _terminator; G1GCPhaseTimes::GCParPhases _phase; G1ParScanThreadState* par_scan_state() { return _par_scan_state; } - RefToScanQueueSet* queues() { return _queues; } + ScannerTasksQueueSet* queues() { return _queues; } TaskTerminator* terminator() { return _terminator; } public: G1ParEvacuateFollowersClosure(G1CollectedHeap* g1h, G1ParScanThreadState* par_scan_state, - RefToScanQueueSet* queues, + ScannerTasksQueueSet* queues, TaskTerminator* terminator, G1GCPhaseTimes::GCParPhases phase) : _start_term(0.0), _term_time(0.0), _term_attempts(0), diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp b/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp index ac9bf8d6724..62606f35dc5 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp @@ -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 @@ -139,7 +139,7 @@ G1CollectedHeap::dirty_young_block(HeapWord* start, size_t word_size) { card_table()->g1_mark_as_young(mr); } -inline RefToScanQueue* G1CollectedHeap::task_queue(uint i) const { +inline ScannerTasksQueue* G1CollectedHeap::task_queue(uint i) const { return _task_queues->queue(i); } diff --git a/src/hotspot/share/gc/g1/g1OopClosures.inline.hpp b/src/hotspot/share/gc/g1/g1OopClosures.inline.hpp index 2274f907c41..c7f24a50e15 100644 --- a/src/hotspot/share/gc/g1/g1OopClosures.inline.hpp +++ b/src/hotspot/share/gc/g1/g1OopClosures.inline.hpp @@ -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 @@ -58,7 +58,7 @@ inline void G1ScanClosureBase::prefetch_and_push(T* p, const oop obj) { obj->forwardee() == RawAccess<>::oop_load(p)), "p should still be pointing to obj or to its forwardee"); - _par_scan_state->push_on_queue(p); + _par_scan_state->push_on_queue(ScannerTask(p)); } template diff --git a/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp b/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp index 825c8b353a9..60f07ad9baa 100644 --- a/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp +++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp @@ -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 @@ -43,7 +43,7 @@ G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, size_t young_cset_length, size_t optional_cset_length) : _g1h(g1h), - _refs(g1h->task_queue(worker_id)), + _task_queue(g1h->task_queue(worker_id)), _rdcq(rdcqs), _ct(g1h->card_table()), _closures(NULL), @@ -119,46 +119,45 @@ size_t G1ParScanThreadState::lab_undo_waste_words() const { } #ifdef ASSERT -bool G1ParScanThreadState::verify_ref(narrowOop* ref) const { - assert(ref != NULL, "invariant"); +void G1ParScanThreadState::verify_task(narrowOop* task) const { + assert(task != NULL, "invariant"); assert(UseCompressedOops, "sanity"); - assert(!has_partial_array_mask(ref), "ref=" PTR_FORMAT, p2i(ref)); - oop p = RawAccess<>::oop_load(ref); + oop p = RawAccess<>::oop_load(task); assert(_g1h->is_in_g1_reserved(p), - "ref=" PTR_FORMAT " p=" PTR_FORMAT, p2i(ref), p2i(p)); - return true; + "task=" PTR_FORMAT " p=" PTR_FORMAT, p2i(task), p2i(p)); } -bool G1ParScanThreadState::verify_ref(oop* ref) const { - assert(ref != NULL, "invariant"); - if (has_partial_array_mask(ref)) { - // Must be in the collection set--it's already been copied. - oop p = clear_partial_array_mask(ref); - assert(_g1h->is_in_cset(p), - "ref=" PTR_FORMAT " p=" PTR_FORMAT, p2i(ref), p2i(p)); - } else { - oop p = RawAccess<>::oop_load(ref); - assert(_g1h->is_in_g1_reserved(p), - "ref=" PTR_FORMAT " p=" PTR_FORMAT, p2i(ref), p2i(p)); - } - return true; +void G1ParScanThreadState::verify_task(oop* task) const { + assert(task != NULL, "invariant"); + oop p = RawAccess<>::oop_load(task); + assert(_g1h->is_in_g1_reserved(p), + "task=" PTR_FORMAT " p=" PTR_FORMAT, p2i(task), p2i(p)); } -bool G1ParScanThreadState::verify_task(StarTask ref) const { - if (ref.is_narrow()) { - return verify_ref((narrowOop*) ref); +void G1ParScanThreadState::verify_task(PartialArrayScanTask task) const { + // Must be in the collection set--it's already been copied. + oop p = task.to_source_array(); + assert(_g1h->is_in_cset(p), "p=" PTR_FORMAT, p2i(p)); +} + +void G1ParScanThreadState::verify_task(ScannerTask task) const { + if (task.is_narrow_oop_ptr()) { + verify_task(task.to_narrow_oop_ptr()); + } else if (task.is_oop_ptr()) { + verify_task(task.to_oop_ptr()); + } else if (task.is_partial_array_task()) { + verify_task(task.to_partial_array_task()); } else { - return verify_ref((oop*) ref); + ShouldNotReachHere(); } } #endif // ASSERT void G1ParScanThreadState::trim_queue() { - StarTask ref; do { // Fully drain the queue. trim_queue_to_threshold(0); - } while (!_refs->is_empty()); + } while (!_task_queue->is_empty()); } HeapWord* G1ParScanThreadState::allocate_in_next_plab(G1HeapRegionAttr* dest, @@ -330,8 +329,7 @@ oop G1ParScanThreadState::copy_to_survivor_space(G1HeapRegionAttr const region_a // the to-space object. The actual length can be found in the // length field of the from-space object. arrayOop(obj)->set_length(0); - oop* old_p = set_partial_array_mask(old); - do_oop_partial_array(old_p); + do_partial_array(PartialArrayScanTask(old)); } else { G1ScanInYoungSetter x(&_scanner, dest_attr.is_young()); obj->oop_iterate_backwards(&_scanner); diff --git a/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp b/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp index 2e14d68001e..02c6c023c00 100644 --- a/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp +++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp @@ -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 @@ -33,6 +33,7 @@ #include "gc/g1/g1RemSet.hpp" #include "gc/g1/heapRegionRemSet.hpp" #include "gc/shared/ageTable.hpp" +#include "gc/shared/taskqueue.hpp" #include "memory/allocation.hpp" #include "oops/oop.hpp" #include "utilities/ticks.hpp" @@ -45,7 +46,7 @@ class outputStream; class G1ParScanThreadState : public CHeapObj { G1CollectedHeap* _g1h; - RefToScanQueue* _refs; + ScannerTasksQueue* _task_queue; G1RedirtyCardsQueue _rdcq; G1CardTable* _ct; G1EvacuationRootClosures* _closures; @@ -114,15 +115,15 @@ public: void set_ref_discoverer(ReferenceDiscoverer* rd) { _scanner.set_ref_discoverer(rd); } #ifdef ASSERT - bool queue_is_empty() const { return _refs->is_empty(); } + bool queue_is_empty() const { return _task_queue->is_empty(); } +#endif - bool verify_ref(narrowOop* ref) const; - bool verify_ref(oop* ref) const; - bool verify_task(StarTask ref) const; -#endif // ASSERT + void verify_task(narrowOop* task) const NOT_DEBUG_RETURN; + void verify_task(oop* task) const NOT_DEBUG_RETURN; + void verify_task(PartialArrayScanTask task) const NOT_DEBUG_RETURN; + void verify_task(ScannerTask task) const NOT_DEBUG_RETURN; - template void do_oop_ext(T* ref); - template void push_on_queue(T* ref); + void push_on_queue(ScannerTask task); template void enqueue_card_if_tracked(G1HeapRegionAttr region_attr, T* p, oop o) { assert(!HeapRegion::is_in_same_region(p, o), "Should have filtered out cross-region references already."); @@ -158,43 +159,12 @@ public: size_t flush(size_t* surviving_young_words); private: - #define G1_PARTIAL_ARRAY_MASK 0x2 - - inline bool has_partial_array_mask(oop* ref) const { - return ((uintptr_t)ref & G1_PARTIAL_ARRAY_MASK) == G1_PARTIAL_ARRAY_MASK; - } - - // We never encode partial array oops as narrowOop*, so return false immediately. - // This allows the compiler to create optimized code when popping references from - // the work queue. - inline bool has_partial_array_mask(narrowOop* ref) const { - assert(((uintptr_t)ref & G1_PARTIAL_ARRAY_MASK) != G1_PARTIAL_ARRAY_MASK, "Partial array oop reference encoded as narrowOop*"); - return false; - } - - // Only implement set_partial_array_mask() for regular oops, not for narrowOops. - // We always encode partial arrays as regular oop, to allow the - // specialization for has_partial_array_mask() for narrowOops above. - // This means that unintentional use of this method with narrowOops are caught - // by the compiler. - inline oop* set_partial_array_mask(oop obj) const { - assert(((uintptr_t)(void *)obj & G1_PARTIAL_ARRAY_MASK) == 0, "Information loss!"); - return (oop*) ((uintptr_t)(void *)obj | G1_PARTIAL_ARRAY_MASK); - } - - inline oop clear_partial_array_mask(oop* ref) const { - return cast_to_oop((intptr_t)ref & ~G1_PARTIAL_ARRAY_MASK); - } - - inline void do_oop_partial_array(oop* p); + inline void do_partial_array(PartialArrayScanTask task); // This method is applied to the fields of the objects that have just been copied. template inline void do_oop_evac(T* p); - inline void deal_with_reference(oop* ref_to_scan); - inline void deal_with_reference(narrowOop* ref_to_scan); - - inline void dispatch_reference(StarTask ref); + inline void dispatch_task(ScannerTask task); // Tries to allocate word_sz in the PLAB of the next "generation" after trying to // allocate into dest. Previous_plab_refill_failed indicates whether previous @@ -232,7 +202,7 @@ public: Tickspan trim_ticks() const; void reset_trim_ticks(); - inline void steal_and_trim_queue(RefToScanQueueSet *task_queues); + inline void steal_and_trim_queue(ScannerTasksQueueSet *task_queues); // An attempt to evacuate "obj" has failed; take necessary steps. oop handle_evacuation_failure_par(oop obj, markWord m); diff --git a/src/hotspot/share/gc/g1/g1ParScanThreadState.inline.hpp b/src/hotspot/share/gc/g1/g1ParScanThreadState.inline.hpp index 085ad6e8712..47e8e7ac468 100644 --- a/src/hotspot/share/gc/g1/g1ParScanThreadState.inline.hpp +++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.inline.hpp @@ -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 @@ -71,14 +71,13 @@ template void G1ParScanThreadState::do_oop_evac(T* p) { } } -template inline void G1ParScanThreadState::push_on_queue(T* ref) { - assert(verify_ref(ref), "sanity"); - _refs->push(ref); +inline void G1ParScanThreadState::push_on_queue(ScannerTask task) { + verify_task(task); + _task_queue->push(task); } -inline void G1ParScanThreadState::do_oop_partial_array(oop* p) { - assert(has_partial_array_mask(p), "invariant"); - oop from_obj = clear_partial_array_mask(p); +inline void G1ParScanThreadState::do_partial_array(PartialArrayScanTask task) { + oop from_obj = task.to_source_array(); assert(_g1h->is_in_reserved(from_obj), "must be in heap."); assert(from_obj->is_objArray(), "must be obj array"); @@ -105,8 +104,7 @@ inline void G1ParScanThreadState::do_oop_partial_array(oop* p) { to_obj_array->set_length(end); // Push the remainder before we process the range in case another // worker has run out of things to do and can steal it. - oop* from_obj_p = set_partial_array_mask(from_obj); - push_on_queue(from_obj_p); + push_on_queue(ScannerTask(PartialArrayScanTask(from_obj))); } else { assert(length == end, "sanity"); // We'll process the final range for this object. Restore the length @@ -127,35 +125,23 @@ inline void G1ParScanThreadState::do_oop_partial_array(oop* p) { to_obj_array->oop_iterate_range(&_scanner, start, end); } -inline void G1ParScanThreadState::deal_with_reference(oop* ref_to_scan) { - if (!has_partial_array_mask(ref_to_scan)) { - do_oop_evac(ref_to_scan); +inline void G1ParScanThreadState::dispatch_task(ScannerTask task) { + verify_task(task); + if (task.is_narrow_oop_ptr()) { + do_oop_evac(task.to_narrow_oop_ptr()); + } else if (task.is_oop_ptr()) { + do_oop_evac(task.to_oop_ptr()); } else { - do_oop_partial_array(ref_to_scan); + do_partial_array(task.to_partial_array_task()); } } -inline void G1ParScanThreadState::deal_with_reference(narrowOop* ref_to_scan) { - assert(!has_partial_array_mask(ref_to_scan), "NarrowOop* elements should never be partial arrays."); - do_oop_evac(ref_to_scan); -} - -inline void G1ParScanThreadState::dispatch_reference(StarTask ref) { - assert(verify_task(ref), "sanity"); - if (ref.is_narrow()) { - deal_with_reference((narrowOop*)ref); - } else { - deal_with_reference((oop*)ref); - } -} - -void G1ParScanThreadState::steal_and_trim_queue(RefToScanQueueSet *task_queues) { - StarTask stolen_task; +void G1ParScanThreadState::steal_and_trim_queue(ScannerTasksQueueSet *task_queues) { + ScannerTask stolen_task; while (task_queues->steal(_worker_id, stolen_task)) { - assert(verify_task(stolen_task), "sanity"); - dispatch_reference(stolen_task); + dispatch_task(stolen_task); - // We've just processed a reference and we might have made + // We've just processed a task and we might have made // available new entries on the queues. So we have to make sure // we drain the queues as necessary. trim_queue(); @@ -163,24 +149,26 @@ void G1ParScanThreadState::steal_and_trim_queue(RefToScanQueueSet *task_queues) } inline bool G1ParScanThreadState::needs_partial_trimming() const { - return !_refs->overflow_empty() || _refs->size() > _stack_trim_upper_threshold; + return !_task_queue->overflow_empty() || + (_task_queue->size() > _stack_trim_upper_threshold); } inline bool G1ParScanThreadState::is_partially_trimmed() const { - return _refs->overflow_empty() && _refs->size() <= _stack_trim_lower_threshold; + return _task_queue->overflow_empty() && + (_task_queue->size() <= _stack_trim_lower_threshold); } inline void G1ParScanThreadState::trim_queue_to_threshold(uint threshold) { - StarTask ref; + ScannerTask task; // Drain the overflow stack first, so other threads can potentially steal. - while (_refs->pop_overflow(ref)) { - if (!_refs->try_push_to_taskqueue(ref)) { - dispatch_reference(ref); + while (_task_queue->pop_overflow(task)) { + if (!_task_queue->try_push_to_taskqueue(task)) { + dispatch_task(task); } } - while (_refs->pop_local(ref, threshold)) { - dispatch_reference(ref); + while (_task_queue->pop_local(task, threshold)) { + dispatch_task(task); } } @@ -220,7 +208,7 @@ inline void G1ParScanThreadState::remember_reference_into_optional_region(T* p) assert(index < _num_optional_regions, "Trying to access optional region idx %u beyond " SIZE_FORMAT, index, _num_optional_regions); _oops_into_optional_regions[index].push_oop(p); - DEBUG_ONLY(verify_ref(p);) + verify_task(p); } G1OopStarChunkedList* G1ParScanThreadState::oops_into_optional_region(const HeapRegion* hr) { diff --git a/src/hotspot/share/gc/shared/taskqueue.hpp b/src/hotspot/share/gc/shared/taskqueue.hpp index 7a6896384fa..312050b4098 100644 --- a/src/hotspot/share/gc/shared/taskqueue.hpp +++ b/src/hotspot/share/gc/shared/taskqueue.hpp @@ -564,4 +564,88 @@ private: int _index; }; +// Wrapper over an oop that is a partially scanned array. +// Can be converted to a ScannerTask for placement in associated task queues. +// Refers to the partially copied source array oop. +class PartialArrayScanTask { + oop _src; + +public: + PartialArrayScanTask() : _src() {} + explicit PartialArrayScanTask(oop src_array) : _src(src_array) {} + // Trivially copyable. + + oop to_source_array() const { return _src; } +}; + +// Discriminated union over oop*, narrowOop*, and PartialArrayScanTask. +// Uses a low tag in the associated pointer to identify the category. +// Used as a task queue element type. +class ScannerTask { + void* _p; + + static const uintptr_t OopTag = 0; + static const uintptr_t NarrowOopTag = 1; + static const uintptr_t PartialArrayTag = 2; + static const uintptr_t TagSize = 2; + static const uintptr_t TagAlignment = 1 << TagSize; + static const uintptr_t TagMask = TagAlignment - 1; + + static void* encode(void* p, uintptr_t tag) { + assert(is_aligned(p, TagAlignment), "misaligned: " PTR_FORMAT, p2i(p)); + return static_cast(p) + tag; + } + + uintptr_t raw_value() const { + return reinterpret_cast(_p); + } + + bool has_tag(uintptr_t tag) const { + return (raw_value() & TagMask) == tag; + } + + void* decode(uintptr_t tag) const { + assert(has_tag(tag), "precondition"); + return static_cast(_p) - tag; + } + +public: + ScannerTask() : _p(NULL) {} + + explicit ScannerTask(oop* p) : _p(encode(p, OopTag)) {} + + explicit ScannerTask(narrowOop* p) : _p(encode(p, NarrowOopTag)) {} + + explicit ScannerTask(PartialArrayScanTask t) : + _p(encode(t.to_source_array(), PartialArrayTag)) {} + + // Trivially copyable. + + // Predicate implementations assume OopTag == 0, others are powers of 2. + + bool is_oop_ptr() const { + return (raw_value() & (NarrowOopTag | PartialArrayTag)) == 0; + } + + bool is_narrow_oop_ptr() const { + return (raw_value() & NarrowOopTag) != 0; + } + + bool is_partial_array_task() const { + return (raw_value() & PartialArrayTag) != 0; + } + + oop* to_oop_ptr() const { + return static_cast(decode(OopTag)); + } + + narrowOop* to_narrow_oop_ptr() const { + return static_cast(decode(NarrowOopTag)); + } + + PartialArrayScanTask to_partial_array_task() const { + return PartialArrayScanTask(oop(decode(PartialArrayTag))); + } +}; + #endif // SHARE_GC_SHARED_TASKQUEUE_HPP From 9768618bab25f7e02897cec4750c1b1dcec11afb Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Thu, 14 May 2020 05:35:06 -0700 Subject: [PATCH 056/143] 8244945: Mark VS2019 as supported and default Reviewed-by: ihse --- make/autoconf/toolchain_windows.m4 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/make/autoconf/toolchain_windows.m4 b/make/autoconf/toolchain_windows.m4 index 6067f22fd74..62e4f288b4b 100644 --- a/make/autoconf/toolchain_windows.m4 +++ b/make/autoconf/toolchain_windows.m4 @@ -25,7 +25,7 @@ ################################################################################ # The order of these defines the priority by which we try to find them. -VALID_VS_VERSIONS="2017 2019 2013 2015 2012 2010" +VALID_VS_VERSIONS="2019 2017 2013 2015 2012 2010" VS_DESCRIPTION_2010="Microsoft Visual Studio 2010" VS_VERSION_INTERNAL_2010=100 @@ -101,8 +101,8 @@ VS_EDITIONS_2019="BuildTools Community Professional Enterprise" VS_SDK_INSTALLDIR_2019= VS_VS_PLATFORM_NAME_2019="v142" VS_SDK_PLATFORM_NAME_2019= -VS_SUPPORTED_2019=false -VS_TOOLSET_SUPPORTED_2019=false +VS_SUPPORTED_2019=true +VS_TOOLSET_SUPPORTED_2019=true ################################################################################ From 0cc7f3585f38e80110c272dcb5fef3ef850dd5b1 Mon Sep 17 00:00:00 2001 From: Andy Herrick Date: Wed, 13 May 2020 16:05:02 -0400 Subject: [PATCH 057/143] 8244576: [macos] Volume icon deleted by osascript for background image Reviewed-by: asemenyuk, almatvee --- .../jpackage/internal/MacDmgBundler.java | 33 +++++++++---------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacDmgBundler.java b/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacDmgBundler.java index 81de7f34743..78c0b8ff2da 100644 --- a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacDmgBundler.java +++ b/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacDmgBundler.java @@ -310,19 +310,29 @@ public class MacDmgBundler extends MacBaseInstallerBundler { File mountedRoot = new File(imagesRoot.getAbsolutePath(), APP_NAME.fetchFrom(params)); - try { - // volume icon - File volumeIconFile = new File(mountedRoot, ".VolumeIcon.icns"); - IOUtils.copyFile(getConfig_VolumeIcon(params), - volumeIconFile); - // background image File bgdir = new File(mountedRoot, BACKGROUND_IMAGE_FOLDER); bgdir.mkdirs(); IOUtils.copyFile(getConfig_VolumeBackground(params), new File(bgdir, BACKGROUND_IMAGE)); + // We will not consider setting background image and creating link + // to install-dir in DMG as critical error, since it can fail in + // headless enviroment. + try { + pb = new ProcessBuilder("osascript", + getConfig_VolumeScript(params).getAbsolutePath()); + IOUtils.exec(pb); + } catch (IOException ex) { + Log.verbose(ex); + } + + // volume icon + File volumeIconFile = new File(mountedRoot, ".VolumeIcon.icns"); + IOUtils.copyFile(getConfig_VolumeIcon(params), + volumeIconFile); + // Indicate that we want a custom icon // NB: attributes of the root directory are ignored // when creating the volume @@ -356,16 +366,6 @@ public class MacDmgBundler extends MacBaseInstallerBundler { Log.verbose(I18N.getString("message.setfile.dmg")); } - // We will not consider setting background image and creating link to - // /Application folder in DMG as critical error, since it can fail in - // headless enviroment. - try { - pb = new ProcessBuilder("osascript", - getConfig_VolumeScript(params).getAbsolutePath()); - IOUtils.exec(pb); - } catch (IOException ex) { - Log.verbose(ex); - } } finally { // Detach the temporary image pb = new ProcessBuilder( @@ -493,5 +493,4 @@ public class MacDmgBundler extends MacBaseInstallerBundler { public boolean isDefault() { return true; } - } From c9925219955d3cb841c919c2da56d3122c83f4c1 Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Thu, 14 May 2020 06:58:59 -0700 Subject: [PATCH 058/143] 8244951: Missing entitlements for hardened runtime Reviewed-by: ihse --- make/CompileJavaModules.gmk | 2 +- make/common/NativeCompilation.gmk | 15 +++++- .../{entitlements.plist => default.plist} | 0 .../data/macosxsigning/java.plist | 4 +- make/data/macosxsigning/jspawnhelper.plist | 8 ++++ .../modules/jdk.incubator.jpackage/Gensrc.gmk | 46 +++++++++++++++++++ 6 files changed, 72 insertions(+), 3 deletions(-) rename make/data/macosxsigning/{entitlements.plist => default.plist} (100%) rename src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/entitlements.plist => make/data/macosxsigning/java.plist (72%) create mode 100644 make/data/macosxsigning/jspawnhelper.plist create mode 100644 make/modules/jdk.incubator.jpackage/Gensrc.gmk diff --git a/make/CompileJavaModules.gmk b/make/CompileJavaModules.gmk index 9d46af5bfb2..85c2232ec7f 100644 --- a/make/CompileJavaModules.gmk +++ b/make/CompileJavaModules.gmk @@ -384,7 +384,7 @@ endif jdk.incubator.jpackage_COPY += .gif .png .txt .spec .script .prerm .preinst \ .postrm .postinst .list .sh .desktop .copyright .control .plist .template \ - .icns .scpt .entitlements .wxs .wxl .wxi .ico .bmp .tiff + .icns .scpt .wxs .wxl .wxi .ico .bmp .tiff jdk.incubator.jpackage_CLEAN += .properties diff --git a/make/common/NativeCompilation.gmk b/make/common/NativeCompilation.gmk index 4bce970dd33..1b30ff9e4f9 100644 --- a/make/common/NativeCompilation.gmk +++ b/make/common/NativeCompilation.gmk @@ -266,6 +266,19 @@ else endif endif +################################################################################ +# GetEntitlementsFile +# Find entitlements file for executable when signing on macosx. If no +# specialized file is found, returns the default file. +# $1 Executable to find entitlements file for. +ENTITLEMENTS_DIR := $(TOPDIR)/make/data/macosxsigning +DEFAULT_ENTITLEMENTS_FILE := $(ENTITLEMENTS_DIR)/default.plist + +GetEntitlementsFile = \ + $(foreach f, $(ENTITLEMENTS_DIR)/$(strip $(notdir $1)).plist, \ + $(if $(wildcard $f), $f, $(DEFAULT_ENTITLEMENTS_FILE)) \ + ) + ################################################################################ # Create the recipe needed to compile a single native source file. # @@ -1183,7 +1196,7 @@ define SetupNativeCompilationBody # silently fail otherwise. ifneq ($(CODESIGN), ) $(CODESIGN) -s "$(MACOSX_CODESIGN_IDENTITY)" --timestamp --options runtime \ - --entitlements $(TOPDIR)/make/data/macosxsigning/entitlements.plist $$@ + --entitlements $$(call GetEntitlementsFile, $$@) $$@ endif endif diff --git a/make/data/macosxsigning/entitlements.plist b/make/data/macosxsigning/default.plist similarity index 100% rename from make/data/macosxsigning/entitlements.plist rename to make/data/macosxsigning/default.plist diff --git a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/entitlements.plist b/make/data/macosxsigning/java.plist similarity index 72% rename from src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/entitlements.plist rename to make/data/macosxsigning/java.plist index 677d0cc0408..b6f2a13ffa9 100644 --- a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/entitlements.plist +++ b/make/data/macosxsigning/java.plist @@ -1,5 +1,5 @@ - + com.apple.security.cs.allow-jit @@ -12,5 +12,7 @@ com.apple.security.cs.debugger + com.apple.security.device.audio-input + diff --git a/make/data/macosxsigning/jspawnhelper.plist b/make/data/macosxsigning/jspawnhelper.plist new file mode 100644 index 00000000000..484f4e01528 --- /dev/null +++ b/make/data/macosxsigning/jspawnhelper.plist @@ -0,0 +1,8 @@ + + + + + com.apple.security.cs.allow-dyld-environment-variables + + + diff --git a/make/modules/jdk.incubator.jpackage/Gensrc.gmk b/make/modules/jdk.incubator.jpackage/Gensrc.gmk new file mode 100644 index 00000000000..a62c8d45d53 --- /dev/null +++ b/make/modules/jdk.incubator.jpackage/Gensrc.gmk @@ -0,0 +1,46 @@ +# +# 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. +# + +include GensrcCommonJdk.gmk + +################################################################################ +# Copy the entitlements file for the java launcher to jpackage as a resource. + +ifeq ($(call isTargetOs, macosx), true) + ENTITLEMENTS_SRC_FILE := $(TOPDIR)/make/data/macosxsigning/java.plist + ENTITLEMENTS_TARGET_FILE := \ + $(SUPPORT_OUTPUTDIR)/gensrc/$(MODULE)/jdk/incubator/jpackage/internal/resources/entitlements.plist + + $(ENTITLEMENTS_TARGET_FILE): $(ENTITLEMENTS_SRC_FILE) + $(call install-file) + + TARGETS := $(ENTITLEMENTS_TARGET_FILE) +endif + +################################################################################ + +all: $(TARGETS) + +.PHONY: all From e13c481c7fe044594e310bc9d9a7d0503e902046 Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Thu, 14 May 2020 23:09:52 +0800 Subject: [PATCH 059/143] 8218482: sun/security/krb5/auto/ReplayCachePrecise.java failed - no KrbException thrown Reviewed-by: mullan --- .../security/krb5/auto/ReplayCachePrecise.java | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/test/jdk/sun/security/krb5/auto/ReplayCachePrecise.java b/test/jdk/sun/security/krb5/auto/ReplayCachePrecise.java index d6fc89259df..67ee042695a 100644 --- a/test/jdk/sun/security/krb5/auto/ReplayCachePrecise.java +++ b/test/jdk/sun/security/krb5/auto/ReplayCachePrecise.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 8001326 + * @bug 8001326 8218482 * @run main/othervm ReplayCachePrecise * @summary when there are 2 two AuthTime with the same time but different hash, * it's not a replay. @@ -34,7 +34,6 @@ import java.nio.channels.SeekableByteChannel; import java.nio.file.Files; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; -import java.util.Random; import sun.security.krb5.KrbException; import sun.security.krb5.internal.KerberosTime; import sun.security.krb5.internal.ReplayCache; @@ -43,15 +42,16 @@ import sun.security.krb5.internal.rcache.AuthTimeWithHash; public class ReplayCachePrecise { static final String client = "dummy@REALM"; static final String server = "server/localhost@REALM"; - static final Random rand = new Random(); public static void main(String[] args) throws Exception { - AuthTimeWithHash a1 = new AuthTimeWithHash(client, server, time(0), 0, + int time = (int)(System.currentTimeMillis()/1000); + + AuthTimeWithHash a1 = new AuthTimeWithHash(client, server, time, 0, "HASH", "1111111111111111"); - AuthTimeWithHash a2 = new AuthTimeWithHash(client, server, time(0), 0, + AuthTimeWithHash a2 = new AuthTimeWithHash(client, server, time, 0, "HASH", "2222222222222222"); - KerberosTime now = new KerberosTime(time(0)*1000L); + KerberosTime now = new KerberosTime(time*1000L); // When all new styles, must exact match ReplayCache cache = ReplayCache.getInstance("dfl:./c1"); @@ -77,8 +77,4 @@ public class ReplayCachePrecise { System.out.println(ke); } } - - private static int time(int x) { - return (int)(System.currentTimeMillis()/1000) + x; - } } From 8c5430972f2c8367d30abae163db991b7167ab88 Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Thu, 14 May 2020 18:56:30 +0200 Subject: [PATCH 060/143] 8245033: Fixes for building in WSL Reviewed-by: erikj --- make/TestImage.gmk | 15 ++++++++++----- make/autoconf/basic.m4 | 16 ++++------------ make/autoconf/basic_tools.m4 | 2 +- make/autoconf/toolchain.m4 | 15 +++++++++++++++ make/autoconf/toolchain_windows.m4 | 5 ++--- make/autoconf/util.m4 | 2 +- make/autoconf/util_windows.m4 | 7 ++++++- make/common/MakeBase.gmk | 9 +++++++-- make/common/NativeCompilation.gmk | 4 ++-- make/conf/jib-profiles.js | 8 +++++--- 10 files changed, 53 insertions(+), 30 deletions(-) diff --git a/make/TestImage.gmk b/make/TestImage.gmk index 8fd3a0c0eff..8511c5dc87f 100644 --- a/make/TestImage.gmk +++ b/make/TestImage.gmk @@ -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 @@ -35,17 +35,22 @@ ifeq ($(call isTargetOs, windows), true) $(FIXPATH_COPY): $(firstword $(FIXPATH)) $(call install-file) + + FIXPATH_WORKSPACE_ROOT := $(call FixPath, $(WORKSPACE_ROOT)) + FIXPATH_OUTPUTDIR := $(call FixPath, $(OUTPUTDIR)) +else + FIXPATH_WORKSPACE_ROOT := $(WORKSPACE_ROOT) + FIXPATH_OUTPUTDIR := $(OUTPUTDIR) endif -BUILD_INFO_PROPERTIES := $(TEST_IMAGE_DIR)/build-info.properties -FIXPATH_ECHO := $(FIXPATH) $(call FixPath, $(ECHO)) +BUILD_INFO_PROPERTIES := $(TEST_IMAGE_DIR)/build-info.properties $(BUILD_INFO_PROPERTIES): $(call MakeTargetDir) $(ECHO) "# Build info properties for JDK tests" > $@ - $(FIXPATH_ECHO) "build.workspace.root=$(WORKSPACE_ROOT)" >> $@ - $(FIXPATH_ECHO) "build.output.root=$(OUTPUTDIR)" >> $@ + $(ECHO) "build.workspace.root=$(FIXPATH_WORKSPACE_ROOT)" >> $@ + $(ECHO) "build.output.root=$(FIXPATH_OUTPUTDIR)" >> $@ prepare-test-image: $(FIXPATH_COPY) $(BUILD_INFO_PROPERTIES) $(call MakeDir, $(TEST_IMAGE_DIR)) diff --git a/make/autoconf/basic.m4 b/make/autoconf/basic.m4 index 3d3e6aeea86..26fa5879a0e 100644 --- a/make/autoconf/basic.m4 +++ b/make/autoconf/basic.m4 @@ -423,24 +423,16 @@ AC_DEFUN([BASIC_CHECK_DIR_ON_LOCAL_DISK], # is the same. On older AIXes we just continue to live with a "not local build" warning. if test "x$OPENJDK_TARGET_OS" = xaix; then DF_LOCAL_ONLY_OPTION='-T local' + elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.wsl"; then + # In WSL, we can only build on a drvfs file system (that is, a mounted real Windows drive) + DF_LOCAL_ONLY_OPTION='-t drvfs' else DF_LOCAL_ONLY_OPTION='-l' fi if $DF $DF_LOCAL_ONLY_OPTION $1 > /dev/null 2>&1; then $2 else - # In WSL, local Windows drives are considered remote by df, but we are - # required to build into a directory accessible from windows, so consider - # them local here. - if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.wsl"; then - if $DF $1 | $GREP -q "^[[A-Z]]:"; then - $2 - else - $3 - fi - else - $3 - fi + $3 fi fi ]) diff --git a/make/autoconf/basic_tools.m4 b/make/autoconf/basic_tools.m4 index 01eb233b5e8..47ea9442ff5 100644 --- a/make/autoconf/basic_tools.m4 +++ b/make/autoconf/basic_tools.m4 @@ -97,7 +97,7 @@ AC_DEFUN_ONCE([BASIC_SETUP_FUNDAMENTAL_TOOLS], UTIL_PATH_PROGS(NICE, nice) UTIL_PATH_PROGS(LSB_RELEASE, lsb_release) - UTIL_PATH_PROGS(CMD, [cmd.exe /mnt/c/Windows/System32/cmd.exe]) + UTIL_PATH_PROGS(CMD, cmd.exe, /mnt/c/Windows/System32) ]) ############################################################################### diff --git a/make/autoconf/toolchain.m4 b/make/autoconf/toolchain.m4 index c49de90df13..086b362ac00 100644 --- a/make/autoconf/toolchain.m4 +++ b/make/autoconf/toolchain.m4 @@ -634,7 +634,12 @@ AC_DEFUN([TOOLCHAIN_EXTRACT_LD_VERSION], # There is no specific version flag, but all output starts with a version string. # First line typically looks something like: # Microsoft (R) Incremental Linker Version 12.00.31101.0 + # Reset PATH since it can contain a mix of WSL/linux paths and Windows paths from VS, + # which, in combination with WSLENV, will make the WSL layer complain + old_path="$PATH" + PATH= LINKER_VERSION_STRING=`$LD 2>&1 | $HEAD -n 1 | $TR -d '\r'` + PATH="$old_path" # Extract version number [ LINKER_VERSION_NUMBER=`$ECHO $LINKER_VERSION_STRING | \ $SED -e 's/.* \([0-9][0-9]*\(\.[0-9][0-9]*\)*\).*/\1/'` ] @@ -732,13 +737,23 @@ AC_DEFUN_ONCE([TOOLCHAIN_DETECT_TOOLCHAIN_CORE], UTIL_FIXUP_EXECUTABLE(LD) # Verify that we indeed succeeded with this trick. AC_MSG_CHECKING([if the found link.exe is actually the Visual Studio linker]) + + # Reset PATH since it can contain a mix of WSL/linux paths and Windows paths from VS, + # which, in combination with WSLENV, will make the WSL layer complain + old_path="$PATH" + PATH= + "$LD" --version > /dev/null + if test $? -eq 0 ; then AC_MSG_RESULT([no]) AC_MSG_ERROR([This is the Cygwin link tool. Please check your PATH and rerun configure.]) else AC_MSG_RESULT([yes]) fi + + PATH="$old_path" + LDCXX="$LD" # jaotc being a windows program expects the linker to be supplied with exe suffix. LD_JAOTC="$LD$EXE_SUFFIX" diff --git a/make/autoconf/toolchain_windows.m4 b/make/autoconf/toolchain_windows.m4 index 62e4f288b4b..b7d11d1b40b 100644 --- a/make/autoconf/toolchain_windows.m4 +++ b/make/autoconf/toolchain_windows.m4 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2019, 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 @@ -485,10 +485,9 @@ AC_DEFUN([TOOLCHAIN_SETUP_VISUAL_STUDIO_ENV], fi # Now execute the newly created bat file. - # The | cat is to stop SetEnv.Cmd to mess with system colors on msys. # Change directory so we don't need to mess with Windows paths in redirects. cd $VS_ENV_TMP_DIR - $CMD /c extract-vs-env.bat | $CAT + $CMD /c extract-vs-env.bat > extract-vs-env.log 2>&1 cd $CONFIGURE_START_DIR if test ! -s $VS_ENV_TMP_DIR/set-vs-env.sh; then diff --git a/make/autoconf/util.m4 b/make/autoconf/util.m4 index 1fdb344dff6..3ab9bf5f5f3 100644 --- a/make/autoconf/util.m4 +++ b/make/autoconf/util.m4 @@ -534,7 +534,7 @@ AC_DEFUN([UTIL_SETUP_TOOL], # Otherwise we believe it is a complete path. Use it as it is. AC_MSG_NOTICE([Will use user supplied tool "$tool_command"]) AC_MSG_CHECKING([for $tool_command]) - if test ! -x "$tool_command"; then + if test ! -x "$tool_command" && test ! -x "$tool_command.exe"; then AC_MSG_RESULT([not found]) AC_MSG_ERROR([User supplied tool $1="$tool_command" does not exist or is not executable]) fi diff --git a/make/autoconf/util_windows.m4 b/make/autoconf/util_windows.m4 index 625f360f2f9..bc3cd0ed96a 100644 --- a/make/autoconf/util_windows.m4 +++ b/make/autoconf/util_windows.m4 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2016, 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 @@ -127,10 +127,15 @@ AC_DEFUN([UTIL_MAKE_WINDOWS_SPACE_SAFE_WSL], UTIL_REWRITE_AS_WINDOWS_MIXED_PATH([TOPDIR_windows]) # First convert to Windows path to make input valid for cmd UTIL_REWRITE_AS_WINDOWS_MIXED_PATH([input_path]) + # Reset PATH since it can contain a mix of WSL/linux paths and Windows paths from VS, + # which, in combination with WSLENV, will make the WSL layer complain + old_path="$PATH" + PATH= new_path=`$CMD /c $TOPDIR_windows/make/scripts/windowsShortName.bat "$input_path" \ | $SED -e 's|\r||g' \ | $TR \\\\\\\\ / | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` # Rewrite back to unix style + PATH="$old_path" UTIL_REWRITE_AS_UNIX_PATH([new_path]) fi ]) diff --git a/make/common/MakeBase.gmk b/make/common/MakeBase.gmk index 221e9455960..533405cfd24 100644 --- a/make/common/MakeBase.gmk +++ b/make/common/MakeBase.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2019, 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 @@ -465,8 +465,13 @@ endif # This is normally not needed since we use the FIXPATH prefix for command lines, # but might be needed in certain circumstances. ifeq ($(call isTargetOs, windows), true) - FixPath = \ + ifeq ($(call isBuildOsEnv, windows.wsl), true) + FixPath = \ + $(shell $(WSLPATH) -m $1) + else + FixPath = \ $(shell $(CYGPATH) -m $1) + endif else FixPath = \ $1 diff --git a/make/common/NativeCompilation.gmk b/make/common/NativeCompilation.gmk index 1b30ff9e4f9..118f6c45136 100644 --- a/make/common/NativeCompilation.gmk +++ b/make/common/NativeCompilation.gmk @@ -1049,7 +1049,7 @@ define SetupNativeCompilationBody endif ifeq ($$($1_TYPE), STATIC_LIBRARY) - $1_VARDEPS := $$($1_AR) $$($1_ARFLAGS) $$($1_LIBS) \ + $1_VARDEPS := $$($1_AR) $$(ARFLAGS) $$($1_ARFLAGS) $$($1_LIBS) \ $$($1_EXTRA_LIBS) $1_VARDEPS_FILE := $$(call DependOnVariable, $1_VARDEPS, \ $$($1_OBJECT_DIR)/$$($1_NOSUFFIX).vardeps) @@ -1067,7 +1067,7 @@ define SetupNativeCompilationBody $$(call LogInfo, Building static library $$($1_BASENAME)) $$(call MakeDir, $$($1_OUTPUT_DIR) $$($1_SYMBOLS_DIR)) $$(call ExecuteWithLog, $$($1_OBJECT_DIR)/$$($1_SAFE_NAME)_link, \ - $$($1_AR) $$($1_ARFLAGS) $(AR_OUT_OPTION)$$($1_TARGET) $$($1_ALL_OBJS) \ + $$($1_AR) $$(ARFLAGS) $$($1_ARFLAGS) $(AR_OUT_OPTION)$$($1_TARGET) $$($1_ALL_OBJS) \ $$($1_RES)) ifeq ($(STATIC_BUILD), true) ifeq ($$($1_USE_MAPFILE_FOR_SYMBOLS), true) diff --git a/make/conf/jib-profiles.js b/make/conf/jib-profiles.js index 37042740286..f80382b669d 100644 --- a/make/conf/jib-profiles.js +++ b/make/conf/jib-profiles.js @@ -998,9 +998,11 @@ var getJibProfilesDependencies = function (input, common) { : input.target_platform); var devkit_cross_prefix = ""; - if (input.build_platform != input.target_platform - && input.build_platform != devkit_platform) { - devkit_cross_prefix = input.build_platform + "-to-"; + if (!(input.target_os == "windows" && isWsl(input))) { + if (input.build_platform != input.target_platform + && input.build_platform != devkit_platform) { + devkit_cross_prefix = input.build_platform + "-to-"; + } } var boot_jdk_platform = (input.build_os == "macosx" ? "osx" : input.build_os) From 014095c4ab55c977a6ab5834b798de1937e5c404 Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Thu, 14 May 2020 19:15:39 +0200 Subject: [PATCH 061/143] 8245041: Fix incorrect output order in configure Reviewed-by: erikj --- make/autoconf/boot-jdk.m4 | 3 ++- make/autoconf/lib-tests.m4 | 5 ++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/make/autoconf/boot-jdk.m4 b/make/autoconf/boot-jdk.m4 index dc443815948..593e9df4236 100644 --- a/make/autoconf/boot-jdk.m4 +++ b/make/autoconf/boot-jdk.m4 @@ -392,8 +392,9 @@ AC_DEFUN_ONCE([BOOTJDK_SETUP_BOOT_JDK], JJS="" AC_MSG_NOTICE([Cannot use pandoc without jjs]) ENABLE_PANDOC=false + else + AC_MSG_RESULT(ok) fi - AC_MSG_RESULT(ok) AC_SUBST(JJS) ]) ]) diff --git a/make/autoconf/lib-tests.m4 b/make/autoconf/lib-tests.m4 index b1437024332..4512291a4f0 100644 --- a/make/autoconf/lib-tests.m4 +++ b/make/autoconf/lib-tests.m4 @@ -77,6 +77,8 @@ AC_DEFUN_ONCE([LIB_TESTS_SETUP_JMH], AC_MSG_RESULT([no, error]) AC_MSG_ERROR([$JMH_HOME does not exist or is not a directory]) fi + AC_MSG_RESULT([yes, $JMH_HOME]) + UTIL_FIXUP_PATH([JMH_HOME]) jar_names="jmh-core jmh-generator-annprocess jopt-simple commons-math3" @@ -84,17 +86,14 @@ AC_DEFUN_ONCE([LIB_TESTS_SETUP_JMH], found_jar_files=$($ECHO $(ls $JMH_HOME/$jar-*.jar 2> /dev/null)) if test "x$found_jar_files" = x; then - AC_MSG_RESULT([no]) AC_MSG_ERROR([--with-jmh does not contain $jar-*.jar]) elif ! test -e "$found_jar_files"; then - AC_MSG_RESULT([no]) AC_MSG_ERROR([--with-jmh contain multiple $jar-*.jar: $found_jar_files]) fi found_jar_var_name=found_${jar//-/_} eval $found_jar_var_name='"'$found_jar_files'"' done - AC_MSG_RESULT([yes]) JMH_CORE_JAR=$found_jmh_core JMH_GENERATOR_JAR=$found_jmh_generator_annprocess From 43da9ff24eb79854d1f04dfe6eb30395cfd3b303 Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Thu, 14 May 2020 19:17:11 +0200 Subject: [PATCH 062/143] 8245032: Remove exceptions from compare.sh Reviewed-by: erikj --- make/scripts/compare.sh | 92 +++-------------------------------------- 1 file changed, 5 insertions(+), 87 deletions(-) diff --git a/make/scripts/compare.sh b/make/scripts/compare.sh index e1fd8a3aa63..e1999cedeb0 100644 --- a/make/scripts/compare.sh +++ b/make/scripts/compare.sh @@ -133,30 +133,8 @@ diff_text() { SUFFIX="${THIS_FILE##*.}" NAME="${THIS_FILE##*/}" - TMP=1 + TMP=$($DIFF $THIS_FILE $OTHER_FILE) - if [[ "$THIS_FILE" = *"META-INF/MANIFEST.MF" ]]; then - # Filter out date string, ant version and java version differences. - TMP=$($DIFF $OTHER_FILE $THIS_FILE | \ - $GREP '^[<>]' | \ - $SED -e '/[<>] Ant-Version: Apache Ant .*/d' \ - -e '/[<>] Created-By: .* (Oracle [Corpatin)]*/d' \ - -e '/[<>] [Corpatin]*)/d' \ - -e '/[<>].*[0-9]\{4\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}-b[0-9]\{2\}.*/d') - fi - if test "x$SUFFIX" = "xjava"; then - TMP=$($DIFF $OTHER_FILE $THIS_FILE | \ - $GREP '^[<>]' | \ - $SED -e '/[<>] \* from.*\.idl/d' \ - -e '/[<>] .*[0-9]\{4\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}-b[0-9]\{2\}.*/d' \ - -e '/[<>] .*[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}.*/d' \ - -e '/[<>] \*.*[0-9]\{4\} \(at \)*[0-9][0-9]*:[0-9]\{2\}:[0-9]\{2\}.*/d' \ - -e '/\/\/ Generated from input file.*/d' \ - -e '/\/\/ This file was generated AUTOMATICALLY from a template file.*/d' \ - -e '/\/\/ java GenerateCharacter.*/d') - fi - # Ignore date strings in class files. - # Anonymous lambda classes get randomly assigned counters in their names. if test "x$SUFFIX" = "xclass"; then if [ "$NAME" = "SystemModules\$all.class" ] \ || [ "$NAME" = "SystemModules\$default.class" ]; then @@ -184,42 +162,9 @@ diff_text() { | eval "$MODULES_CLASS_FILTER" > ${THIS_FILE}.javap & wait TMP=$($DIFF ${OTHER_FILE}.javap ${THIS_FILE}.javap) - # To improve performance when large diffs are found, do a rough filtering of classes - # elibeble for these exceptions - elif $GREP -R -e '[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}' \ - -e 'lambda\$[a-zA-Z0-9]*\$[0-9]' ${THIS_FILE} > /dev/null - then - $JAVAP -c -constants -l -p "${OTHER_FILE}" > ${OTHER_FILE}.javap & - $JAVAP -c -constants -l -p "${THIS_FILE}" > ${THIS_FILE}.javap & - wait - TMP=$($DIFF ${OTHER_FILE}.javap ${THIS_FILE}.javap | \ - $GREP '^[<>]' | \ - $SED -e '/[<>].*[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}.*/d' \ - -e '/[<>].*lambda\$[a-zA-Z0-9]*\$[0-9]*/d') fi fi - if test "x$SUFFIX" = "xproperties"; then - # Filter out date string differences. - TMP=$($DIFF $OTHER_FILE $THIS_FILE | \ - $GREP '^[<>]' | \ - $SED -e '/[<>].*[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}.*/d') - fi - if test "x$SUFFIX" = "xhtml"; then - # Some javadoc versions do not put quotes around font size - HTML_FILTER="$SED \ - -e 's///g'" - $CAT $THIS_FILE | eval "$HTML_FILTER" > $THIS_FILE.filtered - $CAT $OTHER_FILE | eval "$HTML_FILTER" > $OTHER_FILE.filtered - TMP=$($DIFF $OTHER_FILE.filtered $THIS_FILE.filtered | \ - $GREP '^[<>]' | \ - $SED -e '/[<>] /d' \ - -e '/[<>] /d' ) - fi - if test "$NAME" = "BenchmarkList"; then - $SORT $THIS_FILE > $THIS_FILE.sorted - $SORT $OTHER_FILE > $OTHER_FILE.sorted - TMP=$($DIFF $THIS_FILE.sorted $OTHER_FILE.sorted) - fi + if test -n "$TMP"; then echo Files $OTHER_FILE and $THIS_FILE differ return 1 @@ -396,7 +341,7 @@ compare_general_files() { ! -name "*.zip" ! -name "*.debuginfo" ! -name "*.dylib" ! -name "jexec" \ ! -name "modules" ! -name "ct.sym" ! -name "*.diz" ! -name "*.dll" \ ! -name "*.cpl" ! -name "*.pdb" ! -name "*.exp" ! -name "*.ilk" \ - ! -name "*.lib" ! -name "*.war" ! -name "*.jmod" ! -name "*.exe" \ + ! -name "*.lib" ! -name "*.jmod" ! -name "*.exe" \ ! -name "*.obj" ! -name "*.o" ! -name "jspawnhelper" ! -name "*.a" \ ! -name "*.tar.gz" ! -name "classes.jsa" ! -name "gtestLauncher" \ ! -name "*.map" \ @@ -412,41 +357,14 @@ compare_general_files() { if [ -e $OTHER_DIR/$f ]; then SUFFIX="${f##*.}" if [ "$(basename $f)" = "release" ]; then - # In release file, ignore differences in change numbers and order - # of modules in list. + # In release file, ignore differences in source rev numbers OTHER_FILE=$WORK_DIR/$f.other THIS_FILE=$WORK_DIR/$f.this $MKDIR -p $(dirname $OTHER_FILE) $MKDIR -p $(dirname $THIS_FILE) - RELEASE_FILTER="$SED \ - -e 's/\:[0-9a-f]\{12,12\}/:CHANGE/g' \ - -e 's/[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}//g' \ - -e 's/^#.*/#COMMENT/g' \ - -e 's/MODULES=/MODULES=\'$'\n/' \ - -e 's/,/\'$'\n/g' \ - | $SORT - " + RELEASE_FILTER="$SED -e 's/SOURCE=".*"/SOURCE=/g'" $CAT $OTHER_DIR/$f | eval "$RELEASE_FILTER" > $OTHER_FILE $CAT $THIS_DIR/$f | eval "$RELEASE_FILTER" > $THIS_FILE - elif [ "x$SUFFIX" = "xhtml" ]; then - # Ignore time stamps in docs files - OTHER_FILE=$WORK_DIR/$f.other - THIS_FILE=$WORK_DIR/$f.this - $MKDIR -p $(dirname $OTHER_FILE) $(dirname $THIS_FILE) - # Older versions of compare might have left soft links with - # these names. - $RM $OTHER_FILE $THIS_FILE - #Note that | doesn't work on mac sed. - HTML_FILTER="$SED \ - -e 's/20[0-9]\{2\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6,7\}//g' \ - -e 's/20[0-9]\{2\}-[0-9]\{2\}-[0-9]\{2\}//g' \ - -e 's/\(-- Generated by javadoc \).*\( --\)/\1(removed)\2/' \ - -e 's/[A-Z][a-z]*, [A-Z][a-z]* [0-9][0-9]*, [0-9]\{4\} [0-9][0-9:]* [AMP]\{2,2\} [A-Z][A-Z]*//' \ - -e 's/from .*\.idl/\.idl/' \ - " - $CAT $OTHER_DIR/$f | eval "$HTML_FILTER" > $OTHER_FILE & - $CAT $THIS_DIR/$f | eval "$HTML_FILTER" > $THIS_FILE & - wait elif [ "$SUFFIX" = "svg" ]; then # GraphViz has non-determinism when generating svg files OTHER_FILE=$WORK_DIR/$f.other From 9a0463165da0c1abbb06a2c82fa775d1f54e53bc Mon Sep 17 00:00:00 2001 From: Alex Menkov Date: Thu, 14 May 2020 10:29:52 -0700 Subject: [PATCH 063/143] 8244973: serviceability/attach/RemovingUnixDomainSocketTest.java fails "stderr was not empty" Reviewed-by: dholmes, sspitsyn --- .../serviceability/attach/RemovingUnixDomainSocketTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/hotspot/jtreg/serviceability/attach/RemovingUnixDomainSocketTest.java b/test/hotspot/jtreg/serviceability/attach/RemovingUnixDomainSocketTest.java index 6ab5cc0149e..950e191d6fa 100644 --- a/test/hotspot/jtreg/serviceability/attach/RemovingUnixDomainSocketTest.java +++ b/test/hotspot/jtreg/serviceability/attach/RemovingUnixDomainSocketTest.java @@ -65,8 +65,8 @@ public class RemovingUnixDomainSocketTest { "jcmd stderr: [" + out.getStderr() + "]\n" + "jcmd exitValue = " + out.getExitValue()); - out.stderrShouldBeEmptyIgnoreVMWarnings() - .stderrShouldBeEmpty(); + out.shouldHaveExitValue(0) + .stderrShouldBeEmptyIgnoreVMWarnings(); } public static void main(String... args) throws Exception { From 95b8e9eaa38bbbe26f48baf09c0b3605b6d53f36 Mon Sep 17 00:00:00 2001 From: Robbin Ehn Date: Thu, 14 May 2020 19:36:51 +0200 Subject: [PATCH 064/143] 8244340: Handshake processing thread lacks yielding Reviewed-by: pchilanomate, dholmes, dcubed --- src/hotspot/share/runtime/handshake.cpp | 151 +++++++++++++++++++----- src/hotspot/share/runtime/handshake.hpp | 10 +- src/hotspot/share/runtime/thread.hpp | 2 +- 3 files changed, 129 insertions(+), 34 deletions(-) diff --git a/src/hotspot/share/runtime/handshake.cpp b/src/hotspot/share/runtime/handshake.cpp index 576c81bde1f..1b02d3671f1 100644 --- a/src/hotspot/share/runtime/handshake.cpp +++ b/src/hotspot/share/runtime/handshake.cpp @@ -63,6 +63,94 @@ public: bool is_direct() { return _is_direct; } }; +// Performing handshakes requires a custom yielding strategy because without it +// there is a clear performance regression vs plain spinning. We keep track of +// when we last saw progress by looking at why each targeted thread has not yet +// completed its handshake. After spinning for a while with no progress we will +// yield, but as long as there is progress, we keep spinning. Thus we avoid +// yielding when there is potential work to be done or the handshake is close +// to being finished. +class HandshakeSpinYield : public StackObj { + private: + jlong _start_time_ns; + jlong _last_spin_start_ns; + jlong _spin_time_ns; + + int _result_count[2][HandshakeState::_number_states]; + int _prev_result_pos; + + int prev_result_pos() { return _prev_result_pos & 0x1; } + int current_result_pos() { return (_prev_result_pos + 1) & 0x1; } + + void wait_raw(jlong now) { + // We start with fine-grained nanosleeping until a millisecond has + // passed, at which point we resort to plain naked_short_sleep. + if (now - _start_time_ns < NANOSECS_PER_MILLISEC) { + os::naked_short_nanosleep(10 * (NANOUNITS / MICROUNITS)); + } else { + os::naked_short_sleep(1); + } + } + + void wait_blocked(JavaThread* self, jlong now) { + ThreadBlockInVM tbivm(self); + wait_raw(now); + } + + bool state_changed() { + for (int i = 0; i < HandshakeState::_number_states; i++) { + if (_result_count[0][i] != _result_count[1][i]) { + return true; + } + } + return false; + } + + void reset_state() { + _prev_result_pos++; + for (int i = 0; i < HandshakeState::_number_states; i++) { + _result_count[current_result_pos()][i] = 0; + } + } + + public: + HandshakeSpinYield(jlong start_time) : + _start_time_ns(start_time), _last_spin_start_ns(start_time), + _spin_time_ns(0), _result_count(), _prev_result_pos(0) { + + const jlong max_spin_time_ns = 100 /* us */ * (NANOUNITS / MICROUNITS); + int free_cpus = os::active_processor_count() - 1; + _spin_time_ns = (5 /* us */ * (NANOUNITS / MICROUNITS)) * free_cpus; // zero on UP + _spin_time_ns = _spin_time_ns > max_spin_time_ns ? max_spin_time_ns : _spin_time_ns; + } + + void add_result(HandshakeState::ProcessResult pr) { + _result_count[current_result_pos()][pr]++; + } + + void process() { + jlong now = os::javaTimeNanos(); + if (state_changed()) { + reset_state(); + // We spin for x amount of time since last state change. + _last_spin_start_ns = now; + return; + } + jlong wait_target = _last_spin_start_ns + _spin_time_ns; + if (wait_target < now) { + // On UP this is always true. + Thread* self = Thread::current(); + if (self->is_Java_thread()) { + wait_blocked((JavaThread*)self, now); + } else { + wait_raw(now); + } + _last_spin_start_ns = os::javaTimeNanos(); + } + reset_state(); + } +}; + class VM_Handshake: public VM_Operation { const jlong _handshake_timeout; public: @@ -81,7 +169,7 @@ class VM_Handshake: public VM_Operation { bool VM_Handshake::handshake_has_timed_out(jlong start_time) { // Check if handshake operation has timed out if (_handshake_timeout > 0) { - return os::elapsed_counter() >= (start_time + _handshake_timeout); + return os::javaTimeNanos() >= (start_time + _handshake_timeout); } return false; } @@ -117,10 +205,7 @@ class VM_HandshakeOneThread: public VM_Handshake { VM_Handshake(op), _target(target) {} void doit() { - jlong start_time_ns = 0; - if (log_is_enabled(Info, handshake)) { - start_time_ns = os::javaTimeNanos(); - } + jlong start_time_ns = os::javaTimeNanos(); ThreadsListHandle tlh; if (tlh.includes(_target)) { @@ -131,13 +216,15 @@ class VM_HandshakeOneThread: public VM_Handshake { } log_trace(handshake)("JavaThread " INTPTR_FORMAT " signaled, begin attempt to process by VMThtread", p2i(_target)); - jlong timeout_start_time = os::elapsed_counter(); - bool by_vm_thread = false; + HandshakeState::ProcessResult pr = HandshakeState::_no_operation; + HandshakeSpinYield hsy(start_time_ns); do { - if (handshake_has_timed_out(timeout_start_time)) { + if (handshake_has_timed_out(start_time_ns)) { handle_timeout(); } - by_vm_thread = _target->handshake_try_process(_op); + pr = _target->handshake_try_process(_op); + hsy.add_result(pr); + hsy.process(); } while (!_op->is_completed()); // This pairs up with the release store in do_handshake(). It prevents future @@ -146,7 +233,7 @@ class VM_HandshakeOneThread: public VM_Handshake { // by the Handshakee. OrderAccess::acquire(); - log_handshake_info(start_time_ns, _op->name(), 1, by_vm_thread ? 1 : 0); + log_handshake_info(start_time_ns, _op->name(), 1, (pr == HandshakeState::_success) ? 1 : 0); } VMOp_Type type() const { return VMOp_HandshakeOneThread; } @@ -159,10 +246,7 @@ class VM_HandshakeAllThreads: public VM_Handshake { VM_HandshakeAllThreads(HandshakeOperation* op) : VM_Handshake(op) {} void doit() { - jlong start_time_ns = 0; - if (log_is_enabled(Info, handshake)) { - start_time_ns = os::javaTimeNanos(); - } + jlong start_time_ns = os::javaTimeNanos(); int handshake_executed_by_vm_thread = 0; JavaThreadIteratorWithHandle jtiwh; @@ -180,10 +264,10 @@ class VM_HandshakeAllThreads: public VM_Handshake { _op->add_target_count(number_of_threads_issued - 1); log_trace(handshake)("Threads signaled, begin processing blocked threads by VMThread"); - const jlong start_time = os::elapsed_counter(); + HandshakeSpinYield hsy(start_time_ns); do { // Check if handshake operation has timed out - if (handshake_has_timed_out(start_time)) { + if (handshake_has_timed_out(start_time_ns)) { handle_timeout(); } @@ -194,10 +278,13 @@ class VM_HandshakeAllThreads: public VM_Handshake { for (JavaThread *thr = jtiwh.next(); thr != NULL; thr = jtiwh.next()) { // A new thread on the ThreadsList will not have an operation, // hence it is skipped in handshake_try_process. - if (thr->handshake_try_process(_op)) { + HandshakeState::ProcessResult pr = thr->handshake_try_process(_op); + if (pr == HandshakeState::_success) { handshake_executed_by_vm_thread++; } + hsy.add_result(pr); } + hsy.process(); } while (!_op->is_completed()); // This pairs up with the release store in do_handshake(). It prevents future @@ -257,10 +344,7 @@ bool Handshake::execute_direct(HandshakeClosure* thread_cl, JavaThread* target) JavaThread* self = JavaThread::current(); HandshakeOperation op(thread_cl, /*is_direct*/ true); - jlong start_time_ns = 0; - if (log_is_enabled(Info, handshake)) { - start_time_ns = os::javaTimeNanos(); - } + jlong start_time_ns = os::javaTimeNanos(); ThreadsListHandle tlh; if (tlh.includes(target)) { @@ -270,14 +354,17 @@ bool Handshake::execute_direct(HandshakeClosure* thread_cl, JavaThread* target) return false; } - bool by_handshaker = false; + HandshakeState::ProcessResult pr = HandshakeState::_no_operation; + HandshakeSpinYield hsy(start_time_ns); while (!op.is_completed()) { - by_handshaker = target->handshake_try_process(&op); + HandshakeState::ProcessResult pr = target->handshake_try_process(&op); + hsy.add_result(pr); // Check for pending handshakes to avoid possible deadlocks where our // target is trying to handshake us. if (SafepointMechanism::should_block(self)) { ThreadBlockInVM tbivm(self); } + hsy.process(); } // This pairs up with the release store in do_handshake(). It prevents future @@ -286,7 +373,7 @@ bool Handshake::execute_direct(HandshakeClosure* thread_cl, JavaThread* target) // by the Handshakee. OrderAccess::acquire(); - log_handshake_info(start_time_ns, op.name(), 1, by_handshaker ? 1 : 0); + log_handshake_info(start_time_ns, op.name(), 1, (pr == HandshakeState::_success) ? 1 : 0); return op.executed(); } @@ -393,22 +480,22 @@ bool HandshakeState::claim_handshake(bool is_direct) { return false; } -bool HandshakeState::try_process(HandshakeOperation* op) { +HandshakeState::ProcessResult HandshakeState::try_process(HandshakeOperation* op) { bool is_direct = op->is_direct(); if (!has_specific_operation(is_direct)){ // JT has already cleared its handshake - return false; + return _no_operation; } if (!possibly_can_process_handshake()) { // JT is observed in an unsafe state, it must notice the handshake itself - return false; + return _not_safe; } // Claim the semaphore if there still an operation to be executed. if (!claim_handshake(is_direct)) { - return false; + return _state_busy; } // Check if the handshake operation is the same as the one we meant to execute. The @@ -416,13 +503,13 @@ bool HandshakeState::try_process(HandshakeOperation* op) { // by another JavaThread might be in progress. if (is_direct && op != _operation_direct) { _processing_sem.signal(); - return false; + return _no_operation; } // If we own the semaphore at this point and while owning the semaphore // can observe a safe state the thread cannot possibly continue without // getting caught by the semaphore. - bool executed = false; + ProcessResult pr = _not_safe; if (can_process_handshake()) { guarantee(!_processing_sem.trywait(), "we should already own the semaphore"); log_trace(handshake)("Processing handshake by %s", Thread::current()->is_VM_thread() ? "VMThread" : "Handshaker"); @@ -431,11 +518,11 @@ bool HandshakeState::try_process(HandshakeOperation* op) { DEBUG_ONLY(_active_handshaker = NULL;) // Disarm after we have executed the operation. clear_handshake(is_direct); - executed = true; + pr = _success; } // Release the thread _processing_sem.signal(); - return executed; + return pr; } diff --git a/src/hotspot/share/runtime/handshake.hpp b/src/hotspot/share/runtime/handshake.hpp index efc2bf5e647..d8621db854f 100644 --- a/src/hotspot/share/runtime/handshake.hpp +++ b/src/hotspot/share/runtime/handshake.hpp @@ -96,7 +96,15 @@ public: process_self_inner(); } } - bool try_process(HandshakeOperation* op); + + enum ProcessResult { + _no_operation = 0, + _not_safe, + _state_busy, + _success, + _number_states + }; + ProcessResult try_process(HandshakeOperation* op); #ifdef ASSERT Thread* _active_handshaker; diff --git a/src/hotspot/share/runtime/thread.hpp b/src/hotspot/share/runtime/thread.hpp index 9903352110e..dd01a61c57c 100644 --- a/src/hotspot/share/runtime/thread.hpp +++ b/src/hotspot/share/runtime/thread.hpp @@ -1360,7 +1360,7 @@ class JavaThread: public Thread { _handshake.process_by_self(); } - bool handshake_try_process(HandshakeOperation* op) { + HandshakeState::ProcessResult handshake_try_process(HandshakeOperation* op) { return _handshake.try_process(op); } From 71cc95e4b1485a2119552406af704c94b176b72e Mon Sep 17 00:00:00 2001 From: Calvin Cheung Date: Thu, 14 May 2020 20:34:18 +0000 Subject: [PATCH 065/143] 8243947: [TESTBUG] hotspot/jtreg:hotspot_appcds_dynamic fails when the JDK doesn't have default CDS archive Generate a default CDS archive when necessary before running AppCDS dynamic tests. Reviewed-by: iklam --- .../jtreg/runtime/cds/appcds/TestCommon.java | 26 +++- .../dynamicArchive/AppendClasspath.java | 4 +- .../dynamicArchive/ArchiveConsistency.java | 2 +- .../appcds/dynamicArchive/ArrayKlasses.java | 7 +- .../ClassResolutionFailure.java | 4 +- .../DynamicArchiveRelocationTest.java | 6 +- .../DynamicArchiveTestBase.java | 66 +++++++--- .../dynamicArchive/DynamicLotsOfClasses.java | 4 +- .../dynamicArchive/ExcludedClasses.java | 4 +- .../appcds/dynamicArchive/HelloDynamic.java | 6 +- .../dynamicArchive/HelloDynamicCustom.java | 4 +- .../HelloDynamicCustomUnload.java | 4 +- .../appcds/dynamicArchive/JITInteraction.java | 4 +- .../appcds/dynamicArchive/LinkClassTest.java | 4 +- .../appcds/dynamicArchive/MainModuleOnly.java | 116 +++++++++--------- .../appcds/dynamicArchive/MethodSorting.java | 4 +- .../appcds/dynamicArchive/MissingArchive.java | 6 +- .../dynamicArchive/NoClassToArchive.java | 14 ++- .../appcds/dynamicArchive/RelativePath.java | 4 +- .../SharedArchiveFileOption.java | 8 +- .../UnsupportedBaseArchive.java | 6 +- .../dynamicArchive/UnusedCPDuringDump.java | 4 +- .../dynamicArchive/WrongTopClasspath.java | 4 +- .../DynamicLoaderConstraintsTest.java | 4 +- test/lib/jdk/test/lib/cds/CDSTestUtils.java | 6 + 25 files changed, 203 insertions(+), 118 deletions(-) diff --git a/test/hotspot/jtreg/runtime/cds/appcds/TestCommon.java b/test/hotspot/jtreg/runtime/cds/appcds/TestCommon.java index 6d79382720d..39ce615ac0e 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/TestCommon.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/TestCommon.java @@ -137,6 +137,22 @@ public class TestCommon extends CDSTestUtils { return createArchive(appJarDir, appJar, classList, suffix); } + /** + * Dump the base archive. The JDK's default class list is used (unless otherwise specified + * in cmdLineSuffix). + */ + public static OutputAnalyzer dumpBaseArchive(String baseArchiveName, String ... cmdLineSuffix) + throws Exception + { + CDSOptions opts = new CDSOptions(); + opts.setArchiveName(baseArchiveName); + opts.addSuffix(cmdLineSuffix); + opts.addSuffix("-Djava.class.path="); + OutputAnalyzer out = CDSTestUtils.createArchive(opts); + CDSTestUtils.checkBaseDump(out); + return out; + } + // Create AppCDS archive using most common args - convenience method public static OutputAnalyzer createArchive(String appJar, String classList[], String... suffix) throws Exception { @@ -158,6 +174,9 @@ public class TestCommon extends CDSTestUtils { // Simulate -Xshare:dump with -XX:ArchiveClassesAtExit. See comments around patchJarForDynamicDump() private static final Class tmp = DynamicDumpHelper.class; + // name of the base archive to be used for dynamic dump + private static String tempBaseArchive = null; + // Create AppCDS archive using appcds options public static OutputAnalyzer createArchive(AppCDSOptions opts) throws Exception { @@ -182,9 +201,14 @@ public class TestCommon extends CDSTestUtils { } if (DYNAMIC_DUMP) { + File baseArchive = null; + if (tempBaseArchive == null || !(new File(tempBaseArchive)).isFile()) { + tempBaseArchive = getNewArchiveName("tempBaseArchive"); + dumpBaseArchive(tempBaseArchive); + } cmd.add("-Xshare:on"); + cmd.add("-XX:SharedArchiveFile=" + tempBaseArchive); cmd.add("-XX:ArchiveClassesAtExit=" + opts.archiveName); - cmd.add("-Xlog:cds"); cmd.add("-Xlog:cds+dynamic"); boolean mainModuleSpecified = false; diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/AppendClasspath.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/AppendClasspath.java index 63ceb817e99..5072a57c930 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/AppendClasspath.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/AppendClasspath.java @@ -29,7 +29,9 @@ * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds * @compile ../test-classes/Hello.java * @compile ../test-classes/HelloMore.java - * @run driver AppendClasspath + * @build sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. AppendClasspath */ import java.io.File; diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/ArchiveConsistency.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/ArchiveConsistency.java index 3b47981fda2..8eef29e1690 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/ArchiveConsistency.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/ArchiveConsistency.java @@ -60,7 +60,7 @@ public class ArchiveConsistency extends DynamicArchiveTestBase { static void testCustomBase() throws Exception { String topArchiveName = getNewArchiveName("top2"); String baseArchiveName = getNewArchiveName("base"); - dumpBaseArchive(baseArchiveName); + TestCommon.dumpBaseArchive(baseArchiveName); doTest(baseArchiveName, topArchiveName); } diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/ArrayKlasses.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/ArrayKlasses.java index 083f82e174c..75ebcfc4b8b 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/ArrayKlasses.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/ArrayKlasses.java @@ -29,9 +29,10 @@ * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds * /test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/test-classes * @build ArrayKlassesApp - * @run driver ClassFileInstaller -jar ArrayKlasses.jar - * ArrayKlassesApp - * @run driver ArrayKlasses + * @build sun.hotspot.WhiteBox + * @run driver ClassFileInstaller -jar ArrayKlasses.jar ArrayKlassesApp + * @run driver ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. ArrayKlasses */ public class ArrayKlasses extends DynamicArchiveTestBase { diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/ClassResolutionFailure.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/ClassResolutionFailure.java index e89a7454da7..5bf97ec44c6 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/ClassResolutionFailure.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/ClassResolutionFailure.java @@ -31,8 +31,10 @@ * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds /test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/test-classes * @build StrConcatApp * @build MissingDependent + * @build sun.hotspot.WhiteBox * @run driver ClassFileInstaller -jar missingDependent.jar MissingDependent - * @run driver ClassResolutionFailure + * @run driver ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. ClassResolutionFailure */ public class ClassResolutionFailure extends DynamicArchiveTestBase { diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/DynamicArchiveRelocationTest.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/DynamicArchiveRelocationTest.java index c17a1b55faf..b178f579583 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/DynamicArchiveRelocationTest.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/DynamicArchiveRelocationTest.java @@ -31,8 +31,10 @@ * @bug 8231610 * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds /test/hotspot/jtreg/runtime/cds/appcds/test-classes * @build Hello + * @build sun.hotspot.WhiteBox * @run driver ClassFileInstaller -jar hello.jar Hello - * @run driver DynamicArchiveRelocationTest + * @run driver ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. DynamicArchiveRelocationTest */ import jdk.test.lib.process.OutputAnalyzer; @@ -93,7 +95,7 @@ public class DynamicArchiveRelocationTest extends DynamicArchiveTestBase { // (1) Dump base archive (static) - OutputAnalyzer out = dumpBaseArchive(baseArchiveName, unlockArg, dumpBaseRelocArg, logArg); + OutputAnalyzer out = TestCommon.dumpBaseArchive(baseArchiveName, unlockArg, dumpBaseRelocArg, logArg); if (dump_base_reloc) { out.shouldContain("ArchiveRelocationMode == 1: always allocate class space at an alternative address"); out.shouldContain("Relocating archive from"); diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/DynamicArchiveTestBase.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/DynamicArchiveTestBase.java index d3208f7a058..f7496b7018c 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/DynamicArchiveTestBase.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/DynamicArchiveTestBase.java @@ -28,6 +28,7 @@ import jdk.test.lib.process.ProcessTools; import jdk.test.lib.cds.CDSOptions; import jdk.test.lib.cds.CDSTestUtils; import jdk.test.lib.cds.CDSTestUtils.Result; +import sun.hotspot.WhiteBox; /** * Base class for test cases in test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/ @@ -35,6 +36,8 @@ import jdk.test.lib.cds.CDSTestUtils.Result; class DynamicArchiveTestBase { private static boolean executedIn_run = false; + private static final WhiteBox WB = WhiteBox.getWhiteBox(); + public static interface DynamicArchiveTest { public void run() throws Exception; } @@ -104,6 +107,9 @@ class DynamicArchiveTestBase { "-XX:ArchiveClassesAtExit=" + topArchiveName); // to allow dynamic archive tests to be run in the "rt-non-cds-mode" cmdLine = TestCommon.concat(cmdLine, "-Xshare:auto"); + if (baseArchiveName == null && isUseSharedSpacesDisabled()) { + baseArchiveName = getTempBaseArchive(); + } if (baseArchiveName != null) { cmdLine = TestCommon.concat(cmdLine, "-XX:SharedArchiveFile=" + baseArchiveName); } @@ -114,6 +120,9 @@ class DynamicArchiveTestBase { public static Result dump2_WB(String baseArchiveName, String topArchiveName, String ... cmdLineSuffix) throws Exception { + if (baseArchiveName == null && isUseSharedSpacesDisabled()) { + baseArchiveName = getTempBaseArchive(); + } return dump2(baseArchiveName, topArchiveName, TestCommon.concat(wbRuntimeArgs(), cmdLineSuffix)); } @@ -131,28 +140,12 @@ class DynamicArchiveTestBase { } /** - * Dump the base archive. The JDK's default class list is used (unless otherwise specified - * in cmdLineSuffix). - */ - public static OutputAnalyzer dumpBaseArchive(String baseArchiveName, String ... cmdLineSuffix) - throws Exception - { - CDSOptions opts = new CDSOptions(); - opts.setArchiveName(baseArchiveName); - opts.addSuffix(cmdLineSuffix); - opts.addSuffix("-Djava.class.path="); - OutputAnalyzer out = CDSTestUtils.createArchive(opts); - CDSTestUtils.checkDump(out); - return out; - } - - /** - * Same as dumpBaseArchive, but also add WhiteBox to the bootcp + * Same as TestCommon.dumpBaseArchive, but also add WhiteBox to the bootcp */ public static void dumpBaseArchive_WB(String baseArchiveName, String ... cmdLineSuffix) throws Exception { - dumpBaseArchive(baseArchiveName, + TestCommon.dumpBaseArchive(baseArchiveName, TestCommon.concat("-Xbootclasspath/a:" + getWhiteBoxJar(), cmdLineSuffix)); } @@ -182,6 +175,9 @@ class DynamicArchiveTestBase { if (baseArchiveName == null && topArchiveName == null) { throw new RuntimeException("Both baseArchiveName and topArchiveName cannot be null at the same time."); } + if (baseArchiveName == null && isUseSharedSpacesDisabled()) { + baseArchiveName = getTempBaseArchive(); + } String archiveFiles = (baseArchiveName == null) ? topArchiveName : (topArchiveName == null) ? baseArchiveName : baseArchiveName + File.pathSeparator + topArchiveName; @@ -198,6 +194,9 @@ class DynamicArchiveTestBase { if (baseArchiveName == null && topArchiveName == null) { throw new RuntimeException("Both baseArchiveName and topArchiveName cannot be null at the same time."); } + if (baseArchiveName == null && isUseSharedSpacesDisabled()) { + baseArchiveName = getTempBaseArchive(); + } String archiveFiles = (baseArchiveName == null) ? topArchiveName : (topArchiveName == null) ? baseArchiveName : baseArchiveName + File.pathSeparator + topArchiveName; @@ -263,4 +262,35 @@ class DynamicArchiveTestBase { dump(topArchiveName, cmdLineSuffix).assertNormalExit(); run(topArchiveName, cmdLineSuffix).assertNormalExit(); } + + private static String tempBaseArchive; + /** + * Return the name of a base archive. + * It will generate one if one doesn't exist. + */ + private static String getTempBaseArchive() throws Exception { + if (tempBaseArchive == null) { + tempBaseArchive = getNewArchiveName("tempBaseArchive"); + TestCommon.dumpBaseArchive(tempBaseArchive); + } + return tempBaseArchive; + } + + /** + * Return true if the UseSharedSpaces flag has been disabled. + * By default, the VM will be started with -Xshare:auto. + * The UseSharedSpaces flag will be disabled by the VM if there's some + * problem in using the default CDS archive. It could happen under some + * situations such as follows: + * - the default CDS archive wasn't generated during build time because + * the JDK was built via cross-compilation on a different platform; + * - the VM under test was started with a different options than the ones + * when the default CDS archive was built. E.g. the VM was started with + * -XX:+UseZGC which implicitly disabled the UseCompressedOoops and the + * UseCompressedClassPointers options. Those "compressed" options were + * enabled when the default CDS archive was built. + */ + private static boolean isUseSharedSpacesDisabled() { + return (WB.getBooleanVMFlag("UseSharedSpaces") == false); + } } diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/DynamicLotsOfClasses.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/DynamicLotsOfClasses.java index c4300097d86..384fdc49c15 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/DynamicLotsOfClasses.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/DynamicLotsOfClasses.java @@ -39,8 +39,8 @@ import java.util.ArrayList; * @build LoadClasses * @build sun.hotspot.WhiteBox * @run driver ClassFileInstaller -jar loadclasses.jar LoadClasses - * @run driver ClassFileInstaller -jar whitebox.jar sun.hotspot.WhiteBox - * @run driver/timeout=500 DynamicLotsOfClasses + * @run driver ClassFileInstaller -jar whitebox.jar sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm/timeout=500 -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:./whitebox.jar DynamicLotsOfClasses */ public class DynamicLotsOfClasses extends DynamicArchiveTestBase { diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/ExcludedClasses.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/ExcludedClasses.java index bc6561e99f0..1b6d29627ad 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/ExcludedClasses.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/ExcludedClasses.java @@ -29,12 +29,14 @@ * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds * /test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/test-classes * @build ExcludedClassesApp + * @build sun.hotspot.WhiteBox * @run driver ClassFileInstaller -jar ExcludedClasses.jar * ExcludedClassesApp * ExcludedClassesApp$NotLinkedSuper * ExcludedClassesApp$NotLinkedChild * ExcludedClassesApp$NotLinkedInterface - * @run driver ExcludedClasses + * @run driver ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. ExcludedClasses */ public class ExcludedClasses extends DynamicArchiveTestBase { diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/HelloDynamic.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/HelloDynamic.java index e95147c4a0e..586c2aab7b5 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/HelloDynamic.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/HelloDynamic.java @@ -28,8 +28,10 @@ * @requires vm.cds * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds /test/hotspot/jtreg/runtime/cds/appcds/test-classes * @build Hello + * @build sun.hotspot.WhiteBox * @run driver ClassFileInstaller -jar hello.jar Hello - * @run driver HelloDynamic + * @run driver ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. HelloDynamic */ public class HelloDynamic extends DynamicArchiveTestBase { @@ -48,7 +50,7 @@ public class HelloDynamic extends DynamicArchiveTestBase { static void testCustomBase() throws Exception { String topArchiveName = getNewArchiveName("top2"); String baseArchiveName = getNewArchiveName("base"); - dumpBaseArchive(baseArchiveName); + TestCommon.dumpBaseArchive(baseArchiveName); doTest(baseArchiveName, topArchiveName); } diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/HelloDynamicCustom.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/HelloDynamicCustom.java index 9f12f80130c..3b57792a56c 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/HelloDynamicCustom.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/HelloDynamicCustom.java @@ -31,8 +31,8 @@ * @build sun.hotspot.WhiteBox * @run driver ClassFileInstaller -jar hello.jar HelloUnload ClassUnloadCommon ClassUnloadCommon$1 ClassUnloadCommon$TestFailure * @run driver ClassFileInstaller -jar hello_custom.jar CustomLoadee - * @run driver ClassFileInstaller -jar WhiteBox.jar sun.hotspot.WhiteBox - * @run driver HelloDynamicCustom + * @run driver ClassFileInstaller -jar WhiteBox.jar sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:./WhiteBox.jar HelloDynamicCustom */ import java.io.File; diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/HelloDynamicCustomUnload.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/HelloDynamicCustomUnload.java index bba552e13f4..69c99f5d953 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/HelloDynamicCustomUnload.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/HelloDynamicCustomUnload.java @@ -34,8 +34,8 @@ * @build sun.hotspot.WhiteBox * @run driver ClassFileInstaller -jar hello.jar HelloUnload ClassUnloadCommon ClassUnloadCommon$1 ClassUnloadCommon$TestFailure * @run driver ClassFileInstaller -jar hello_custom.jar CustomLoadee - * @run driver ClassFileInstaller -jar WhiteBox.jar sun.hotspot.WhiteBox - * @run driver HelloDynamicCustomUnload + * @run driver ClassFileInstaller -jar WhiteBox.jar sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:./WhiteBox.jar HelloDynamicCustomUnload */ import java.io.File; diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/JITInteraction.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/JITInteraction.java index aa433e9da78..5912f87d895 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/JITInteraction.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/JITInteraction.java @@ -29,9 +29,9 @@ * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds /test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/test-classes * @build TestJIT * @build sun.hotspot.WhiteBox - * @run driver ClassFileInstaller -jar WhiteBox.jar sun.hotspot.WhiteBox + * @run driver ClassFileInstaller -jar WhiteBox.jar sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission * @run driver ClassFileInstaller -jar testjit.jar TestJIT - * @run driver JITInteraction + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:./WhiteBox.jar JITInteraction */ public class JITInteraction extends DynamicArchiveTestBase { diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/LinkClassTest.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/LinkClassTest.java index dad46496007..9b2ca6f964f 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/LinkClassTest.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/LinkClassTest.java @@ -30,8 +30,10 @@ * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds * /test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/test-classes * @build LinkClassApp + * @build sun.hotspot.WhiteBox * @run driver ClassFileInstaller -jar link_class_app.jar LinkClassApp Parent Child Parent2 Child2 MyShutdown - * @run driver LinkClassTest + * @run driver ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. LinkClassTest */ public class LinkClassTest extends DynamicArchiveTestBase { diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/MainModuleOnly.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/MainModuleOnly.java index 7b17c50b385..abf285c0503 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/MainModuleOnly.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/MainModuleOnly.java @@ -99,23 +99,23 @@ public class MainModuleOnly extends DynamicArchiveTestBase { // create an archive with both -cp and --module-path in the command line. // Only the class in the modular jar in the --module-path will be archived; // the class in the modular jar in the -cp won't be archived. - dump2(null, topArchiveName, - "-Xlog:cds+dynamic=debug,cds=debug", - "-cp", destJar.toString(), - "--module-path", moduleDir.toString(), - "-m", TEST_MODULE1) - .assertNormalExit(output -> { - output.shouldContain("Buffer-space to target-space delta") - .shouldContain("Written dynamic archive 0x"); - }); - - // run with the archive using the same command line as in dump time. - // The main class should be loaded from the archive. - run2(null, topArchiveName, - "-Xlog:cds+dynamic=debug,cds=debug,class+load=trace", + dump(topArchiveName, + "-Xlog:cds+dynamic=debug,cds=debug", "-cp", destJar.toString(), "--module-path", moduleDir.toString(), "-m", TEST_MODULE1) + .assertNormalExit(output -> { + output.shouldContain("Buffer-space to target-space delta") + .shouldContain("Written dynamic archive 0x"); + }); + + // run with the archive using the same command line as in dump time. + // The main class should be loaded from the archive. + run(topArchiveName, + "-Xlog:cds+dynamic=debug,cds=debug,class+load=trace", + "-cp", destJar.toString(), + "--module-path", moduleDir.toString(), + "-m", TEST_MODULE1) .assertNormalExit(output -> { output.shouldContain("[class,load] com.simple.Main source: shared objects file") .shouldHaveExitValue(0); @@ -124,22 +124,22 @@ public class MainModuleOnly extends DynamicArchiveTestBase { // run with the archive with the main class name inserted before the -m. // The main class name will be picked up before the module name. So the // main class should be loaded from the jar in the -cp. - run2(null, topArchiveName, - "-Xlog:cds+dynamic=debug,cds=debug,class+load=trace", - "-cp", destJar.toString(), - "--module-path", moduleDir.toString(), - MAIN_CLASS, "-m", TEST_MODULE1) + run(topArchiveName, + "-Xlog:cds+dynamic=debug,cds=debug,class+load=trace", + "-cp", destJar.toString(), + "--module-path", moduleDir.toString(), + MAIN_CLASS, "-m", TEST_MODULE1) .assertNormalExit(out -> out.shouldMatch(".class.load. com.simple.Main source:.*com.simple.jar")); // run with the archive with exploded module. Since during dump time, we // only archive classes from the modular jar in the --module-path, the // main class should be loaded from the exploded module directory. - run2(null, topArchiveName, - "-Xlog:cds+dynamic=debug,cds=debug,class+load=trace", - "-cp", destJar.toString(), - "--module-path", MODS_DIR.toString(), - "-m", TEST_MODULE1 + "/" + MAIN_CLASS) + run(topArchiveName, + "-Xlog:cds+dynamic=debug,cds=debug,class+load=trace", + "-cp", destJar.toString(), + "--module-path", MODS_DIR.toString(), + "-m", TEST_MODULE1 + "/" + MAIN_CLASS) .assertNormalExit(out -> { out.shouldMatch(".class.load. com.simple.Main source:.*com.simple") .shouldContain(MODS_DIR.toString()); @@ -148,12 +148,12 @@ public class MainModuleOnly extends DynamicArchiveTestBase { // run with the archive with the --upgrade-module-path option. // CDS will be disabled with this options and the main class will be // loaded from the modular jar. - run2(null, topArchiveName, - "-Xlog:cds+dynamic=debug,cds=debug,class+load=trace", - "-cp", destJar.toString(), - "--upgrade-module-path", moduleDir.toString(), - "--module-path", moduleDir.toString(), - "-m", TEST_MODULE1) + run(topArchiveName, + "-Xlog:cds+dynamic=debug,cds=debug,class+load=trace", + "-cp", destJar.toString(), + "--upgrade-module-path", moduleDir.toString(), + "--module-path", moduleDir.toString(), + "-m", TEST_MODULE1) .assertSilentlyDisabledCDS(out -> { out.shouldHaveExitValue(0) .shouldMatch("CDS is disabled when the.*option is specified") @@ -165,12 +165,12 @@ public class MainModuleOnly extends DynamicArchiveTestBase { // run with the archive with the --limit-modules option. // CDS will be disabled with this options and the main class will be // loaded from the modular jar. - run2(null, topArchiveName, - "-Xlog:cds+dynamic=debug,cds=debug,class+load=trace", - "-cp", destJar.toString(), - "--limit-modules", "java.base," + TEST_MODULE1, - "--module-path", moduleDir.toString(), - "-m", TEST_MODULE1) + run(topArchiveName, + "-Xlog:cds+dynamic=debug,cds=debug,class+load=trace", + "-cp", destJar.toString(), + "--limit-modules", "java.base," + TEST_MODULE1, + "--module-path", moduleDir.toString(), + "-m", TEST_MODULE1) .assertSilentlyDisabledCDS(out -> { out.shouldHaveExitValue(0) .shouldMatch("CDS is disabled when the.*option is specified") @@ -182,12 +182,12 @@ public class MainModuleOnly extends DynamicArchiveTestBase { // run with the archive with the --patch-module option. // CDS will be disabled with this options and the main class will be // loaded from the modular jar. - run2(null, topArchiveName, - "-Xlog:cds+dynamic=debug,cds=debug,class+load=trace", - "-cp", destJar.toString(), - "--patch-module", TEST_MODULE1 + "=" + MODS_DIR.toString(), - "--module-path", moduleDir.toString(), - "-m", TEST_MODULE1) + run(topArchiveName, + "-Xlog:cds+dynamic=debug,cds=debug,class+load=trace", + "-cp", destJar.toString(), + "--patch-module", TEST_MODULE1 + "=" + MODS_DIR.toString(), + "--module-path", moduleDir.toString(), + "-m", TEST_MODULE1) .assertSilentlyDisabledCDS(out -> { out.shouldHaveExitValue(0) .shouldMatch("CDS is disabled when the.*option is specified") @@ -198,21 +198,21 @@ public class MainModuleOnly extends DynamicArchiveTestBase { // run with the archive and the jar with modified timestamp. // It should fail due to timestamp of the jar doesn't match the one // used during dump time. - run2(null, topArchiveName, - "-Xlog:cds+dynamic=debug,cds=debug,class+load=trace", - "-cp", destJar.toString(), - "--module-path", moduleDir.toString(), - "-m", TEST_MODULE1) + run(topArchiveName, + "-Xlog:cds+dynamic=debug,cds=debug,class+load=trace", + "-cp", destJar.toString(), + "--module-path", moduleDir.toString(), + "-m", TEST_MODULE1) .assertAbnormalExit( "A jar file is not the one used while building the shared archive file:"); // create an archive with a non-empty directory in the --module-path. // The dumping process will exit with an error due to non-empty directory // in the --module-path. - dump2(null, topArchiveName, - "-Xlog:cds+dynamic=debug,cds=debug", - "-cp", destJar.toString(), - "--module-path", MODS_DIR.toString(), - "-m", TEST_MODULE1 + "/" + MAIN_CLASS) + dump(topArchiveName, + "-Xlog:cds+dynamic=debug,cds=debug", + "-cp", destJar.toString(), + "--module-path", MODS_DIR.toString(), + "-m", TEST_MODULE1 + "/" + MAIN_CLASS) .assertAbnormalExit(output -> { output.shouldMatch("Error: non-empty directory.*com.simple"); }); @@ -254,12 +254,12 @@ public class MainModuleOnly extends DynamicArchiveTestBase { System.out.println("Caught IOException from Files.copy(). Cannot continue."); return; } - dump2(null, topArchiveName, - "-Xlog:cds+dynamic=debug,cds=debug", - "-cp", destJar.toString(), - "-Xlog:exceptions=trace", - "--module-path", longDirJar.toString(), - "-m", TEST_MODULE1) + dump(topArchiveName, + "-Xlog:cds+dynamic=debug,cds=debug", + "-cp", destJar.toString(), + "-Xlog:exceptions=trace", + "--module-path", longDirJar.toString(), + "-m", TEST_MODULE1) .ifAbnormalExit(output -> { output.shouldMatch("os::stat error.*CDS dump aborted"); }); diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/MethodSorting.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/MethodSorting.java index 3ec6d5cec68..a85b62a6550 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/MethodSorting.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/MethodSorting.java @@ -32,6 +32,7 @@ * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds /test/hotspot/jtreg/runtime/cds/appcds/test-classes * /test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/test-classes * @build MethodSortingApp + * @build sun.hotspot.WhiteBox * @run driver ClassFileInstaller -jar method_sorting.jar * MethodSortingApp * MethodSortingApp$HelloA @@ -44,7 +45,8 @@ * MethodSortingApp$ImplementorA1 * MethodSortingApp$ImplementorB * MethodSortingApp$ImplementorB1 - * @run driver MethodSorting + * @run driver ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. MethodSorting */ public class MethodSorting extends DynamicArchiveTestBase { diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/MissingArchive.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/MissingArchive.java index 460a8bfeef3..3e7829ce544 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/MissingArchive.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/MissingArchive.java @@ -30,9 +30,9 @@ import java.io.File; * @requires vm.cds * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds /test/hotspot/jtreg/runtime/cds/appcds/test-classes * @build GenericTestApp sun.hotspot.WhiteBox - * @run driver ClassFileInstaller -jar WhiteBox.jar sun.hotspot.WhiteBox + * @run driver ClassFileInstaller -jar WhiteBox.jar sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission * @run driver ClassFileInstaller -jar GenericTestApp.jar GenericTestApp - * @run driver MissingArchive + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:./WhiteBox.jar MissingArchive */ public class MissingArchive extends DynamicArchiveTestBase { @@ -56,7 +56,7 @@ public class MissingArchive extends DynamicArchiveTestBase { static void test(String args[]) throws Exception { String topArchiveName = getNewArchiveName("top"); String baseArchiveName = getNewArchiveName("base"); - dumpBaseArchive(baseArchiveName); + TestCommon.dumpBaseArchive(baseArchiveName); String appJar = ClassFileInstaller.getJarPath("GenericTestApp.jar"); String mainClass = "GenericTestApp"; diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/NoClassToArchive.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/NoClassToArchive.java index a8fe1c1f07b..7330837e471 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/NoClassToArchive.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/NoClassToArchive.java @@ -38,8 +38,10 @@ * * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds /test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/test-classes * @build StrConcatApp + * @build sun.hotspot.WhiteBox * @run driver ClassFileInstaller -jar strConcatApp.jar StrConcatApp - * @run driver NoClassToArchive + * @run driver ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. NoClassToArchive */ import java.io.File; @@ -61,7 +63,7 @@ public class NoClassToArchive extends DynamicArchiveTestBase { // (1) Test with default base archive + top archive static void testDefaultBase() throws Exception { String topArchiveName = getNewArchiveName("top"); - doTest(null, topArchiveName); + doTest(topArchiveName); } // (2) Test with custom base archive + top archive @@ -83,15 +85,15 @@ public class NoClassToArchive extends DynamicArchiveTestBase { } } - private static void doTest(String baseArchiveName, String topArchiveName) throws Exception { - dump2(baseArchiveName, topArchiveName, + private static void doTest(String topArchiveName) throws Exception { + dump(topArchiveName, "-Xlog:cds", "-Xlog:cds+dynamic=debug", "-Xlog:class+load=trace", "-version") .assertNormalExit(output -> checkWarning(output)); - dump2(baseArchiveName, topArchiveName, + dump(topArchiveName, "-Xlog:cds", "-Xlog:cds+dynamic=debug", "-Xlog:class+load=trace", @@ -114,7 +116,7 @@ public class NoClassToArchive extends DynamicArchiveTestBase { TestCommon.checkExecReturn(output, 0, true, "length = 0"); // create a custom base archive based on the class list - dumpBaseArchive(baseArchiveName, "-XX:SharedClassListFile=" + classList); + TestCommon.dumpBaseArchive(baseArchiveName, "-XX:SharedClassListFile=" + classList); // create a dynamic archive with the custom base archive // no class should be included in the dynamic archive diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/RelativePath.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/RelativePath.java index 29ebef22ad6..e51ae5f789b 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/RelativePath.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/RelativePath.java @@ -27,9 +27,11 @@ * @summary Test relative paths specified in the -cp. * @requires vm.cds * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds + * @build sun.hotspot.WhiteBox * @compile ../test-classes/Hello.java * @compile ../test-classes/HelloMore.java - * @run driver RelativePath + * @run driver ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. RelativePath */ import java.io.File; diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/SharedArchiveFileOption.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/SharedArchiveFileOption.java index 91da6708cb4..afceb30094f 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/SharedArchiveFileOption.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/SharedArchiveFileOption.java @@ -28,8 +28,10 @@ * @requires vm.cds * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds /test/hotspot/jtreg/runtime/cds/appcds/test-classes * @build Hello + * @build sun.hotspot.WhiteBox * @run driver ClassFileInstaller -jar hello.jar Hello - * @run driver SharedArchiveFileOption + * @run driver ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. SharedArchiveFileOption */ import java.io.File; @@ -44,8 +46,8 @@ public class SharedArchiveFileOption extends DynamicArchiveTestBase { String topArchiveName = getNewArchiveName("top"); String baseArchiveName = getNewArchiveName("base"); baseArchiveName2 = getNewArchiveName("base2"); - dumpBaseArchive(baseArchiveName); - dumpBaseArchive(baseArchiveName2); + TestCommon.dumpBaseArchive(baseArchiveName); + TestCommon.dumpBaseArchive(baseArchiveName2); doTest(baseArchiveName, topArchiveName); } diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/UnsupportedBaseArchive.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/UnsupportedBaseArchive.java index e9fb1cb2612..b6a88007a98 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/UnsupportedBaseArchive.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/UnsupportedBaseArchive.java @@ -34,8 +34,8 @@ import java.nio.file.Paths; * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds /test/hotspot/jtreg/runtime/cds/appcds/test-classes * @compile ../test-classes/Hello.java * @build sun.hotspot.WhiteBox - * @run driver ClassFileInstaller -jar WhiteBox.jar sun.hotspot.WhiteBox - * @run driver UnsupportedBaseArchive + * @run driver ClassFileInstaller -jar WhiteBox.jar sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:./WhiteBox.jar UnsupportedBaseArchive */ public class UnsupportedBaseArchive extends DynamicArchiveTestBase { @@ -103,7 +103,7 @@ public class UnsupportedBaseArchive extends DynamicArchiveTestBase { // create a base archive with the --module-path option buildTestModule(); baseArchiveName = getNewArchiveName("base-with-module"); - dumpBaseArchive(baseArchiveName, + TestCommon.dumpBaseArchive(baseArchiveName, "-cp", srcJar.toString(), "--module-path", moduleDir.toString(), "-m", TEST_MODULE); diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/UnusedCPDuringDump.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/UnusedCPDuringDump.java index f8d7ad45c3e..a6a991dc353 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/UnusedCPDuringDump.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/UnusedCPDuringDump.java @@ -29,8 +29,10 @@ * defined to the PlatformClassLoader and AppClassLoader. * @requires vm.cds * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds + * @build sun.hotspot.WhiteBox * @compile ../test-classes/Hello.java - * @run main/othervm -Dtest.cds.copy.child.stdout=false UnusedCPDuringDump + * @run driver ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Dtest.cds.copy.child.stdout=false -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. UnusedCPDuringDump */ import java.io.File; diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/WrongTopClasspath.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/WrongTopClasspath.java index 4006a0fe6cd..4ec06c56581 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/WrongTopClasspath.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/WrongTopClasspath.java @@ -33,7 +33,7 @@ import java.io.File; * @run driver ClassFileInstaller -jar WhiteBox.jar sun.hotspot.WhiteBox * @run driver ClassFileInstaller -jar GenericTestApp.jar GenericTestApp * @run driver ClassFileInstaller -jar WrongJar.jar GenericTestApp - * @run driver WrongTopClasspath + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:./WhiteBox.jar WrongTopClasspath */ public class WrongTopClasspath extends DynamicArchiveTestBase { @@ -45,7 +45,7 @@ public class WrongTopClasspath extends DynamicArchiveTestBase { static void test(String args[]) throws Exception { String topArchiveName = getNewArchiveName("top"); String baseArchiveName = getNewArchiveName("base"); - dumpBaseArchive(baseArchiveName); + TestCommon.dumpBaseArchive(baseArchiveName); String appJar = ClassFileInstaller.getJarPath("GenericTestApp.jar"); String wrongJar = ClassFileInstaller.getJarPath("WrongJar.jar"); diff --git a/test/hotspot/jtreg/runtime/cds/appcds/loaderConstraints/DynamicLoaderConstraintsTest.java b/test/hotspot/jtreg/runtime/cds/appcds/loaderConstraints/DynamicLoaderConstraintsTest.java index c21d03f461f..b2c7154818b 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/loaderConstraints/DynamicLoaderConstraintsTest.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/loaderConstraints/DynamicLoaderConstraintsTest.java @@ -31,7 +31,9 @@ * /test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive * @modules java.base/jdk.internal.misc * jdk.httpserver - * @run driver DynamicLoaderConstraintsTest + * @build sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. DynamicLoaderConstraintsTest */ import com.sun.net.httpserver.HttpExchange; diff --git a/test/lib/jdk/test/lib/cds/CDSTestUtils.java b/test/lib/jdk/test/lib/cds/CDSTestUtils.java index b8f743d9119..8750db37dab 100644 --- a/test/lib/jdk/test/lib/cds/CDSTestUtils.java +++ b/test/lib/jdk/test/lib/cds/CDSTestUtils.java @@ -283,6 +283,12 @@ public class CDSTestUtils { return output; } + // check result of dumping base archive + public static OutputAnalyzer checkBaseDump(OutputAnalyzer output) throws Exception { + output.shouldContain("Loading classes to share"); + output.shouldHaveExitValue(0); + return output; + } // A commonly used convenience methods to create an archive and check the results // Creates an archive and checks for errors From 8da07d1ae968deb488247b031eb3994ed3cda3fc Mon Sep 17 00:00:00 2001 From: Yumin Qi Date: Thu, 14 May 2020 14:24:55 -0700 Subject: [PATCH 066/143] 8242524: Use different default CDS archives depending on UseCompressOops Reviewed-by: erikj, iklam, ccheung --- make/Images.gmk | 30 +++++++++++++++++++++++++ make/scripts/compare.sh | 2 +- src/hotspot/share/memory/filemap.cpp | 1 + src/hotspot/share/runtime/arguments.cpp | 23 ++++++++++--------- src/hotspot/share/runtime/arguments.hpp | 2 +- 5 files changed, 46 insertions(+), 12 deletions(-) diff --git a/make/Images.gmk b/make/Images.gmk index 36a7e7317a3..1770c0abe88 100644 --- a/make/Images.gmk +++ b/make/Images.gmk @@ -117,8 +117,10 @@ JLINK_JRE_TARGETS := $(jlink_jre) ifeq ($(BUILD_CDS_ARCHIVE), true) ifeq ($(OPENJDK_TARGET_OS), windows) CDS_ARCHIVE := bin/server/classes.jsa + CDS_NOCOOPS_ARCHIVE := bin/server/classes_nocoops.jsa else CDS_ARCHIVE := lib/server/classes.jsa + CDS_NOCOOPS_ARCHIVE := lib/server/classes_nocoops.jsa endif $(eval $(call SetupExecute, gen_cds_archive_jdk, \ @@ -127,6 +129,7 @@ ifeq ($(BUILD_CDS_ARCHIVE), true) OUTPUT_FILE := $(JDK_IMAGE_DIR)/$(CDS_ARCHIVE), \ SUPPORT_DIR := $(SUPPORT_OUTPUTDIR)/images/jdk, \ COMMAND := $(FIXPATH) $(JDK_IMAGE_DIR)/bin/java -Xshare:dump \ + -XX:SharedArchiveFile=$(JDK_IMAGE_DIR)/$(CDS_ARCHIVE) \ -Xmx128M -Xms128M $(LOG_INFO), \ )) @@ -138,10 +141,37 @@ ifeq ($(BUILD_CDS_ARCHIVE), true) OUTPUT_FILE := $(JRE_IMAGE_DIR)/$(CDS_ARCHIVE), \ SUPPORT_DIR := $(SUPPORT_OUTPUTDIR)/images/jre, \ COMMAND := $(FIXPATH) $(JRE_IMAGE_DIR)/bin/java -Xshare:dump \ + -XX:SharedArchiveFile=$(JRE_IMAGE_DIR)/$(CDS_ARCHIVE) \ -Xmx128M -Xms128M $(LOG_INFO), \ )) JRE_TARGETS += $(gen_cds_archive_jre) + + $(eval $(call SetupExecute, gen_cds_nocoops_archive_jdk, \ + WARN := Creating CDS-NOCOOPS archive for jdk image, \ + DEPS := $(jlink_jdk), \ + OUTPUT_FILE := $(JDK_IMAGE_DIR)/$(CDS_NOCOOPS_ARCHIVE), \ + SUPPORT_DIR := $(SUPPORT_OUTPUTDIR)/images/jdk, \ + COMMAND := $(FIXPATH) $(JDK_IMAGE_DIR)/bin/java -Xshare:dump \ + -XX:SharedArchiveFile=$(JDK_IMAGE_DIR)/$(CDS_NOCOOPS_ARCHIVE) \ + -XX:-UseCompressedOops \ + -Xmx128M -Xms128M $(LOG_INFO), \ + )) + + JDK_TARGETS += $(gen_cds_nocoops_archive_jdk) + + $(eval $(call SetupExecute, gen_cds_nocoops_archive_jre, \ + WARN := Creating CDS-NOCOOPS archive for jre image, \ + DEPS := $(jlink_jre), \ + OUTPUT_FILE := $(JRE_IMAGE_DIR)/$(CDS_NOCOOPS_ARCHIVE), \ + SUPPORT_DIR := $(SUPPORT_OUTPUTDIR)/images/jre, \ + COMMAND := $(FIXPATH) $(JRE_IMAGE_DIR)/bin/java -Xshare:dump \ + -XX:SharedArchiveFile=$(JRE_IMAGE_DIR)/$(CDS_NOCOOPS_ARCHIVE) \ + -XX:-UseCompressedOops \ + -Xmx128M -Xms128M $(LOG_INFO), \ + )) + + JRE_TARGETS += $(gen_cds_nocoops_archive_jre) endif ################################################################################ diff --git a/make/scripts/compare.sh b/make/scripts/compare.sh index e1999cedeb0..813e9bead20 100644 --- a/make/scripts/compare.sh +++ b/make/scripts/compare.sh @@ -343,7 +343,7 @@ compare_general_files() { ! -name "*.cpl" ! -name "*.pdb" ! -name "*.exp" ! -name "*.ilk" \ ! -name "*.lib" ! -name "*.jmod" ! -name "*.exe" \ ! -name "*.obj" ! -name "*.o" ! -name "jspawnhelper" ! -name "*.a" \ - ! -name "*.tar.gz" ! -name "classes.jsa" ! -name "gtestLauncher" \ + ! -name "*.tar.gz" ! -name "*.jsa" ! -name "gtestLauncher" \ ! -name "*.map" \ | $GREP -v "./bin/" | $SORT | $FILTER) diff --git a/src/hotspot/share/memory/filemap.cpp b/src/hotspot/share/memory/filemap.cpp index b3d74ed7932..25d4accb459 100644 --- a/src/hotspot/share/memory/filemap.cpp +++ b/src/hotspot/share/memory/filemap.cpp @@ -1069,6 +1069,7 @@ bool FileMapInfo::open_for_read() { } else { _full_path = Arguments::GetSharedDynamicArchivePath(); } + log_info(cds)("trying to map %s", _full_path); int fd = os::open(_full_path, O_RDONLY | O_BINARY, 0); if (fd < 0) { if (errno == ENOENT) { diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index a14276119dd..9f94ca2eb51 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -3519,13 +3519,21 @@ jint Arguments::parse_options_buffer(const char* name, char* buffer, const size_ return status; } -void Arguments::set_shared_spaces_flags() { +jint Arguments::set_shared_spaces_flags_and_archive_paths() { if (DumpSharedSpaces) { if (RequireSharedSpaces) { warning("Cannot dump shared archive while using shared archive"); } UseSharedSpaces = false; } +#if INCLUDE_CDS + // Initialize shared archive paths which could include both base and dynamic archive paths + // This must be after set_ergonomics_flags() called so flag UseCompressedOops is set properly. + if (!init_shared_archive_paths()) { + return JNI_ENOMEM; + } +#endif // INCLUDE_CDS + return JNI_OK; } #if INCLUDE_CDS @@ -3541,7 +3549,8 @@ char* Arguments::get_default_shared_archive_path() { size_t file_sep_len = strlen(os::file_separator()); const size_t len = jvm_path_len + file_sep_len + 20; default_archive_path = NEW_C_HEAP_ARRAY(char, len, mtArguments); - jio_snprintf(default_archive_path, len, "%s%sclasses.jsa", + jio_snprintf(default_archive_path, len, + UseCompressedOops ? "%s%sclasses.jsa": "%s%sclasses_nocoops.jsa", jvm_path, os::file_separator()); return default_archive_path; } @@ -3986,13 +3995,6 @@ jint Arguments::parse(const JavaVMInitArgs* initial_cmd_args) { return result; } -#if INCLUDE_CDS - // Initialize shared archive paths which could include both base and dynamic archive paths - if (!init_shared_archive_paths()) { - return JNI_ENOMEM; - } -#endif - // Delay warning until here so that we've had a chance to process // the -XX:-PrintWarnings flag if (needs_hotspotrc_warning) { @@ -4080,7 +4082,8 @@ jint Arguments::apply_ergo() { GCConfig::arguments()->initialize(); - set_shared_spaces_flags(); + result = set_shared_spaces_flags_and_archive_paths(); + if (result != JNI_OK) return result; // Initialize Metaspace flags and alignments Metaspace::ergo_initialize(); diff --git a/src/hotspot/share/runtime/arguments.hpp b/src/hotspot/share/runtime/arguments.hpp index 047e72e9a26..02a04c4626a 100644 --- a/src/hotspot/share/runtime/arguments.hpp +++ b/src/hotspot/share/runtime/arguments.hpp @@ -370,7 +370,7 @@ class Arguments : AllStatic { static void set_use_compressed_oops(); static void set_use_compressed_klass_ptrs(); static jint set_ergonomics_flags(); - static void set_shared_spaces_flags(); + static jint set_shared_spaces_flags_and_archive_paths(); // limits the given memory size by the maximum amount of memory this process is // currently allowed to allocate or reserve. static julong limit_by_allocatable_memory(julong size); From cab61f1515d9f71a4afe4cf6f1e3d7f9f19c9f1c Mon Sep 17 00:00:00 2001 From: Alex Menkov Date: Thu, 14 May 2020 15:17:45 -0700 Subject: [PATCH 067/143] 8243012: Fix issues in j.l.i package info Reviewed-by: alanb, sspitsyn --- .../java/lang/instrument/package-info.java | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/java.instrument/share/classes/java/lang/instrument/package-info.java b/src/java.instrument/share/classes/java/lang/instrument/package-info.java index aa663e8b70b..7cd34b71c91 100644 --- a/src/java.instrument/share/classes/java/lang/instrument/package-info.java +++ b/src/java.instrument/share/classes/java/lang/instrument/package-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, 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 @@ -32,13 +32,6 @@ * programs running on the JVM. The mechanism for instrumentation is modification * of the byte-codes of methods. * - *

Note: developers/admininstrators are responsible for verifying - * the trustworthiness of content and structure of the Java Agents they deploy, - * since those are able to arbitrarily transform the bytecode from other JAR files. - * Since that happens after the Jars containing the bytecode have been verified - * as trusted, the trustworthiness of a Java Agent can determine the trust towards - * the entire program. - * *

An agent is deployed as a JAR file. An attribute in the JAR file manifest * specifies the agent class which will be loaded to start the agent. Agents can * be started in several ways: @@ -56,8 +49,14 @@ * file.

* * - *

Each of these ways to start an agent is described below. + *

Agents can transform classes in arbitrary ways at load time, transform + * modules, or transform the bytecode of methods of already loaded classes. + * Developers or administrators that deploy agents, deploy applications that + * package an agent with the application, or use tools that load agents into a + * running application, are responsible for verifying the trustworthiness of each + * agent including the content and structure of the agent JAR file. * + *

The three ways to start an agent are described below. * *

Starting an Agent from the Command-Line Interface

* From b883badc47bf66ff4781f65bdd23c42549adf91a Mon Sep 17 00:00:00 2001 From: Mandy Chung Date: Thu, 14 May 2020 17:05:41 -0700 Subject: [PATCH 068/143] 8244961: MethodHandles::privateLookupIn throws NPE when called during initPhase2 Reviewed-by: chegar --- .../share/classes/java/lang/invoke/MethodHandles.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java index ffb491c2bf7..21cc3912593 100644 --- a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java +++ b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java @@ -256,12 +256,12 @@ public class MethodHandles { // M2 != M1, set previous lookup class to M1 and drop MODULE access newPreviousClass = callerClass; newModes &= ~Lookup.MODULE; - } - if (!callerModule.isNamed() && targetModule.isNamed()) { - IllegalAccessLogger logger = IllegalAccessLogger.illegalAccessLogger(); - if (logger != null) { - logger.logIfOpenedForIllegalAccess(caller, targetClass); + if (!callerModule.isNamed() && targetModule.isNamed()) { + IllegalAccessLogger logger = IllegalAccessLogger.illegalAccessLogger(); + if (logger != null) { + logger.logIfOpenedForIllegalAccess(caller, targetClass); + } } } return Lookup.newLookup(targetClass, newPreviousClass, newModes); From 4c54fa2274ab842dbecf72e201d5d5005eb38069 Mon Sep 17 00:00:00 2001 From: Fernando Guallini Date: Fri, 15 May 2020 09:49:54 +0800 Subject: [PATCH 069/143] 8209774: Refactor shell test javax/xml/jaxp/common/8035437/run.sh to java Reviewed-by: dfuchs, joehw, alanb --- .../8035437/AbstractMethodErrorTest.java | 29 +++++-- .../xerces/internal/dom/DocumentImpl.java | 0 .../org/w3c/dom/Document.java | 0 .../{patch-src1 => }/org/w3c/dom/Node.java | 0 test/jdk/javax/xml/jaxp/common/8035437/run.sh | 75 ------------------- 5 files changed, 22 insertions(+), 82 deletions(-) rename test/jdk/javax/xml/jaxp/common/8035437/{patch-src2 => }/com/sun/org/apache/xerces/internal/dom/DocumentImpl.java (100%) rename test/jdk/javax/xml/jaxp/common/8035437/{patch-src1 => }/org/w3c/dom/Document.java (100%) rename test/jdk/javax/xml/jaxp/common/8035437/{patch-src1 => }/org/w3c/dom/Node.java (100%) delete mode 100644 test/jdk/javax/xml/jaxp/common/8035437/run.sh diff --git a/test/jdk/javax/xml/jaxp/common/8035437/AbstractMethodErrorTest.java b/test/jdk/javax/xml/jaxp/common/8035437/AbstractMethodErrorTest.java index 142c468c164..1514b907516 100644 --- a/test/jdk/javax/xml/jaxp/common/8035437/AbstractMethodErrorTest.java +++ b/test/jdk/javax/xml/jaxp/common/8035437/AbstractMethodErrorTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 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 @@ -28,7 +28,26 @@ import org.w3c.dom.Document; import org.w3c.dom.ls.DOMImplementationLS; import org.w3c.dom.ls.LSSerializer; -class AbstractMethodErrorTest { +/* + * @test + * @bug 8035437 + * @summary Verifies that java.lang.AbstractMethodError is not thrown when + * serializing improper version of DocumentImpl class as reported in XERCESJ-1007. + * Test preconditions and steps: + * - Compiles test version of org.w3c.dom.Node and org.w3c.dom.Document + * - Compiles DocumentImpl overriding java.xml module with Node and Document + * - Runs AbstractMethodErrorTest overriding java.xml only with DocumentImpl class + * Hence, the interfaces compiled in the first step need to be removed + * from the test folder in order to reproduce the bug scenario. At the time of writing, + * the clean command was not able to resolve paths generated by compile/module + * @library /test/lib + * @compile --patch-module java.xml=${test.src} org/w3c/dom/Document.java + * org/w3c/dom/Node.java com/sun/org/apache/xerces/internal/dom/DocumentImpl.java + * @clean org.w3c.dom.* + * @run main/othervm --patch-module java.xml=${test.class.path} AbstractMethodErrorTest + */ + +public class AbstractMethodErrorTest { public static void main(String[] args) throws Exception { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); @@ -39,11 +58,7 @@ class AbstractMethodErrorTest { DOMImplementationLS implLS = (DOMImplementationLS) impl.getFeature("LS", "3.0"); LSSerializer dsi = implLS.createLSSerializer(); - /* We should have here incorrect document without getXmlVersion() method: - * Such Document is generated by replacing the JDK bootclasses with it's - * own Node,Document and DocumentImpl classes (see run.sh). According to - * XERCESJ-1007 the AbstractMethodError should be thrown in such case. - */ + // We should have here incorrect document without getXmlVersion() method String result = dsi.writeToString(document); System.out.println("Result:" + result); } diff --git a/test/jdk/javax/xml/jaxp/common/8035437/patch-src2/com/sun/org/apache/xerces/internal/dom/DocumentImpl.java b/test/jdk/javax/xml/jaxp/common/8035437/com/sun/org/apache/xerces/internal/dom/DocumentImpl.java similarity index 100% rename from test/jdk/javax/xml/jaxp/common/8035437/patch-src2/com/sun/org/apache/xerces/internal/dom/DocumentImpl.java rename to test/jdk/javax/xml/jaxp/common/8035437/com/sun/org/apache/xerces/internal/dom/DocumentImpl.java diff --git a/test/jdk/javax/xml/jaxp/common/8035437/patch-src1/org/w3c/dom/Document.java b/test/jdk/javax/xml/jaxp/common/8035437/org/w3c/dom/Document.java similarity index 100% rename from test/jdk/javax/xml/jaxp/common/8035437/patch-src1/org/w3c/dom/Document.java rename to test/jdk/javax/xml/jaxp/common/8035437/org/w3c/dom/Document.java diff --git a/test/jdk/javax/xml/jaxp/common/8035437/patch-src1/org/w3c/dom/Node.java b/test/jdk/javax/xml/jaxp/common/8035437/org/w3c/dom/Node.java similarity index 100% rename from test/jdk/javax/xml/jaxp/common/8035437/patch-src1/org/w3c/dom/Node.java rename to test/jdk/javax/xml/jaxp/common/8035437/org/w3c/dom/Node.java diff --git a/test/jdk/javax/xml/jaxp/common/8035437/run.sh b/test/jdk/javax/xml/jaxp/common/8035437/run.sh deleted file mode 100644 index 9b1d327e6d2..00000000000 --- a/test/jdk/javax/xml/jaxp/common/8035437/run.sh +++ /dev/null @@ -1,75 +0,0 @@ -#!/bin/sh - -## -# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. -# 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 8035437 -# @summary Tests that java.lang.AbstractMethodError is not thrown when -# serializing improper version of DocumentImpl class. - -OS=`uname -s` -case "$OS" in - SunOS ) - PS=":" - ;; - Linux ) - PS=":" - ;; - Darwin ) - PS=":" - ;; - AIX ) - PS=":" - ;; - Windows*) - PS=";" - ;; - CYGWIN*) - PS=";" - ;; - * ) - echo "Unrecognized system!" - exit 1; - ;; -esac - -mkdir -p exec/java.xml compile/java.xml - -$COMPILEJAVA/bin/javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} \ - -d compile/java.xml --patch-module java.xml=$TESTSRC/patch-src1 \ - $TESTSRC/patch-src1/org/w3c/dom/Document.java \ - $TESTSRC/patch-src1/org/w3c/dom/Node.java || exit 1 - -$COMPILEJAVA/bin/javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} \ - -d exec/java.xml --patch-module java.xml=compile/java.xml${PS}$TESTSRC/patch-src2 \ - $TESTSRC/patch-src2/com/sun/org/apache/xerces/internal/dom/DocumentImpl.java \ - || exit 2 - -$COMPILEJAVA/bin/javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} \ - $TESTSRC/AbstractMethodErrorTest.java -d exec || exit 3 - -$TESTJAVA/bin/java ${TESTVMOPTS} --patch-module java.xml=exec -cp exec AbstractMethodErrorTest || exit 4 - -exit 0 - From b76a215ff6088d59012bda82fa26a6c0ce8a8463 Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Fri, 15 May 2020 12:09:59 +0200 Subject: [PATCH 070/143] 8245046: SetupTarget incorrect for hotspot-ide-project Reviewed-by: erikj --- make/Main.gmk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/make/Main.gmk b/make/Main.gmk index 81843478de5..f19622477cd 100644 --- a/make/Main.gmk +++ b/make/Main.gmk @@ -261,7 +261,7 @@ endef $(foreach v, $(JVM_VARIANTS), $(eval $(call DeclareHotspotLibsRecipe,$v))) $(eval $(call SetupTarget, hotspot-ide-project, \ - MAKEFILE := ide/CreateVSProject, \ + MAKEFILE := hotspot/ide/CreateVSProject, \ DEPS := hotspot exploded-image, \ )) From 82f2a0e2e4f45335badf0df4edb51523e2729fba Mon Sep 17 00:00:00 2001 From: Claes Redestad Date: Fri, 15 May 2020 12:25:37 +0200 Subject: [PATCH 071/143] 8245024: Simplify and eagerly initialize StringConcatFactory Reviewed-by: psandoz --- .../share/classes/java/lang/System.java | 17 +- .../java/lang/invoke/StringConcatFactory.java | 164 ++++++++---------- 2 files changed, 88 insertions(+), 93 deletions(-) diff --git a/src/java.base/share/classes/java/lang/System.java b/src/java.base/share/classes/java/lang/System.java index 630e9a2dbd5..7fc959ae1be 100644 --- a/src/java.base/share/classes/java/lang/System.java +++ b/src/java.base/share/classes/java/lang/System.java @@ -37,6 +37,7 @@ import java.io.UnsupportedEncodingException; import java.lang.annotation.Annotation; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodType; +import java.lang.invoke.StringConcatFactory; import java.lang.module.ModuleDescriptor; import java.lang.reflect.Constructor; import java.lang.reflect.Executable; @@ -62,6 +63,7 @@ import java.util.function.Supplier; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Stream; +import jdk.internal.misc.Unsafe; import jdk.internal.util.StaticProperty; import jdk.internal.module.ModuleBootstrap; import jdk.internal.module.ServicesCatalog; @@ -2049,6 +2051,7 @@ public final class System { * @return JNI_OK for success, JNI_ERR for failure */ private static int initPhase2(boolean printToStderr, boolean printStackTrace) { + try { bootLayer = ModuleBootstrap.boot(); } catch (Exception | Error e) { @@ -2065,15 +2068,23 @@ public final class System { /* * Invoked by VM. Phase 3 is the final system initialization: - * 1. set security manager - * 2. set system class loader - * 3. set TCCL + * 1. eagerly initialize bootstrap method factories that might interact + * negatively with custom security managers and custom class loaders + * 2. set security manager + * 3. set system class loader + * 4. set TCCL * * This method must be called after the module system initialization. * The security manager and system class loader may be a custom class from * the application classpath or modulepath. */ private static void initPhase3() { + + // Initialize the StringConcatFactory eagerly to avoid potential + // bootstrap circularity issues that could be caused by a custom + // SecurityManager + Unsafe.getUnsafe().ensureClassInitialized(StringConcatFactory.class); + String smProp = System.getProperty("java.security.manager"); if (smProp != null) { switch (smProp) { diff --git a/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java b/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java index 181e7578e82..9d14352215a 100644 --- a/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java +++ b/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java @@ -129,13 +129,10 @@ public final class StringConcatFactory { /** * Concatenation strategy to use. See {@link Strategy} for possible options. * This option is controllable with -Djava.lang.invoke.stringConcat JDK option. + * + * Defaults to MH_INLINE_SIZED_EXACT if not set. */ - private static Strategy STRATEGY; - - /** - * Default strategy to use for concatenation. - */ - private static final Strategy DEFAULT_STRATEGY = Strategy.MH_INLINE_SIZED_EXACT; + private static final Strategy STRATEGY; private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess(); @@ -182,42 +179,13 @@ public final class StringConcatFactory { */ private static final boolean DEBUG; - /** - * Enables caching of strategy stubs. This may improve the linkage time by reusing the generated - * code, at the expense of contaminating the profiles. - */ - private static final boolean CACHE_ENABLE; - - private static final ConcurrentMap CACHE; - - /** - * Dump generated classes to disk, for debugging purposes. - */ - private static final ProxyClassesDumper DUMPER; - static { - // In case we need to double-back onto the StringConcatFactory during this - // static initialization, make sure we have the reasonable defaults to complete - // the static initialization properly. After that, actual users would use - // the proper values we have read from the properties. - STRATEGY = DEFAULT_STRATEGY; - // CACHE_ENABLE = false; // implied - // CACHE = null; // implied - // DEBUG = false; // implied - // DUMPER = null; // implied - final String strategy = VM.getSavedProperty("java.lang.invoke.stringConcat"); - CACHE_ENABLE = Boolean.parseBoolean( - VM.getSavedProperty("java.lang.invoke.stringConcat.cache")); + STRATEGY = (strategy == null) ? null : Strategy.valueOf(strategy); + DEBUG = Boolean.parseBoolean( VM.getSavedProperty("java.lang.invoke.stringConcat.debug")); - final String dumpPath = - VM.getSavedProperty("java.lang.invoke.stringConcat.dumpClasses"); - - STRATEGY = (strategy == null) ? DEFAULT_STRATEGY : Strategy.valueOf(strategy); - CACHE = CACHE_ENABLE ? new ConcurrentHashMap<>() : null; - DUMPER = (dumpPath == null) ? null : ProxyClassesDumper.getInstance(dumpPath); } /** @@ -260,7 +228,7 @@ public final class StringConcatFactory { } /** - * Parses the recipe string, and produces the traversable collection of + * Parses the recipe string, and produces a traversable collection of * {@link java.lang.invoke.StringConcatFactory.RecipeElement}-s for generator * strategies. Notably, this class parses out the constants from the recipe * and from other static arguments. @@ -668,21 +636,9 @@ public final class StringConcatFactory { MAX_INDY_CONCAT_ARG_SLOTS); } - String className = getClassName(lookup.lookupClass()); MethodType mt = adaptType(concatType); Recipe rec = new Recipe(recipe, constants); - - MethodHandle mh; - if (CACHE_ENABLE) { - Key key = new Key(className, mt, rec); - mh = CACHE.get(key); - if (mh == null) { - mh = generate(lookup, className, mt, rec); - CACHE.put(key, mh); - } - } else { - mh = generate(lookup, className, mt, rec); - } + MethodHandle mh = generate(lookup, mt, rec); return new ConstantCallSite(mh.asType(concatType)); } @@ -714,46 +670,18 @@ public final class StringConcatFactory { : args; } - private static String getClassName(Class hostClass) throws StringConcatException { - /* - The generated class is in the same package as the host class as - it's the implementation of the string concatenation for the host class. - - When cache is enabled, we want to cache as much as we can. - */ - - switch (STRATEGY) { - case BC_SB: - case BC_SB_SIZED: - case BC_SB_SIZED_EXACT: { - if (CACHE_ENABLE) { - String pkgName = hostClass.getPackageName(); - return (!pkgName.isEmpty() ? pkgName.replace('.', '/') + "/" : "") + "Stubs$$StringConcat"; - } else { - String name = hostClass.isHidden() ? hostClass.getName().replace('/', '_') - : hostClass.getName(); - return name.replace('.', '/') + "$$StringConcat"; - } - } - case MH_SB_SIZED: - case MH_SB_SIZED_EXACT: - case MH_INLINE_SIZED_EXACT: - // MethodHandle strategies do not need a class name. - return ""; - default: - throw new StringConcatException("Concatenation strategy " + STRATEGY + " is not implemented"); - } - } - - private static MethodHandle generate(Lookup lookup, String className, MethodType mt, Recipe recipe) throws StringConcatException { + private static MethodHandle generate(Lookup lookup, MethodType mt, Recipe recipe) throws StringConcatException { try { + if (STRATEGY == null) { + return MethodHandleInlineCopyStrategy.generate(mt, recipe); + } switch (STRATEGY) { case BC_SB: - return BytecodeStringBuilderStrategy.generate(lookup, className, mt, recipe, Mode.DEFAULT); + return BytecodeStringBuilderStrategy.generate(lookup, mt, recipe, Mode.DEFAULT); case BC_SB_SIZED: - return BytecodeStringBuilderStrategy.generate(lookup, className, mt, recipe, Mode.SIZED); + return BytecodeStringBuilderStrategy.generate(lookup, mt, recipe, Mode.SIZED); case BC_SB_SIZED_EXACT: - return BytecodeStringBuilderStrategy.generate(lookup, className, mt, recipe, Mode.SIZED_EXACT); + return BytecodeStringBuilderStrategy.generate(lookup, mt, recipe, Mode.SIZED_EXACT); case MH_SB_SIZED: return MethodHandleStringBuilderStrategy.generate(mt, recipe, Mode.SIZED); case MH_SB_SIZED_EXACT: @@ -836,11 +764,45 @@ public final class StringConcatFactory { static final int CLASSFILE_VERSION = 52; static final String METHOD_NAME = "concat"; + private static final ConcurrentMap CACHE; + + /** + * Enables caching of strategy stubs. This may improve the linkage time by reusing the generated + * code, at the expense of contaminating the profiles. + */ + private static final boolean CACHE_ENABLE; + + /** + * Dump generated classes to disk, for debugging purposes. + */ + private static final ProxyClassesDumper DUMPER; + + static { + CACHE_ENABLE = Boolean.parseBoolean( + VM.getSavedProperty("java.lang.invoke.stringConcat.cache")); + CACHE = CACHE_ENABLE ? new ConcurrentHashMap<>() : null; + + final String dumpPath = + VM.getSavedProperty("java.lang.invoke.stringConcat.dumpClasses"); + + DUMPER = (dumpPath == null) ? null : ProxyClassesDumper.getInstance(dumpPath); + } + private BytecodeStringBuilderStrategy() { // no instantiation } - private static MethodHandle generate(Lookup lookup, String className, MethodType args, Recipe recipe, Mode mode) throws Exception { + private static MethodHandle generate(Lookup lookup, MethodType args, Recipe recipe, Mode mode) throws Exception { + String className = getClassName(lookup.lookupClass()); + Key key = null; + if (CACHE_ENABLE) { + key = new Key(className, args, recipe); + MethodHandle mh = CACHE.get(key); + if (mh != null) { + return mh; + } + } + ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES); cw.visit(CLASSFILE_VERSION, @@ -1130,13 +1092,35 @@ public final class StringConcatFactory { try { Class innerClass = lookup.defineHiddenClass(classBytes, true, STRONG).lookupClass(); dumpIfEnabled(className, classBytes); - return lookup.findStatic(innerClass, METHOD_NAME, args); + MethodHandle mh = lookup.findStatic(innerClass, METHOD_NAME, args); + if (CACHE_ENABLE) { + CACHE.put(key, mh); + } + return mh; } catch (Exception e) { dumpIfEnabled(className + "$$FAILED", classBytes); throw new StringConcatException("Exception while spinning the class", e); } } + /** + * The generated class is in the same package as the host class as + * it's the implementation of the string concatenation for the host + * class. + * + * When cache is enabled, we want to cache as much as we can. + */ + private static String getClassName(Class hostClass) { + if (CACHE_ENABLE) { + String pkgName = hostClass.getPackageName(); + return (!pkgName.isEmpty() ? pkgName.replace('.', '/') + "/" : "") + "Stubs$$StringConcat"; + } else { + String name = hostClass.isHidden() ? hostClass.getName().replace('/', '_') + : hostClass.getName(); + return name.replace('.', '/') + "$$StringConcat"; + } + } + private static void dumpIfEnabled(String name, byte[] bytes) { if (DUMPER != null) { DUMPER.dumpClass(name, bytes); @@ -1707,7 +1691,7 @@ public final class StringConcatFactory { private static MethodHandle prepender(String prefix, Class cl, String suffix) { return MethodHandles.insertArguments( MethodHandles.insertArguments( - PREPENDERS.computeIfAbsent(cl, PREPEND),2, prefix), 3, suffix); + PREPENDERS.computeIfAbsent(cl, PREPEND), 2, prefix), 3, suffix); } private static MethodHandle mixer(Class cl) { @@ -1752,7 +1736,7 @@ public final class StringConcatFactory { SIMPLE = JLA.stringConcatHelper("simpleConcat", methodType(String.class, Object.class, Object.class)); NEW_STRING = JLA.stringConcatHelper("newString", methodType(String.class, byte[].class, long.class)); - NEW_ARRAY = JLA.stringConcatHelper( "newArray", methodType(byte[].class, long.class)); + NEW_ARRAY = JLA.stringConcatHelper("newArray", methodType(byte[].class, long.class)); } } From 178e69a3b9a49f5038c809a0bcdb7f91614369b9 Mon Sep 17 00:00:00 2001 From: Rahul Yadav Date: Fri, 15 May 2020 14:46:17 +0100 Subject: [PATCH 072/143] 8244652: Add test for non utf-8 response handling by websocket The test java.net.httpclient.websocket.WSHandshakeExceptionTest.java checks that the websocket client handles invalid utf-8 sent by the websocket server Reviewed-by: dfuchs --- .../websocket/WSHandshakeExceptionTest.java | 54 ++++++++++++++++--- 1 file changed, 48 insertions(+), 6 deletions(-) diff --git a/test/jdk/java/net/httpclient/websocket/WSHandshakeExceptionTest.java b/test/jdk/java/net/httpclient/websocket/WSHandshakeExceptionTest.java index d25d6c8e5ea..44620f63ff4 100644 --- a/test/jdk/java/net/httpclient/websocket/WSHandshakeExceptionTest.java +++ b/test/jdk/java/net/httpclient/websocket/WSHandshakeExceptionTest.java @@ -32,10 +32,17 @@ * @run testng/othervm -Djdk.internal.httpclient.debug=true WSHandshakeExceptionTest */ +import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; import com.sun.net.httpserver.HttpsConfigurator; import com.sun.net.httpserver.HttpsServer; +import com.sun.net.httpserver.HttpExchange; + + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.net.InetAddress; import java.net.http.HttpClient; import java.net.http.WebSocket; @@ -67,6 +74,8 @@ public class WSHandshakeExceptionTest { HttpsServer httpsTestServer; // HTTPS/1.1 String httpURI; String httpsURI; + String httpNonUtf8URI; + String httpsNonUtf8URI; static final int ITERATION_COUNT = 10; // a shared executor helps reduce the amount of threads created by the test @@ -75,10 +84,15 @@ public class WSHandshakeExceptionTest { @DataProvider(name = "variants") public Object[][] variants() { return new Object[][]{ - { httpURI, false }, - { httpsURI, false }, - { httpURI, true }, - { httpsURI, true }, + { httpURI, false }, + { httpsURI, false }, + { httpURI, true }, + { httpsURI, true }, + + { httpNonUtf8URI, true }, + { httpsNonUtf8URI, true }, + { httpNonUtf8URI, false }, + { httpsNonUtf8URI, false } }; } @@ -110,9 +124,20 @@ public class WSHandshakeExceptionTest { } WebSocketHandshakeException wse = (WebSocketHandshakeException) t; assertNotNull(wse.getResponse()); + assertNotNull(wse.getResponse().body()); + assertEquals(wse.getResponse().body().getClass(), String.class); + String body = (String)wse.getResponse().body(); out.println("Status code is " + wse.getResponse().statusCode()); - out.println("Response is " + wse.getResponse().body()); - assertTrue(((String)wse.getResponse().body()).contains("404")); + out.println("Response is " + body); + if(uri.contains("/nonutf8body")) { + // the invalid sequence 0xFF should have been replaced + // by the replacement character (U+FFFD) + assertTrue(body.equals("\ufffd")); + } + else { + // default HttpServer 404 body expected + assertTrue(body.contains("404")); + } assertEquals(wse.getResponse().statusCode(), 404); } } @@ -128,10 +153,14 @@ public class WSHandshakeExceptionTest { InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); httpTestServer = HttpServer.create(sa, 0); httpURI = "ws://localhost:" + httpTestServer.getAddress().getPort() + "/"; + httpNonUtf8URI = "ws://localhost:" + httpTestServer.getAddress().getPort() + "/nonutf8body"; + httpTestServer.createContext("/nonutf8body", new BodyHandler()); httpsTestServer = HttpsServer.create(sa, 0); httpsTestServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); httpsURI = "wss://localhost:" + httpsTestServer.getAddress().getPort() + "/"; + httpsNonUtf8URI = "wss://localhost:" + httpsTestServer.getAddress().getPort() + "/nonutf8body"; + httpsTestServer.createContext("/nonutf8body", new BodyHandler()); httpTestServer.start(); httpsTestServer.start(); @@ -153,4 +182,17 @@ public class WSHandshakeExceptionTest { } return cause; } + + static class BodyHandler implements HttpHandler { + + @Override + public void handle(HttpExchange e) throws IOException { + try(InputStream is = e.getRequestBody(); + OutputStream os = e.getResponseBody()) { + byte[] invalidUtf8 = {(byte)0xFF}; //Invalid utf-8 byte + e.sendResponseHeaders(404, invalidUtf8.length); + os.write(invalidUtf8); + } + } + } } From 3930460af55644a2ba5874cda1615e4aa31909a1 Mon Sep 17 00:00:00 2001 From: Zhengyu Gu Date: Fri, 15 May 2020 10:43:20 -0400 Subject: [PATCH 073/143] 8244953: Shenandoah: gc/shenandoah/TestStringInternCleanup fails with broken string table root Reviewed-by: shade --- .../gc/shenandoah/shenandoahClosures.hpp | 9 +++++++- .../shenandoah/shenandoahClosures.inline.hpp | 7 ++++++ .../share/gc/shenandoah/shenandoahHeap.cpp | 22 +++++++++++++------ .../gc/shenandoah/shenandoahPhaseTimings.cpp | 2 +- .../gc/shenandoah/shenandoahPhaseTimings.hpp | 4 +++- .../share/gc/shenandoah/shenandoahUnload.cpp | 8 +------ 6 files changed, 35 insertions(+), 17 deletions(-) diff --git a/src/hotspot/share/gc/shenandoah/shenandoahClosures.hpp b/src/hotspot/share/gc/shenandoah/shenandoahClosures.hpp index b9735a0b483..f9c0e0175e0 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahClosures.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahClosures.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Red Hat, Inc. All rights reserved. + * Copyright (c) 2019, 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 @@ -26,6 +26,7 @@ #include "memory/iterator.hpp" #include "oops/accessDecorators.hpp" +#include "runtime/handshake.hpp" class ShenandoahHeap; class ShenandoahMarkingContext; @@ -102,6 +103,12 @@ public: inline void do_code_blob(CodeBlob* cb); }; +class ShenandoahRendezvousClosure : public HandshakeClosure { +public: + inline ShenandoahRendezvousClosure(); + inline void do_thread(Thread* thread); +}; + #ifdef ASSERT class ShenandoahAssertNotForwardedClosure : public OopClosure { private: diff --git a/src/hotspot/share/gc/shenandoah/shenandoahClosures.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahClosures.inline.hpp index 14fd869ec8a..93c5a261632 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahClosures.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahClosures.inline.hpp @@ -158,6 +158,13 @@ void ShenandoahCodeBlobAndDisarmClosure::do_code_blob(CodeBlob* cb) { } } +ShenandoahRendezvousClosure::ShenandoahRendezvousClosure() : + HandshakeClosure("ShenandoahRendezvous") { +} + +void ShenandoahRendezvousClosure::do_thread(Thread* thread) { +} + #ifdef ASSERT template void ShenandoahAssertNotForwardedClosure::do_oop_work(T* p) { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp index 333d1575f9b..7c8b86f5a5c 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp @@ -1830,11 +1830,21 @@ public: void ShenandoahHeap::op_weak_roots() { if (is_concurrent_weak_root_in_progress()) { - // Concurrent weak root processing - ShenandoahConcurrentWeakRootsEvacUpdateTask task(ShenandoahPhaseTimings::conc_weak_roots); - workers()->run_task(&task); - if (!ShenandoahConcurrentRoots::should_do_concurrent_class_unloading()) { - set_concurrent_weak_root_in_progress(false); + { + // Concurrent weak root processing + ShenandoahGCWorkerPhase worker_phase(ShenandoahPhaseTimings::conc_weak_roots_work); + ShenandoahConcurrentWeakRootsEvacUpdateTask task(ShenandoahPhaseTimings::conc_weak_roots_work); + workers()->run_task(&task); + if (!ShenandoahConcurrentRoots::should_do_concurrent_class_unloading()) { + set_concurrent_weak_root_in_progress(false); + } + } + + // Perform handshake to flush out dead oops + { + ShenandoahTimingsTracker t(ShenandoahPhaseTimings::conc_weak_roots_rendezvous); + ShenandoahRendezvousClosure cl; + Handshake::execute(&cl); } } } @@ -2866,8 +2876,6 @@ void ShenandoahHeap::entry_weak_roots() { ShenandoahConcurrentPhase gc_phase(msg, ShenandoahPhaseTimings::conc_weak_roots); EventMark em("%s", msg); - ShenandoahGCWorkerPhase worker_phase(ShenandoahPhaseTimings::conc_weak_roots); - ShenandoahWorkerScope scope(workers(), ShenandoahWorkerPolicy::calc_workers_for_conc_root_processing(), "concurrent weak root"); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.cpp b/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.cpp index ddfd1e66737..5f99568e764 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.cpp @@ -107,7 +107,7 @@ bool ShenandoahPhaseTimings::is_worker_phase(Phase phase) { case purge_class_unload: case purge_weak_par: case heap_iteration_roots: - case conc_weak_roots: + case conc_weak_roots_work: case conc_strong_roots: return true; default: diff --git a/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.hpp b/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.hpp index 651c54457d4..185047f402a 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.hpp @@ -91,7 +91,9 @@ class outputStream; SHENANDOAH_PAR_PHASE_DO(evac_, " E: ", f) \ \ f(conc_weak_roots, "Concurrent Weak Roots") \ - SHENANDOAH_PAR_PHASE_DO(conc_weak_roots_, " CWR: ", f) \ + f(conc_weak_roots_work, " Roots") \ + SHENANDOAH_PAR_PHASE_DO(conc_weak_roots_work_, " CWR: ", f) \ + f(conc_weak_roots_rendezvous, " Rendezvous") \ f(conc_cleanup_early, "Concurrent Cleanup") \ f(conc_class_unload, "Concurrent Class Unloading") \ f(conc_class_unload_unlink, " Unlink Stale") \ diff --git a/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp b/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp index 19b59d4cc73..cd1d067616f 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp @@ -136,12 +136,6 @@ void ShenandoahUnload::prepare() { DependencyContext::cleaning_start(); } -class ShenandoahUnloadRendezvousClosure : public HandshakeClosure { -public: - ShenandoahUnloadRendezvousClosure() : HandshakeClosure("ShenandoahUnloadRendezvous") {} - void do_thread(Thread* thread) {} -}; - void ShenandoahUnload::unload() { ShenandoahHeap* heap = ShenandoahHeap::heap(); assert(ShenandoahConcurrentRoots::can_do_concurrent_class_unloading(), "Filtered by caller"); @@ -175,7 +169,7 @@ void ShenandoahUnload::unload() { // Make sure stale metadata and nmethods are no longer observable { ShenandoahTimingsTracker t(ShenandoahPhaseTimings::conc_class_unload_rendezvous); - ShenandoahUnloadRendezvousClosure cl; + ShenandoahRendezvousClosure cl; Handshake::execute(&cl); } From fad2cf51ba2d2d92842f2f8a3d7a9eb23b98a5d9 Mon Sep 17 00:00:00 2001 From: Patrick Concannon Date: Tue, 12 May 2020 21:51:53 +0100 Subject: [PATCH 074/143] 8241072: Reimplement the Legacy DatagramSocket API Replace the underlying implementations of the java.net.DatagramSocket and java.net.MulticastSocket APIs with simpler and more modern implementations that are easy to maintain and debug. Co-authored-by: Alan Bateman Co-authored-by: Chris Hegarty Co-authored-by: Daniel Fuchs Reviewed-by: alanb, chegar, dfuchs --- .../classes/java/net/DatagramSocket.java | 742 +++--------- .../classes/java/net/DatagramSocketImpl.java | 19 + .../classes/java/net/MulticastSocket.java | 294 +---- .../classes/java/net/NetMulticastSocket.java | 1007 +++++++++++++++++ .../sun/nio/ch/DatagramSocketAdaptor.java | 22 +- test/jdk/ProblemList.txt | 4 - .../net/DatagramSocket/AddressNotSet.java | 1 + .../jdk/java/net/DatagramSocket/B6411513.java | 3 + .../net/DatagramSocket/DatagramTimeout.java | 100 +- .../InterruptibleDatagramSocket.java | 2 + .../net/DatagramSocket/ReuseAddressTest.java | 1 + .../java/net/DatagramSocket/SendCheck.java | 3 +- .../java/net/DatagramSocket/SendPortZero.java | 3 +- .../SetGetReceiveBufferSize.java | 1 + .../DatagramSocket/SetGetSendBufferSize.java | 1 + .../net/DatagramSocket/TestAfterClose.java | 2 + .../UnreferencedDatagramSockets.java | 73 +- .../net/DatagramSocketImpl/TestCreate.java | 4 +- test/jdk/java/net/InetAddress/CheckJNI.java | 4 + .../java/net/MulticastSocket/B6427403.java | 2 + .../MulticastSocket/MulticastAddresses.java | 2 + .../NoSetNetworkInterface.java | 1 + .../java/net/MulticastSocket/Promiscuous.java | 1 + .../net/MulticastSocket/SendPortZero.java | 3 +- .../net/MulticastSocket/SetLoopbackMode.java | 3 + .../MulticastSocket/SetLoopbackModeIPv4.java | 2 + .../MulticastSocket/SetLoopbackOption.java | 1 + .../net/MulticastSocket/SetOutgoingIf.java | 1 + .../net/MulticastSocket/SetTTLAndGetTTL.java | 2 + .../java/net/MulticastSocket/SetTTLTo0.java | 2 + .../UnreferencedMulticastSockets.java | 77 +- test/jdk/java/net/Socket/AddressTest.java | 1 + .../jdk/java/net/SocketOption/AfterClose.java | 2 + .../java/net/SocketOption/OptionsTest.java | 1 + 34 files changed, 1478 insertions(+), 909 deletions(-) create mode 100644 src/java.base/share/classes/java/net/NetMulticastSocket.java diff --git a/src/java.base/share/classes/java/net/DatagramSocket.java b/src/java.base/share/classes/java/net/DatagramSocket.java index 6cbaeacce50..070257f789a 100644 --- a/src/java.base/share/classes/java/net/DatagramSocket.java +++ b/src/java.base/share/classes/java/net/DatagramSocket.java @@ -29,10 +29,10 @@ import java.io.IOException; import java.io.UncheckedIOException; import java.nio.channels.DatagramChannel; import java.security.AccessController; -import java.security.PrivilegedExceptionAction; -import java.util.Objects; +import java.security.PrivilegedAction; import java.util.Set; -import java.util.Collections; +import sun.net.NetProperties; +import sun.nio.ch.DefaultSelectorProvider; /** * This class represents a socket for sending and receiving datagram packets. @@ -113,117 +113,27 @@ import java.util.Collections; * @since 1.0 */ public class DatagramSocket implements java.io.Closeable { - /** - * Various states of this socket. - */ - private boolean bound = false; - private boolean closed = false; - private volatile boolean created; - private final Object closeLock = new Object(); - /* - * The implementation of this DatagramSocket. - */ - private final DatagramSocketImpl impl; + // An instance of DatagramSocketAdaptor, NetMulticastSocket, or null + private final DatagramSocket delegate; - /** - * Are we using an older DatagramSocketImpl? - */ - final boolean oldImpl; - - /** - * Set when a socket is ST_CONNECTED until we are certain - * that any packets which might have been received prior - * to calling connect() but not read by the application - * have been read. During this time we check the source - * address of all packets received to be sure they are from - * the connected destination. Other packets are read but - * silently dropped. - */ - private boolean explicitFilter = false; - private int bytesLeftToFilter; - /* - * Connection state: - * ST_NOT_CONNECTED = socket not connected - * ST_CONNECTED = socket connected - * ST_CONNECTED_NO_IMPL = socket connected but not at impl level - */ - static final int ST_NOT_CONNECTED = 0; - static final int ST_CONNECTED = 1; - static final int ST_CONNECTED_NO_IMPL = 2; - - int connectState = ST_NOT_CONNECTED; - - /* - * Connected address & port - */ - InetAddress connectedAddress = null; - int connectedPort = -1; - - /** - * Connects this socket to a remote socket address (IP address + port number). - * Binds socket if not already bound. - * - * @param address The remote address. - * @param port The remote port - * @throws SocketException if binding the socket fails. - */ - private synchronized void connectInternal(InetAddress address, int port) throws SocketException { - if (port < 0 || port > 0xFFFF) { - throw new IllegalArgumentException("connect: " + port); + DatagramSocket delegate() { + if (delegate == null) { + throw new InternalError("Should not get here"); } - if (address == null) { - throw new IllegalArgumentException("connect: null address"); - } - checkAddress (address, "connect"); - if (isClosed()) - return; - SecurityManager security = System.getSecurityManager(); - if (security != null) { - if (address.isMulticastAddress()) { - security.checkMulticast(address); - } else { - security.checkConnect(address.getHostAddress(), port); - security.checkAccept(address.getHostAddress(), port); - } - } - - if (port == 0) { - throw new SocketException("Can't connect to port 0"); - } - if (!isBound()) - bind(new InetSocketAddress(0)); - - // old impls do not support connect/disconnect - if (oldImpl || (impl instanceof AbstractPlainDatagramSocketImpl && - ((AbstractPlainDatagramSocketImpl)impl).nativeConnectDisabled())) { - connectState = ST_CONNECTED_NO_IMPL; - } else { - try { - getImpl().connect(address, port); - - // socket is now connected by the impl - connectState = ST_CONNECTED; - // Do we need to filter some packets? - int avail = getImpl().dataAvailable(); - if (avail == -1) { - throw new SocketException(); - } - explicitFilter = avail > 0; - if (explicitFilter) { - bytesLeftToFilter = getReceiveBufferSize(); - } - } catch (SocketException se) { - - // connection will be emulated by DatagramSocket - connectState = ST_CONNECTED_NO_IMPL; - } - } - - connectedAddress = address; - connectedPort = port; + return delegate; } + /** + * All constructors eventually call this one. + * @param delegate The wrapped DatagramSocket implementation, or null. + */ + DatagramSocket(DatagramSocket delegate) { + assert delegate == null + || delegate instanceof NetMulticastSocket + || delegate instanceof sun.nio.ch.DatagramSocketAdaptor; + this.delegate = delegate; + } /** * Constructs a datagram socket and binds it to any available port @@ -256,10 +166,7 @@ public class DatagramSocket implements java.io.Closeable { * @since 1.4 */ protected DatagramSocket(DatagramSocketImpl impl) { - if (impl == null) - throw new NullPointerException(); - this.impl = impl; - this.oldImpl = checkOldImpl(impl); + this(new NetMulticastSocket(impl)); } /** @@ -286,28 +193,7 @@ public class DatagramSocket implements java.io.Closeable { * @since 1.4 */ public DatagramSocket(SocketAddress bindaddr) throws SocketException { - // Special case initialization for the DatagramChannel socket adaptor. - if (this instanceof sun.nio.ch.DatagramSocketAdaptor) { - this.impl = null; // no DatagramSocketImpl - this.oldImpl = false; - return; - } - - // create a datagram socket. - boolean multicast = (this instanceof MulticastSocket); - this.impl = createImpl(multicast); - // creates the udp socket - impl.create(); - created = true; - this.oldImpl = checkOldImpl(impl); - if (bindaddr != null) { - try { - bind(bindaddr); - } finally { - if (!isBound()) - close(); - } - } + this(createDelegate(bindaddr, DatagramSocket.class)); } /** @@ -362,67 +248,6 @@ public class DatagramSocket implements java.io.Closeable { this(new InetSocketAddress(laddr, port)); } - /** - * Return true if the given DatagramSocketImpl is an "old" impl. An old impl - * is one that doesn't implement the abstract methods added in Java SE 1.4. - */ - private static boolean checkOldImpl(DatagramSocketImpl impl) { - // DatagramSocketImpl.peekData() is a protected method, therefore we need to use - // getDeclaredMethod, therefore we need permission to access the member - try { - AccessController.doPrivileged( - new PrivilegedExceptionAction<>() { - public Void run() throws NoSuchMethodException { - Class[] cl = new Class[1]; - cl[0] = DatagramPacket.class; - impl.getClass().getDeclaredMethod("peekData", cl); - return null; - } - }); - return false; - } catch (java.security.PrivilegedActionException e) { - return true; - } - } - - static Class implClass = null; - - /** - * Creates a DatagramSocketImpl. - * @param multicast true if the DatagramSocketImpl is for a MulticastSocket - */ - private static DatagramSocketImpl createImpl(boolean multicast) throws SocketException { - DatagramSocketImpl impl; - DatagramSocketImplFactory factory = DatagramSocket.factory; - if (factory != null) { - impl = factory.createDatagramSocketImpl(); - } else { - impl = DefaultDatagramSocketImplFactory.createDatagramSocketImpl(multicast); - } - return impl; - } - - /** - * Return the {@code DatagramSocketImpl} attached to this socket, - * creating the socket if not already created. - * - * @return the {@code DatagramSocketImpl} attached to that - * DatagramSocket - * @throws SocketException if creating the socket fails - * @since 1.4 - */ - final DatagramSocketImpl getImpl() throws SocketException { - if (!created) { - synchronized (this) { - if (!created) { - impl.create(); - created = true; - } - } - } - return impl; - } - /** * Binds this DatagramSocket to a specific address and port. *

@@ -438,41 +263,8 @@ public class DatagramSocket implements java.io.Closeable { * not supported by this socket. * @since 1.4 */ - public synchronized void bind(SocketAddress addr) throws SocketException { - if (isClosed()) - throw new SocketException("Socket is closed"); - if (isBound()) - throw new SocketException("already bound"); - if (addr == null) - addr = new InetSocketAddress(0); - if (!(addr instanceof InetSocketAddress)) - throw new IllegalArgumentException("Unsupported address type!"); - InetSocketAddress epoint = (InetSocketAddress) addr; - if (epoint.isUnresolved()) - throw new SocketException("Unresolved address"); - InetAddress iaddr = epoint.getAddress(); - int port = epoint.getPort(); - checkAddress(iaddr, "bind"); - SecurityManager sec = System.getSecurityManager(); - if (sec != null) { - sec.checkListen(port); - } - try { - getImpl().bind(port, iaddr); - } catch (SocketException e) { - getImpl().close(); - throw e; - } - bound = true; - } - - void checkAddress (InetAddress addr, String op) { - if (addr == null) { - return; - } - if (!(addr instanceof Inet4Address || addr instanceof Inet6Address)) { - throw new IllegalArgumentException(op + ": invalid address type"); - } + public void bind(SocketAddress addr) throws SocketException { + delegate().bind(addr); } /** @@ -534,11 +326,7 @@ public class DatagramSocket implements java.io.Closeable { * @since 1.2 */ public void connect(InetAddress address, int port) { - try { - connectInternal(address, port); - } catch (SocketException se) { - throw new UncheckedIOException("connect failed", se); - } + delegate().connect(address, port); } /** @@ -566,14 +354,7 @@ public class DatagramSocket implements java.io.Closeable { * @since 1.4 */ public void connect(SocketAddress addr) throws SocketException { - if (addr == null) - throw new IllegalArgumentException("Address can't be null"); - if (!(addr instanceof InetSocketAddress)) - throw new IllegalArgumentException("Unsupported address type"); - InetSocketAddress epoint = (InetSocketAddress) addr; - if (epoint.isUnresolved()) - throw new SocketException("Unresolved address"); - connectInternal(epoint.getAddress(), epoint.getPort()); + delegate().connect(addr); } /** @@ -594,17 +375,7 @@ public class DatagramSocket implements java.io.Closeable { * @since 1.2 */ public void disconnect() { - synchronized (this) { - if (isClosed()) - return; - if (connectState == ST_CONNECTED) { - impl.disconnect (); - } - connectedAddress = null; - connectedPort = -1; - connectState = ST_NOT_CONNECTED; - explicitFilter = false; - } + delegate().disconnect(); } /** @@ -618,7 +389,7 @@ public class DatagramSocket implements java.io.Closeable { * @since 1.4 */ public boolean isBound() { - return bound; + return delegate().isBound(); } /** @@ -632,7 +403,7 @@ public class DatagramSocket implements java.io.Closeable { * @since 1.4 */ public boolean isConnected() { - return connectState != ST_NOT_CONNECTED; + return delegate().isConnected(); } /** @@ -647,7 +418,7 @@ public class DatagramSocket implements java.io.Closeable { * @since 1.2 */ public InetAddress getInetAddress() { - return connectedAddress; + return delegate().getInetAddress(); } /** @@ -662,7 +433,7 @@ public class DatagramSocket implements java.io.Closeable { * @since 1.2 */ public int getPort() { - return connectedPort; + return delegate().getPort(); } /** @@ -682,9 +453,7 @@ public class DatagramSocket implements java.io.Closeable { * @since 1.4 */ public SocketAddress getRemoteSocketAddress() { - if (!isConnected()) - return null; - return new InetSocketAddress(getInetAddress(), getPort()); + return delegate().getRemoteSocketAddress(); } /** @@ -698,11 +467,7 @@ public class DatagramSocket implements java.io.Closeable { * @since 1.4 */ public SocketAddress getLocalSocketAddress() { - if (isClosed()) - return null; - if (!isBound()) - return null; - return new InetSocketAddress(getLocalAddress(), getLocalPort()); + return delegate().getLocalSocketAddress(); } /** @@ -748,54 +513,7 @@ public class DatagramSocket implements java.io.Closeable { * @spec JSR-51 */ public void send(DatagramPacket p) throws IOException { - synchronized (p) { - if (isClosed()) - throw new SocketException("Socket is closed"); - InetAddress packetAddress = p.getAddress(); - int packetPort = p.getPort(); - checkAddress (packetAddress, "send"); - if (connectState == ST_NOT_CONNECTED) { - if (packetAddress == null) { - throw new IllegalArgumentException("Address not set"); - } - if (packetPort < 0 || packetPort > 0xFFFF) - throw new IllegalArgumentException("port out of range:" + packetPort); - // check the address is ok with the security manager on every send. - SecurityManager security = System.getSecurityManager(); - - // The reason you want to synchronize on datagram packet - // is because you don't want an applet to change the address - // while you are trying to send the packet for example - // after the security check but before the send. - if (security != null) { - if (packetAddress.isMulticastAddress()) { - security.checkMulticast(packetAddress); - } else { - security.checkConnect(packetAddress.getHostAddress(), - packetPort); - } - } - if (packetPort == 0) { - throw new SocketException("Can't send to port 0"); - } - } else { - // we're connected - if (packetAddress == null) { - p.setAddress(connectedAddress); - p.setPort(connectedPort); - } else if ((!packetAddress.equals(connectedAddress)) || - packetPort != connectedPort) { - throw new IllegalArgumentException("connected address " + - "and packet address" + - " differ"); - } - } - // Check whether the socket is bound - if (!isBound()) - bind(new InetSocketAddress(0)); - // call the method to send - getImpl().send(p); - } + delegate().send(p); } /** @@ -831,105 +549,8 @@ public class DatagramSocket implements java.io.Closeable { * @revised 1.4 * @spec JSR-51 */ - public synchronized void receive(DatagramPacket p) throws IOException { - synchronized (p) { - if (!isBound()) - bind(new InetSocketAddress(0)); - if (connectState == ST_NOT_CONNECTED) { - // check the address is ok with the security manager before every recv. - SecurityManager security = System.getSecurityManager(); - if (security != null) { - while(true) { - String peekAd = null; - int peekPort = 0; - // peek at the packet to see who it is from. - if (!oldImpl) { - // We can use the new peekData() API - DatagramPacket peekPacket = new DatagramPacket(new byte[1], 1); - peekPort = getImpl().peekData(peekPacket); - peekAd = peekPacket.getAddress().getHostAddress(); - } else { - InetAddress adr = new InetAddress(); - peekPort = getImpl().peek(adr); - peekAd = adr.getHostAddress(); - } - try { - security.checkAccept(peekAd, peekPort); - // security check succeeded - so now break - // and recv the packet. - break; - } catch (SecurityException se) { - // Throw away the offending packet by consuming - // it in a tmp buffer. - DatagramPacket tmp = new DatagramPacket(new byte[1], 1); - getImpl().receive(tmp); - - // silently discard the offending packet - // and continue: unknown/malicious - // entities on nets should not make - // runtime throw security exception and - // disrupt the applet by sending random - // datagram packets. - continue; - } - } // end of while - } - } - DatagramPacket tmp = null; - if ((connectState == ST_CONNECTED_NO_IMPL) || explicitFilter) { - // We have to do the filtering the old fashioned way since - // the native impl doesn't support connect or the connect - // via the impl failed, or .. "explicitFilter" may be set when - // a socket is connected via the impl, for a period of time - // when packets from other sources might be queued on socket. - boolean stop = false; - while (!stop) { - InetAddress peekAddress = null; - int peekPort = -1; - // peek at the packet to see who it is from. - if (!oldImpl) { - // We can use the new peekData() API - DatagramPacket peekPacket = new DatagramPacket(new byte[1], 1); - peekPort = getImpl().peekData(peekPacket); - peekAddress = peekPacket.getAddress(); - } else { - // this api only works for IPv4 - peekAddress = new InetAddress(); - peekPort = getImpl().peek(peekAddress); - } - if ((!connectedAddress.equals(peekAddress)) || - (connectedPort != peekPort)) { - // throw the packet away and silently continue - tmp = new DatagramPacket( - new byte[1024], 1024); - getImpl().receive(tmp); - if (explicitFilter) { - if (checkFiltering(tmp)) { - stop = true; - } - } - } else { - stop = true; - } - } - } - // If the security check succeeds, or the datagram is - // connected then receive the packet - getImpl().receive(p); - if (explicitFilter && tmp == null) { - // packet was not filtered, account for it here - checkFiltering(p); - } - } - } - - private boolean checkFiltering(DatagramPacket p) throws SocketException { - bytesLeftToFilter -= p.getLength(); - if (bytesLeftToFilter <= 0 || getImpl().dataAvailable() <= 0) { - explicitFilter = false; - return true; - } - return false; + public void receive(DatagramPacket p) throws IOException { + delegate().receive(p); } /** @@ -951,22 +572,7 @@ public class DatagramSocket implements java.io.Closeable { * @since 1.1 */ public InetAddress getLocalAddress() { - if (isClosed()) - return null; - InetAddress in; - try { - in = (InetAddress) getImpl().getOption(SocketOptions.SO_BINDADDR); - if (in.isAnyLocalAddress()) { - in = InetAddress.anyLocalAddress(); - } - SecurityManager s = System.getSecurityManager(); - if (s != null) { - s.checkConnect(in.getHostAddress(), -1); - } - } catch (Exception e) { - in = InetAddress.anyLocalAddress(); // "0.0.0.0" - } - return in; + return delegate().getLocalAddress(); } /** @@ -978,13 +584,7 @@ public class DatagramSocket implements java.io.Closeable { * {@code 0} if it is not bound yet. */ public int getLocalPort() { - if (isClosed()) - return -1; - try { - return getImpl().getLocalPort(); - } catch (Exception e) { - return 0; - } + return delegate().getLocalPort(); } /** @@ -1004,12 +604,8 @@ public class DatagramSocket implements java.io.Closeable { * @since 1.1 * @see #getSoTimeout() */ - public synchronized void setSoTimeout(int timeout) throws SocketException { - if (isClosed()) - throw new SocketException("Socket is closed"); - if (timeout < 0) - throw new IllegalArgumentException("timeout < 0"); - getImpl().setOption(SocketOptions.SO_TIMEOUT, timeout); + public void setSoTimeout(int timeout) throws SocketException { + delegate().setSoTimeout(timeout); } /** @@ -1021,18 +617,8 @@ public class DatagramSocket implements java.io.Closeable { * @since 1.1 * @see #setSoTimeout(int) */ - public synchronized int getSoTimeout() throws SocketException { - if (isClosed()) - throw new SocketException("Socket is closed"); - if (getImpl() == null) - return 0; - Object o = getImpl().getOption(SocketOptions.SO_TIMEOUT); - /* extra type safety */ - if (o instanceof Integer) { - return ((Integer) o).intValue(); - } else { - return 0; - } + public int getSoTimeout() throws SocketException { + return delegate().getSoTimeout(); } /** @@ -1065,13 +651,8 @@ public class DatagramSocket implements java.io.Closeable { * @see #getSendBufferSize() * @since 1.2 */ - public synchronized void setSendBufferSize(int size) throws SocketException { - if (!(size > 0)) { - throw new IllegalArgumentException("negative send size"); - } - if (isClosed()) - throw new SocketException("Socket is closed"); - getImpl().setOption(SocketOptions.SO_SNDBUF, size); + public void setSendBufferSize(int size) throws SocketException { + delegate().setSendBufferSize(size); } /** @@ -1084,15 +665,8 @@ public class DatagramSocket implements java.io.Closeable { * @see #setSendBufferSize * @since 1.2 */ - public synchronized int getSendBufferSize() throws SocketException { - if (isClosed()) - throw new SocketException("Socket is closed"); - int result = 0; - Object o = getImpl().getOption(SocketOptions.SO_SNDBUF); - if (o instanceof Integer) { - result = ((Integer)o).intValue(); - } - return result; + public int getSendBufferSize() throws SocketException { + return delegate().getSendBufferSize(); } /** @@ -1124,13 +698,8 @@ public class DatagramSocket implements java.io.Closeable { * @see #getReceiveBufferSize() * @since 1.2 */ - public synchronized void setReceiveBufferSize(int size) throws SocketException { - if (size <= 0) { - throw new IllegalArgumentException("invalid receive size"); - } - if (isClosed()) - throw new SocketException("Socket is closed"); - getImpl().setOption(SocketOptions.SO_RCVBUF, size); + public void setReceiveBufferSize(int size) throws SocketException { + delegate().setReceiveBufferSize(size); } /** @@ -1142,15 +711,8 @@ public class DatagramSocket implements java.io.Closeable { * @see #setReceiveBufferSize(int) * @since 1.2 */ - public synchronized int getReceiveBufferSize() throws SocketException { - if (isClosed()) - throw new SocketException("Socket is closed"); - int result = 0; - Object o = getImpl().getOption(SocketOptions.SO_RCVBUF); - if (o instanceof Integer) { - result = ((Integer)o).intValue(); - } - return result; + public int getReceiveBufferSize() throws SocketException { + return delegate().getReceiveBufferSize(); } /** @@ -1187,14 +749,8 @@ public class DatagramSocket implements java.io.Closeable { * @see #isBound() * @see #isClosed() */ - public synchronized void setReuseAddress(boolean on) throws SocketException { - if (isClosed()) - throw new SocketException("Socket is closed"); - // Integer instead of Boolean for compatibility with older DatagramSocketImpl - if (oldImpl) - getImpl().setOption(SocketOptions.SO_REUSEADDR, on?-1:0); - else - getImpl().setOption(SocketOptions.SO_REUSEADDR, Boolean.valueOf(on)); + public void setReuseAddress(boolean on) throws SocketException { + delegate().setReuseAddress(on); } /** @@ -1206,11 +762,8 @@ public class DatagramSocket implements java.io.Closeable { * @since 1.4 * @see #setReuseAddress(boolean) */ - public synchronized boolean getReuseAddress() throws SocketException { - if (isClosed()) - throw new SocketException("Socket is closed"); - Object o = getImpl().getOption(SocketOptions.SO_REUSEADDR); - return ((Boolean)o).booleanValue(); + public boolean getReuseAddress() throws SocketException { + return delegate().getReuseAddress(); } /** @@ -1230,10 +783,8 @@ public class DatagramSocket implements java.io.Closeable { * @since 1.4 * @see #getBroadcast() */ - public synchronized void setBroadcast(boolean on) throws SocketException { - if (isClosed()) - throw new SocketException("Socket is closed"); - getImpl().setOption(SocketOptions.SO_BROADCAST, Boolean.valueOf(on)); + public void setBroadcast(boolean on) throws SocketException { + delegate().setBroadcast(on); } /** @@ -1244,10 +795,8 @@ public class DatagramSocket implements java.io.Closeable { * @since 1.4 * @see #setBroadcast(boolean) */ - public synchronized boolean getBroadcast() throws SocketException { - if (isClosed()) - throw new SocketException("Socket is closed"); - return ((Boolean)(getImpl().getOption(SocketOptions.SO_BROADCAST))).booleanValue(); + public boolean getBroadcast() throws SocketException { + return delegate().getBroadcast(); } /** @@ -1287,20 +836,8 @@ public class DatagramSocket implements java.io.Closeable { * @since 1.4 * @see #getTrafficClass */ - public synchronized void setTrafficClass(int tc) throws SocketException { - if (tc < 0 || tc > 255) - throw new IllegalArgumentException("tc is not in range 0 -- 255"); - - if (isClosed()) - throw new SocketException("Socket is closed"); - try { - getImpl().setOption(SocketOptions.IP_TOS, tc); - } catch (SocketException se) { - // not supported if socket already connected - // Solaris returns error in such cases - if(!isConnected()) - throw se; - } + public void setTrafficClass(int tc) throws SocketException { + delegate().setTrafficClass(tc); } /** @@ -1319,10 +856,8 @@ public class DatagramSocket implements java.io.Closeable { * @since 1.4 * @see #setTrafficClass(int) */ - public synchronized int getTrafficClass() throws SocketException { - if (isClosed()) - throw new SocketException("Socket is closed"); - return ((Integer)(getImpl().getOption(SocketOptions.IP_TOS))).intValue(); + public int getTrafficClass() throws SocketException { + return delegate().getTrafficClass(); } /** @@ -1338,12 +873,7 @@ public class DatagramSocket implements java.io.Closeable { * @spec JSR-51 */ public void close() { - synchronized(closeLock) { - if (isClosed()) - return; - impl.close(); - closed = true; - } + delegate().close(); } /** @@ -1353,9 +883,7 @@ public class DatagramSocket implements java.io.Closeable { * @since 1.4 */ public boolean isClosed() { - synchronized(closeLock) { - return closed; - } + return delegate().isClosed(); } /** @@ -1409,7 +937,7 @@ public class DatagramSocket implements java.io.Closeable { */ public static synchronized void setDatagramSocketImplFactory(DatagramSocketImplFactory fac) - throws IOException + throws IOException { if (factory != null) { throw new SocketException("factory already defined"); @@ -1452,10 +980,7 @@ public class DatagramSocket implements java.io.Closeable { public DatagramSocket setOption(SocketOption name, T value) throws IOException { - Objects.requireNonNull(name); - if (isClosed()) - throw new SocketException("Socket is closed"); - getImpl().setOption(name, value); + delegate().setOption(name, value); return this; } @@ -1483,15 +1008,9 @@ public class DatagramSocket implements java.io.Closeable { * @since 9 */ public T getOption(SocketOption name) throws IOException { - Objects.requireNonNull(name); - if (isClosed()) - throw new SocketException("Socket is closed"); - return getImpl().getOption(name); + return delegate().getOption(name); } - private volatile Set> options; - private final Object optionsLock = new Object(); - /** * Returns a set of the socket options supported by this socket. * @@ -1504,22 +1023,117 @@ public class DatagramSocket implements java.io.Closeable { * @since 9 */ public Set> supportedOptions() { - Set> options = this.options; - if (options != null) - return options; - - synchronized (optionsLock) { - options = this.options; - if (options != null) - return options; - - try { - DatagramSocketImpl impl = getImpl(); - options = Collections.unmodifiableSet(impl.supportedOptions()); - } catch (IOException e) { - options = Collections.emptySet(); - } - return this.options = options; - } + return delegate().supportedOptions(); } + + // Temporary solution until JDK-8237352 is addressed + private static final SocketAddress NO_DELEGATE = new SocketAddress() {}; + private static final boolean USE_PLAINDATAGRAMSOCKET = usePlainDatagramSocketImpl(); + + private static boolean usePlainDatagramSocketImpl() { + PrivilegedAction pa = () -> NetProperties.get("jdk.net.usePlainDatagramSocketImpl"); + String s = AccessController.doPrivileged(pa); + return (s != null) && (s.isEmpty() || s.equalsIgnoreCase("true")); + } + + /** + * Best effort to convert an {@link IOException} + * into a {@link SocketException}. + * + * @param e an instance of {@link IOException} + * @return an instance of {@link SocketException} + */ + private static SocketException toSocketException(IOException e) { + if (e instanceof SocketException) + return (SocketException) e; + Throwable cause = e.getCause(); + if (cause instanceof SocketException) + return (SocketException) cause; + SocketException se = new SocketException(e.getMessage()); + se.initCause(e); + return se; + } + + /** + * Creates a delegate for the specific requested {@code type}. This method should + * only be called by {@code DatagramSocket} and {@code MulticastSocket} + * public constructors. + * + * @param bindaddr An address to bind to, or {@code null} if creating an unbound + * socket. + * @param type This is either {@code MulticastSocket.class}, if the delegate needs + * to support joining multicast groups, or {@code DatagramSocket.class}, + * if it doesn't. Typically, this will be {@code DatagramSocket.class} + * when creating a delegate for {@code DatagramSocket}, and + * {@code MulticastSocket.class} when creating a delegate for + * {@code MulticastSocket}. + * @param The target type for which the delegate is created. + * This is either {@code java.net.DatagramSocket} or + * {@code java.net.MulticastSocket}. + * @return {@code null} if {@code bindaddr == NO_DELEGATE}, otherwise returns a + * delegate for the requested {@code type}. + * @throws SocketException if an exception occurs while creating or binding the + * the delegate. + */ + static T createDelegate(SocketAddress bindaddr, Class type) + throws SocketException { + + // Temporary solution until JDK-8237352 is addressed + if (bindaddr == NO_DELEGATE) return null; + + assert type == DatagramSocket.class || type == MulticastSocket.class; + boolean multicast = (type == MulticastSocket.class); + DatagramSocket delegate = null; + boolean initialized = false; + try { + DatagramSocketImplFactory factory = DatagramSocket.factory; + if (USE_PLAINDATAGRAMSOCKET || factory != null) { + // create legacy DatagramSocket delegate + DatagramSocketImpl impl; + if (factory != null) { + impl = factory.createDatagramSocketImpl(); + } else { + impl = DefaultDatagramSocketImplFactory.createDatagramSocketImpl(multicast); + } + delegate = new NetMulticastSocket(impl); + ((NetMulticastSocket) delegate).getImpl(); // ensure impl.create() is called. + } else { + // create NIO adaptor + delegate = DefaultSelectorProvider.get() + .openUninterruptibleDatagramChannel() + .socket(); + } + + if (multicast) { + // set reuseaddress if multicasting + // (must be set before binding) + delegate.setReuseAddress(true); + } + + if (bindaddr != null) { + // bind if needed + delegate.bind(bindaddr); + } + + // enable broadcast if possible + try { + delegate.setBroadcast(true); + } catch (IOException ioe) { + } + + initialized = true; + } catch (IOException ioe) { + throw toSocketException(ioe); + } finally { + // make sure the delegate is closed if anything + // went wrong + if (!initialized && delegate != null) { + delegate.close(); + } + } + @SuppressWarnings("unchecked") + T result = (T) delegate; + return result; + } + } diff --git a/src/java.base/share/classes/java/net/DatagramSocketImpl.java b/src/java.base/share/classes/java/net/DatagramSocketImpl.java index 5e396b2cf66..84c91436f53 100644 --- a/src/java.base/share/classes/java/net/DatagramSocketImpl.java +++ b/src/java.base/share/classes/java/net/DatagramSocketImpl.java @@ -32,6 +32,25 @@ import java.util.Set; /** * Abstract datagram and multicast socket implementation base class. + * + * @implNote Sockets created with the {@code DatagramSocket} and {@code + * MulticastSocket} public constructors historically delegated all socket + * operations to a {@code DatagramSocketImpl} implementation named + * "PlainDatagramSocketImpl". {@code DatagramSocket} and {@code MulticastSocket} + * have since been changed to a new implementation based on {@code DatagramChannel}. + * The JDK continues to ship with the older implementation to allow code to run + * that depends on unspecified behavior that differs between the old and new + * implementations. The old implementation will be used if the Java virtual + * machine is started with the system property {@systemProperty + * jdk.net.usePlainDatagramSocketImpl} set to use the old implementation. It may + * also be set in the JDK's network configuration file, located in {@code + * ${java.home}/conf/net.properties}. The value of the property is the string + * representation of a boolean. If set without a value then it defaults to {@code + * true}, hence running with {@code -Djdk.net.usePlainDatagramSocketImpl} or + * {@code -Djdk.net.usePlainDatagramSocketImpl=true} will configure the Java + * virtual machine to use the old implementation. The property and old + * implementation will be removed in a future version. + * * @author Pavani Diwanji * @since 1.1 */ diff --git a/src/java.base/share/classes/java/net/MulticastSocket.java b/src/java.base/share/classes/java/net/MulticastSocket.java index 18b1fe2af8e..d8ffd9eae71 100644 --- a/src/java.base/share/classes/java/net/MulticastSocket.java +++ b/src/java.base/share/classes/java/net/MulticastSocket.java @@ -28,9 +28,6 @@ package java.net; import java.io.IOException; import java.nio.channels.DatagramChannel; import java.nio.channels.MulticastChannel; -import java.util.Collections; -import java.util.Enumeration; -import java.util.Set; /** * The multicast datagram socket class is useful for sending @@ -135,11 +132,19 @@ import java.util.Set; */ public class MulticastSocket extends DatagramSocket { + @Override + final MulticastSocket delegate() { + return (MulticastSocket) super.delegate(); + } + /** - * Used on some platforms to record if an outgoing interface - * has been set for this socket. + * Create a MulticastSocket that delegates to the given delegate if not null. + * @param delegate the delegate, can be null. */ - private boolean interfaceSet; + MulticastSocket(MulticastSocket delegate) { + super(delegate); + } + /** * Create a multicast socket. @@ -216,44 +221,9 @@ public class MulticastSocket extends DatagramSocket { * @since 1.4 */ public MulticastSocket(SocketAddress bindaddr) throws IOException { - super((SocketAddress) null); - - // No further initialization when this is a DatagramChannel socket adaptor - if (this instanceof sun.nio.ch.DatagramSocketAdaptor) - return; - - // Enable SO_REUSEADDR before binding - setReuseAddress(true); - - if (bindaddr != null) { - try { - bind(bindaddr); - } finally { - if (!isBound()) { - close(); - } - } - } + this(createDelegate(bindaddr, MulticastSocket.class)); } - /** - * The lock on the socket's TTL. This is for set/getTTL and - * send(packet,ttl). - */ - private Object ttlLock = new Object(); - - /** - * The lock on the socket's interface - used by setInterface - * and getInterface - */ - private Object infLock = new Object(); - - /** - * The "last" interface set by setInterface on this MulticastSocket - */ - private InetAddress infAddress = null; - - /** * Set the default time-to-live for multicast packets sent out * on this {@code MulticastSocket} in order to control the @@ -271,9 +241,7 @@ public class MulticastSocket extends DatagramSocket { */ @Deprecated public void setTTL(byte ttl) throws IOException { - if (isClosed()) - throw new SocketException("Socket is closed"); - getImpl().setTTL(ttl); + delegate().setTTL(ttl); } /** @@ -297,12 +265,7 @@ public class MulticastSocket extends DatagramSocket { * @since 1.2 */ public void setTimeToLive(int ttl) throws IOException { - if (ttl < 0 || ttl > 255) { - throw new IllegalArgumentException("ttl out of range"); - } - if (isClosed()) - throw new SocketException("Socket is closed"); - getImpl().setTimeToLive(ttl); + delegate().setTimeToLive(ttl); } /** @@ -318,9 +281,7 @@ public class MulticastSocket extends DatagramSocket { */ @Deprecated public byte getTTL() throws IOException { - if (isClosed()) - throw new SocketException("Socket is closed"); - return getImpl().getTTL(); + return delegate().getTTL(); } /** @@ -333,9 +294,7 @@ public class MulticastSocket extends DatagramSocket { * @since 1.2 */ public int getTimeToLive() throws IOException { - if (isClosed()) - throw new SocketException("Socket is closed"); - return getImpl().getTimeToLive(); + return delegate().getTimeToLive(); } /** @@ -359,31 +318,7 @@ public class MulticastSocket extends DatagramSocket { */ @Deprecated(since="14") public void joinGroup(InetAddress mcastaddr) throws IOException { - if (isClosed()) { - throw new SocketException("Socket is closed"); - } - - checkAddress(mcastaddr, "joinGroup"); - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkMulticast(mcastaddr); - } - - if (!mcastaddr.isMulticastAddress()) { - throw new SocketException("Not a multicast address"); - } - - /** - * required for some platforms where it's not possible to join - * a group without setting the interface first. - */ - NetworkInterface defaultInterface = NetworkInterface.getDefault(); - - if (!interfaceSet && defaultInterface != null) { - setNetworkInterface(defaultInterface); - } - - getImpl().join(mcastaddr); + delegate().joinGroup(mcastaddr); } /** @@ -406,21 +341,7 @@ public class MulticastSocket extends DatagramSocket { */ @Deprecated(since="14") public void leaveGroup(InetAddress mcastaddr) throws IOException { - if (isClosed()) { - throw new SocketException("Socket is closed"); - } - - checkAddress(mcastaddr, "leaveGroup"); - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkMulticast(mcastaddr); - } - - if (!mcastaddr.isMulticastAddress()) { - throw new SocketException("Not a multicast address"); - } - - getImpl().leave(mcastaddr); + delegate().leaveGroup(mcastaddr); } /** @@ -452,26 +373,7 @@ public class MulticastSocket extends DatagramSocket { */ public void joinGroup(SocketAddress mcastaddr, NetworkInterface netIf) throws IOException { - if (isClosed()) - throw new SocketException("Socket is closed"); - - if (mcastaddr == null || !(mcastaddr instanceof InetSocketAddress)) - throw new IllegalArgumentException("Unsupported address type"); - - if (oldImpl) - throw new UnsupportedOperationException(); - - checkAddress(((InetSocketAddress)mcastaddr).getAddress(), "joinGroup"); - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkMulticast(((InetSocketAddress)mcastaddr).getAddress()); - } - - if (!((InetSocketAddress)mcastaddr).getAddress().isMulticastAddress()) { - throw new SocketException("Not a multicast address"); - } - - getImpl().joinGroup(mcastaddr, netIf); + delegate().joinGroup(mcastaddr, netIf); } /** @@ -500,26 +402,7 @@ public class MulticastSocket extends DatagramSocket { */ public void leaveGroup(SocketAddress mcastaddr, NetworkInterface netIf) throws IOException { - if (isClosed()) - throw new SocketException("Socket is closed"); - - if (mcastaddr == null || !(mcastaddr instanceof InetSocketAddress)) - throw new IllegalArgumentException("Unsupported address type"); - - if (oldImpl) - throw new UnsupportedOperationException(); - - checkAddress(((InetSocketAddress)mcastaddr).getAddress(), "leaveGroup"); - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkMulticast(((InetSocketAddress)mcastaddr).getAddress()); - } - - if (!((InetSocketAddress)mcastaddr).getAddress().isMulticastAddress()) { - throw new SocketException("Not a multicast address"); - } - - getImpl().leaveGroup(mcastaddr, netIf); + delegate().leaveGroup(mcastaddr, netIf); } /** @@ -537,15 +420,7 @@ public class MulticastSocket extends DatagramSocket { */ @Deprecated(since="14") public void setInterface(InetAddress inf) throws SocketException { - if (isClosed()) { - throw new SocketException("Socket is closed"); - } - checkAddress(inf, "setInterface"); - synchronized (infLock) { - getImpl().setOption(SocketOptions.IP_MULTICAST_IF, inf); - infAddress = inf; - interfaceSet = true; - } + delegate().setInterface(inf); } /** @@ -565,53 +440,7 @@ public class MulticastSocket extends DatagramSocket { */ @Deprecated(since="14") public InetAddress getInterface() throws SocketException { - if (isClosed()) { - throw new SocketException("Socket is closed"); - } - synchronized (infLock) { - InetAddress ia = - (InetAddress)getImpl().getOption(SocketOptions.IP_MULTICAST_IF); - - /** - * No previous setInterface or interface can be - * set using setNetworkInterface - */ - if (infAddress == null) { - return ia; - } - - /** - * Same interface set with setInterface? - */ - if (ia.equals(infAddress)) { - return ia; - } - - /** - * Different InetAddress from what we set with setInterface - * so enumerate the current interface to see if the - * address set by setInterface is bound to this interface. - */ - try { - NetworkInterface ni = NetworkInterface.getByInetAddress(ia); - Enumeration addrs = ni.getInetAddresses(); - while (addrs.hasMoreElements()) { - InetAddress addr = addrs.nextElement(); - if (addr.equals(infAddress)) { - return infAddress; - } - } - - /** - * No match so reset infAddress to indicate that the - * interface has changed via means - */ - infAddress = null; - return ia; - } catch (Exception e) { - return ia; - } - } + return delegate().getInterface(); } /** @@ -626,12 +455,7 @@ public class MulticastSocket extends DatagramSocket { */ public void setNetworkInterface(NetworkInterface netIf) throws SocketException { - - synchronized (infLock) { - getImpl().setOption(SocketOptions.IP_MULTICAST_IF2, netIf); - infAddress = null; - interfaceSet = true; - } + delegate().setNetworkInterface(netIf); } /** @@ -646,15 +470,7 @@ public class MulticastSocket extends DatagramSocket { * @since 1.4 */ public NetworkInterface getNetworkInterface() throws SocketException { - NetworkInterface ni - = (NetworkInterface)getImpl().getOption(SocketOptions.IP_MULTICAST_IF2); - if (ni == null) { - InetAddress[] addrs = new InetAddress[1]; - addrs[0] = InetAddress.anyLocalAddress(); - return new NetworkInterface(addrs[0].getHostName(), 0, addrs); - } else { - return ni; - } + return delegate().getNetworkInterface(); } /** @@ -678,7 +494,7 @@ public class MulticastSocket extends DatagramSocket { */ @Deprecated(since="14") public void setLoopbackMode(boolean disable) throws SocketException { - getImpl().setOption(SocketOptions.IP_MULTICAST_LOOP, Boolean.valueOf(disable)); + delegate().setLoopbackMode(disable); } /** @@ -694,7 +510,7 @@ public class MulticastSocket extends DatagramSocket { */ @Deprecated(since="14") public boolean getLoopbackMode() throws SocketException { - return ((Boolean)getImpl().getOption(SocketOptions.IP_MULTICAST_LOOP)).booleanValue(); + return delegate().getLoopbackMode(); } /** @@ -755,60 +571,6 @@ public class MulticastSocket extends DatagramSocket { @Deprecated public void send(DatagramPacket p, byte ttl) throws IOException { - if (isClosed()) - throw new SocketException("Socket is closed"); - synchronized(ttlLock) { - synchronized(p) { - InetAddress packetAddress = p.getAddress(); - int packetPort = p.getPort(); - checkAddress(packetAddress, "send"); - if (connectState == ST_NOT_CONNECTED) { - if (packetAddress == null) { - throw new IllegalArgumentException("Address not set"); - } - if (packetPort < 0 || packetPort > 0xFFFF) - throw new IllegalArgumentException("port out of range:" + packetPort); - // Security manager makes sure that the multicast address - // is allowed one and that the ttl used is less - // than the allowed maxttl. - SecurityManager security = System.getSecurityManager(); - if (security != null) { - if (packetAddress.isMulticastAddress()) { - security.checkMulticast(packetAddress, ttl); - } else { - security.checkConnect(packetAddress.getHostAddress(), - packetPort); - } - } - } else { - // we're connected - if (packetAddress == null) { - p.setAddress(connectedAddress); - p.setPort(connectedPort); - } else if ((!packetAddress.equals(connectedAddress)) || - packetPort != connectedPort) { - throw new IllegalArgumentException("connected address and packet address" + - " differ"); - } - } - byte dttl = getTTL(); - try { - if (ttl != dttl) { - // set the ttl - getImpl().setTTL(ttl); - } - if (packetPort == 0) { - throw new SocketException("Can't send to port 0"); - } - // call the datagram method to send - getImpl().send(p); - } finally { - // set it back to default - if (ttl != dttl) { - getImpl().setTTL(dttl); - } - } - } // synch p - } //synch ttl - } //method + delegate().send(p, ttl); + } } diff --git a/src/java.base/share/classes/java/net/NetMulticastSocket.java b/src/java.base/share/classes/java/net/NetMulticastSocket.java new file mode 100644 index 00000000000..4add390600a --- /dev/null +++ b/src/java.base/share/classes/java/net/NetMulticastSocket.java @@ -0,0 +1,1007 @@ +/* + * Copyright (c) 1995, 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 java.net; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.channels.DatagramChannel; +import java.security.AccessController; +import java.security.PrivilegedExceptionAction; +import java.util.Enumeration; +import java.util.Objects; +import java.util.Set; +import java.util.Collections; + +/** + * A multicast datagram socket that delegates socket operations to a + * {@link DatagramSocketImpl}. + * + * This class overrides every public method defined by {@link DatagramSocket} + * and {@link MulticastSocket}. + */ +final class NetMulticastSocket extends MulticastSocket { + /** + * Various states of this socket. + */ + private boolean bound = false; + private boolean closed = false; + private volatile boolean created; + private final Object closeLock = new Object(); + + /* + * The implementation of this DatagramSocket. + */ + private final DatagramSocketImpl impl; + + /** + * Are we using an older DatagramSocketImpl? + */ + private final boolean oldImpl; + + /** + * Set when a socket is ST_CONNECTED until we are certain + * that any packets which might have been received prior + * to calling connect() but not read by the application + * have been read. During this time we check the source + * address of all packets received to be sure they are from + * the connected destination. Other packets are read but + * silently dropped. + */ + private boolean explicitFilter = false; + private int bytesLeftToFilter; + /* + * Connection state: + * ST_NOT_CONNECTED = socket not connected + * ST_CONNECTED = socket connected + * ST_CONNECTED_NO_IMPL = socket connected but not at impl level + */ + static final int ST_NOT_CONNECTED = 0; + static final int ST_CONNECTED = 1; + static final int ST_CONNECTED_NO_IMPL = 2; + + int connectState = ST_NOT_CONNECTED; + + /* + * Connected address & port + */ + InetAddress connectedAddress = null; + int connectedPort = -1; + + /** + * This constructor is also used by {@link DatagramSocket#DatagramSocket(DatagramSocketImpl)}. + * @param impl The impl used in this instance. + */ + NetMulticastSocket(DatagramSocketImpl impl) { + super((MulticastSocket) null); + this.impl = Objects.requireNonNull(impl); + this.oldImpl = checkOldImpl(impl); + } + + /** + * Connects this socket to a remote socket address (IP address + port number). + * Binds socket if not already bound. + * + * @param address The remote address. + * @param port The remote port + * @throws SocketException if binding the socket fails. + */ + private synchronized void connectInternal(InetAddress address, int port) throws SocketException { + if (port < 0 || port > 0xFFFF) { + throw new IllegalArgumentException("connect: " + port); + } + if (address == null) { + throw new IllegalArgumentException("connect: null address"); + } + checkAddress(address, "connect"); + if (isClosed()) + return; + SecurityManager security = System.getSecurityManager(); + if (security != null) { + if (address.isMulticastAddress()) { + security.checkMulticast(address); + } else { + security.checkConnect(address.getHostAddress(), port); + security.checkAccept(address.getHostAddress(), port); + } + } + + if (port == 0) { + throw new SocketException("Can't connect to port 0"); + } + if (!isBound()) + bind(new InetSocketAddress(0)); + + // old impls do not support connect/disconnect + if (oldImpl || (impl instanceof AbstractPlainDatagramSocketImpl && + ((AbstractPlainDatagramSocketImpl) impl).nativeConnectDisabled())) { + connectState = ST_CONNECTED_NO_IMPL; + } else { + try { + getImpl().connect(address, port); + + // socket is now connected by the impl + connectState = ST_CONNECTED; + // Do we need to filter some packets? + int avail = getImpl().dataAvailable(); + if (avail == -1) { + throw new SocketException(); + } + explicitFilter = avail > 0; + if (explicitFilter) { + bytesLeftToFilter = getReceiveBufferSize(); + } + } catch (SocketException se) { + + // connection will be emulated by DatagramSocket + connectState = ST_CONNECTED_NO_IMPL; + } + } + + connectedAddress = address; + connectedPort = port; + } + + /** + * Return true if the given DatagramSocketImpl is an "old" impl. An old impl + * is one that doesn't implement the abstract methods added in Java SE 1.4. + */ + private static boolean checkOldImpl(DatagramSocketImpl impl) { + // DatagramSocketImpl.peekData() is a protected method, therefore we need to use + // getDeclaredMethod, therefore we need permission to access the member + try { + AccessController.doPrivileged( + new PrivilegedExceptionAction<>() { + public Void run() throws NoSuchMethodException { + Class[] cl = new Class[1]; + cl[0] = DatagramPacket.class; + impl.getClass().getDeclaredMethod("peekData", cl); + return null; + } + }); + return false; + } catch (java.security.PrivilegedActionException e) { + return true; + } + } + + /** + * Return the {@code DatagramSocketImpl} attached to this socket, + * creating the socket if not already created. + * + * @return the {@code DatagramSocketImpl} attached to that + * DatagramSocket + * @throws SocketException if creating the socket fails + * @since 1.4 + */ + final DatagramSocketImpl getImpl() throws SocketException { + if (!created) { + synchronized (this) { + if (!created) { + impl.create(); + created = true; + } + } + } + return impl; + } + + @Override + public synchronized void bind(SocketAddress addr) throws SocketException { + if (isClosed()) + throw new SocketException("Socket is closed"); + if (isBound()) + throw new SocketException("already bound"); + if (addr == null) + addr = new InetSocketAddress(0); + if (!(addr instanceof InetSocketAddress)) + throw new IllegalArgumentException("Unsupported address type!"); + InetSocketAddress epoint = (InetSocketAddress) addr; + if (epoint.isUnresolved()) + throw new SocketException("Unresolved address"); + InetAddress iaddr = epoint.getAddress(); + int port = epoint.getPort(); + checkAddress(iaddr, "bind"); + SecurityManager sec = System.getSecurityManager(); + if (sec != null) { + sec.checkListen(port); + } + try { + getImpl().bind(port, iaddr); + } catch (SocketException e) { + getImpl().close(); + throw e; + } + bound = true; + } + + static void checkAddress(InetAddress addr, String op) { + if (addr == null) { + return; + } + if (!(addr instanceof Inet4Address || addr instanceof Inet6Address)) { + throw new IllegalArgumentException(op + ": invalid address type"); + } + } + + @Override + public void connect(InetAddress address, int port) { + try { + connectInternal(address, port); + } catch (SocketException se) { + throw new UncheckedIOException("connect failed", se); + } + } + + @Override + public void connect(SocketAddress addr) throws SocketException { + if (addr == null) + throw new IllegalArgumentException("Address can't be null"); + if (!(addr instanceof InetSocketAddress)) + throw new IllegalArgumentException("Unsupported address type"); + InetSocketAddress epoint = (InetSocketAddress) addr; + if (epoint.isUnresolved()) + throw new SocketException("Unresolved address"); + connectInternal(epoint.getAddress(), epoint.getPort()); + } + + @Override + public void disconnect() { + synchronized (this) { + if (isClosed()) + return; + if (connectState == ST_CONNECTED) { + impl.disconnect(); + } + connectedAddress = null; + connectedPort = -1; + connectState = ST_NOT_CONNECTED; + explicitFilter = false; + } + } + + @Override + public boolean isBound() { + return bound; + } + + @Override + public boolean isConnected() { + return connectState != ST_NOT_CONNECTED; + } + + @Override + public InetAddress getInetAddress() { + return connectedAddress; + } + + @Override + public int getPort() { + return connectedPort; + } + + @Override + public SocketAddress getRemoteSocketAddress() { + if (!isConnected()) + return null; + return new InetSocketAddress(getInetAddress(), getPort()); + } + + @Override + public SocketAddress getLocalSocketAddress() { + if (isClosed()) + return null; + if (!isBound()) + return null; + return new InetSocketAddress(getLocalAddress(), getLocalPort()); + } + + @Override + public void send(DatagramPacket p) throws IOException { + synchronized (p) { + if (isClosed()) + throw new SocketException("Socket is closed"); + InetAddress packetAddress = p.getAddress(); + int packetPort = p.getPort(); + checkAddress(packetAddress, "send"); + if (connectState == ST_NOT_CONNECTED) { + if (packetAddress == null) { + throw new IllegalArgumentException("Address not set"); + } + if (packetPort < 0 || packetPort > 0xFFFF) + throw new IllegalArgumentException("port out of range: " + packetPort); + // check the address is ok with the security manager on every send. + SecurityManager security = System.getSecurityManager(); + + // The reason you want to synchronize on datagram packet + // is because you don't want an applet to change the address + // while you are trying to send the packet for example + // after the security check but before the send. + if (security != null) { + if (packetAddress.isMulticastAddress()) { + security.checkMulticast(packetAddress); + } else { + security.checkConnect(packetAddress.getHostAddress(), + packetPort); + } + } + if (packetPort == 0) { + throw new SocketException("Can't send to port 0"); + } + } else { + // we're connected + if (packetAddress == null) { + p.setAddress(connectedAddress); + p.setPort(connectedPort); + } else if ((!packetAddress.equals(connectedAddress)) || + packetPort != connectedPort) { + throw new IllegalArgumentException("connected address " + + "and packet address" + + " differ"); + } + } + // Check whether the socket is bound + if (!isBound()) + bind(new InetSocketAddress(0)); + // call the method to send + getImpl().send(p); + } + } + + @Override + public synchronized void receive(DatagramPacket p) throws IOException { + synchronized (p) { + if (!isBound()) + bind(new InetSocketAddress(0)); + if (connectState == ST_NOT_CONNECTED) { + // check the address is ok with the security manager before every recv. + SecurityManager security = System.getSecurityManager(); + if (security != null) { + while (true) { + String peekAd = null; + int peekPort = 0; + // peek at the packet to see who it is from. + if (!oldImpl) { + // We can use the new peekData() API + DatagramPacket peekPacket = new DatagramPacket(new byte[1], 1); + peekPort = getImpl().peekData(peekPacket); + peekAd = peekPacket.getAddress().getHostAddress(); + } else { + InetAddress adr = new InetAddress(); + peekPort = getImpl().peek(adr); + peekAd = adr.getHostAddress(); + } + try { + security.checkAccept(peekAd, peekPort); + // security check succeeded - so now break + // and recv the packet. + break; + } catch (SecurityException se) { + // Throw away the offending packet by consuming + // it in a tmp buffer. + DatagramPacket tmp = new DatagramPacket(new byte[1], 1); + getImpl().receive(tmp); + + // silently discard the offending packet + // and continue: unknown/malicious + // entities on nets should not make + // runtime throw security exception and + // disrupt the applet by sending random + // datagram packets. + continue; + } + } // end of while + } + } + DatagramPacket tmp = null; + if ((connectState == ST_CONNECTED_NO_IMPL) || explicitFilter) { + // We have to do the filtering the old fashioned way since + // the native impl doesn't support connect or the connect + // via the impl failed, or .. "explicitFilter" may be set when + // a socket is connected via the impl, for a period of time + // when packets from other sources might be queued on socket. + boolean stop = false; + while (!stop) { + InetAddress peekAddress = null; + int peekPort = -1; + // peek at the packet to see who it is from. + if (!oldImpl) { + // We can use the new peekData() API + DatagramPacket peekPacket = new DatagramPacket(new byte[1], 1); + peekPort = getImpl().peekData(peekPacket); + peekAddress = peekPacket.getAddress(); + } else { + // this api only works for IPv4 + peekAddress = new InetAddress(); + peekPort = getImpl().peek(peekAddress); + } + if ((!connectedAddress.equals(peekAddress)) || + (connectedPort != peekPort)) { + // throw the packet away and silently continue + tmp = new DatagramPacket( + new byte[1024], 1024); + getImpl().receive(tmp); + if (explicitFilter) { + if (checkFiltering(tmp)) { + stop = true; + } + } + } else { + stop = true; + } + } + } + // If the security check succeeds, or the datagram is + // connected then receive the packet + getImpl().receive(p); + if (explicitFilter && tmp == null) { + // packet was not filtered, account for it here + checkFiltering(p); + } + } + } + + private boolean checkFiltering(DatagramPacket p) throws SocketException { + bytesLeftToFilter -= p.getLength(); + if (bytesLeftToFilter <= 0 || getImpl().dataAvailable() <= 0) { + explicitFilter = false; + return true; + } + return false; + } + + @Override + public InetAddress getLocalAddress() { + if (isClosed()) + return null; + InetAddress in; + try { + in = (InetAddress) getImpl().getOption(SocketOptions.SO_BINDADDR); + if (in.isAnyLocalAddress()) { + in = InetAddress.anyLocalAddress(); + } + SecurityManager s = System.getSecurityManager(); + if (s != null) { + s.checkConnect(in.getHostAddress(), -1); + } + } catch (Exception e) { + in = InetAddress.anyLocalAddress(); // "0.0.0.0" + } + return in; + } + + @Override + public int getLocalPort() { + if (isClosed()) + return -1; + try { + return getImpl().getLocalPort(); + } catch (Exception e) { + return 0; + } + } + + @Override + public synchronized void setSoTimeout(int timeout) throws SocketException { + if (isClosed()) + throw new SocketException("Socket is closed"); + if (timeout < 0) + throw new IllegalArgumentException("timeout < 0"); + getImpl().setOption(SocketOptions.SO_TIMEOUT, timeout); + } + + @Override + public synchronized int getSoTimeout() throws SocketException { + if (isClosed()) + throw new SocketException("Socket is closed"); + if (getImpl() == null) + return 0; + Object o = getImpl().getOption(SocketOptions.SO_TIMEOUT); + /* extra type safety */ + if (o instanceof Integer) { + return ((Integer) o).intValue(); + } else { + return 0; + } + } + + @Override + public synchronized void setSendBufferSize(int size) throws SocketException { + if (!(size > 0)) { + throw new IllegalArgumentException("negative send size"); + } + if (isClosed()) + throw new SocketException("Socket is closed"); + getImpl().setOption(SocketOptions.SO_SNDBUF, size); + } + + @Override + public synchronized int getSendBufferSize() throws SocketException { + if (isClosed()) + throw new SocketException("Socket is closed"); + int result = 0; + Object o = getImpl().getOption(SocketOptions.SO_SNDBUF); + if (o instanceof Integer) { + result = ((Integer) o).intValue(); + } + return result; + } + + @Override + public synchronized void setReceiveBufferSize(int size) throws SocketException { + if (size <= 0) { + throw new IllegalArgumentException("invalid receive size"); + } + if (isClosed()) + throw new SocketException("Socket is closed"); + getImpl().setOption(SocketOptions.SO_RCVBUF, size); + } + + @Override + public synchronized int getReceiveBufferSize() throws SocketException { + if (isClosed()) + throw new SocketException("Socket is closed"); + int result = 0; + Object o = getImpl().getOption(SocketOptions.SO_RCVBUF); + if (o instanceof Integer) { + result = ((Integer) o).intValue(); + } + return result; + } + + @Override + public synchronized void setReuseAddress(boolean on) throws SocketException { + if (isClosed()) + throw new SocketException("Socket is closed"); + // Integer instead of Boolean for compatibility with older DatagramSocketImpl + if (oldImpl) + getImpl().setOption(SocketOptions.SO_REUSEADDR, on ? -1 : 0); + else + getImpl().setOption(SocketOptions.SO_REUSEADDR, Boolean.valueOf(on)); + } + + @Override + public synchronized boolean getReuseAddress() throws SocketException { + if (isClosed()) + throw new SocketException("Socket is closed"); + Object o = getImpl().getOption(SocketOptions.SO_REUSEADDR); + return ((Boolean) o).booleanValue(); + } + + @Override + public synchronized void setBroadcast(boolean on) throws SocketException { + if (isClosed()) + throw new SocketException("Socket is closed"); + getImpl().setOption(SocketOptions.SO_BROADCAST, Boolean.valueOf(on)); + } + + @Override + public synchronized boolean getBroadcast() throws SocketException { + if (isClosed()) + throw new SocketException("Socket is closed"); + return ((Boolean) (getImpl().getOption(SocketOptions.SO_BROADCAST))).booleanValue(); + } + + @Override + public synchronized void setTrafficClass(int tc) throws SocketException { + if (tc < 0 || tc > 255) + throw new IllegalArgumentException("tc is not in range 0 -- 255"); + + if (isClosed()) + throw new SocketException("Socket is closed"); + try { + getImpl().setOption(SocketOptions.IP_TOS, tc); + } catch (SocketException se) { + // not supported if socket already connected + // Solaris returns error in such cases + if (!isConnected()) + throw se; + } + } + + @Override + public synchronized int getTrafficClass() throws SocketException { + if (isClosed()) + throw new SocketException("Socket is closed"); + return ((Integer) (getImpl().getOption(SocketOptions.IP_TOS))).intValue(); + } + + @Override + public void close() { + synchronized (closeLock) { + if (isClosed()) + return; + impl.close(); + closed = true; + } + } + + @Override + public boolean isClosed() { + synchronized (closeLock) { + return closed; + } + } + + @Override + public DatagramSocket setOption(SocketOption name, T value) + throws IOException + { + Objects.requireNonNull(name); + if (isClosed()) + throw new SocketException("Socket is closed"); + getImpl().setOption(name, value); + return this; + } + + @Override + public T getOption(SocketOption name) throws IOException { + Objects.requireNonNull(name); + if (isClosed()) + throw new SocketException("Socket is closed"); + return getImpl().getOption(name); + } + + private volatile Set> options; + private final Object optionsLock = new Object(); + + @Override + public Set> supportedOptions() { + Set> options = this.options; + if (options != null) + return options; + synchronized (optionsLock) { + options = this.options; + if (options != null) { + return options; + } + try { + DatagramSocketImpl impl = getImpl(); + options = Collections.unmodifiableSet(impl.supportedOptions()); + } catch (IOException e) { + options = Collections.emptySet(); + } + return this.options = options; + } + } + + // Multicast socket support + + /** + * Used on some platforms to record if an outgoing interface + * has been set for this socket. + */ + private boolean interfaceSet; + + /** + * The lock on the socket's TTL. This is for set/getTTL and + * send(packet,ttl). + */ + private final Object ttlLock = new Object(); + + /** + * The lock on the socket's interface - used by setInterface + * and getInterface + */ + private final Object infLock = new Object(); + + /** + * The "last" interface set by setInterface on this MulticastSocket + */ + private InetAddress infAddress = null; + + @Deprecated + @Override + public void setTTL(byte ttl) throws IOException { + if (isClosed()) + throw new SocketException("Socket is closed"); + getImpl().setTTL(ttl); + } + + @Override + public void setTimeToLive(int ttl) throws IOException { + if (ttl < 0 || ttl > 255) { + throw new IllegalArgumentException("ttl out of range"); + } + if (isClosed()) + throw new SocketException("Socket is closed"); + getImpl().setTimeToLive(ttl); + } + + @Deprecated + @Override + public byte getTTL() throws IOException { + if (isClosed()) + throw new SocketException("Socket is closed"); + return getImpl().getTTL(); + } + + @Override + public int getTimeToLive() throws IOException { + if (isClosed()) + throw new SocketException("Socket is closed"); + return getImpl().getTimeToLive(); + } + + @Override + @Deprecated + public void joinGroup(InetAddress mcastaddr) throws IOException { + if (isClosed()) { + throw new SocketException("Socket is closed"); + } + + checkAddress(mcastaddr, "joinGroup"); + SecurityManager security = System.getSecurityManager(); + if (security != null) { + security.checkMulticast(mcastaddr); + } + + if (!mcastaddr.isMulticastAddress()) { + throw new SocketException("Not a multicast address"); + } + + /** + * required for some platforms where it's not possible to join + * a group without setting the interface first. + */ + NetworkInterface defaultInterface = NetworkInterface.getDefault(); + + if (!interfaceSet && defaultInterface != null) { + setNetworkInterface(defaultInterface); + } + + getImpl().join(mcastaddr); + } + + @Override + @Deprecated + public void leaveGroup(InetAddress mcastaddr) throws IOException { + if (isClosed()) { + throw new SocketException("Socket is closed"); + } + + checkAddress(mcastaddr, "leaveGroup"); + SecurityManager security = System.getSecurityManager(); + if (security != null) { + security.checkMulticast(mcastaddr); + } + + if (!mcastaddr.isMulticastAddress()) { + throw new SocketException("Not a multicast address"); + } + + getImpl().leave(mcastaddr); + } + + @Override + public void joinGroup(SocketAddress mcastaddr, NetworkInterface netIf) + throws IOException { + if (isClosed()) + throw new SocketException("Socket is closed"); + + if (mcastaddr == null || !(mcastaddr instanceof InetSocketAddress)) + throw new IllegalArgumentException("Unsupported address type"); + + if (oldImpl) + throw new UnsupportedOperationException(); + + checkAddress(((InetSocketAddress)mcastaddr).getAddress(), "joinGroup"); + SecurityManager security = System.getSecurityManager(); + if (security != null) { + security.checkMulticast(((InetSocketAddress)mcastaddr).getAddress()); + } + + if (!((InetSocketAddress)mcastaddr).getAddress().isMulticastAddress()) { + throw new SocketException("Not a multicast address"); + } + + getImpl().joinGroup(mcastaddr, netIf); + } + + @Override + public void leaveGroup(SocketAddress mcastaddr, NetworkInterface netIf) + throws IOException { + if (isClosed()) + throw new SocketException("Socket is closed"); + + if (mcastaddr == null || !(mcastaddr instanceof InetSocketAddress)) + throw new IllegalArgumentException("Unsupported address type"); + + if (oldImpl) + throw new UnsupportedOperationException(); + + checkAddress(((InetSocketAddress)mcastaddr).getAddress(), "leaveGroup"); + SecurityManager security = System.getSecurityManager(); + if (security != null) { + security.checkMulticast(((InetSocketAddress)mcastaddr).getAddress()); + } + + if (!((InetSocketAddress)mcastaddr).getAddress().isMulticastAddress()) { + throw new SocketException("Not a multicast address"); + } + + getImpl().leaveGroup(mcastaddr, netIf); + } + + @Override + @Deprecated + public void setInterface(InetAddress inf) throws SocketException { + if (isClosed()) { + throw new SocketException("Socket is closed"); + } + checkAddress(inf, "setInterface"); + synchronized (infLock) { + getImpl().setOption(SocketOptions.IP_MULTICAST_IF, inf); + infAddress = inf; + interfaceSet = true; + } + } + + @Override + @Deprecated + public InetAddress getInterface() throws SocketException { + if (isClosed()) { + throw new SocketException("Socket is closed"); + } + synchronized (infLock) { + InetAddress ia = + (InetAddress)getImpl().getOption(SocketOptions.IP_MULTICAST_IF); + + /** + * No previous setInterface or interface can be + * set using setNetworkInterface + */ + if (infAddress == null) { + return ia; + } + + /** + * Same interface set with setInterface? + */ + if (ia.equals(infAddress)) { + return ia; + } + + /** + * Different InetAddress from what we set with setInterface + * so enumerate the current interface to see if the + * address set by setInterface is bound to this interface. + */ + try { + NetworkInterface ni = NetworkInterface.getByInetAddress(ia); + Enumeration addrs = ni.getInetAddresses(); + while (addrs.hasMoreElements()) { + InetAddress addr = addrs.nextElement(); + if (addr.equals(infAddress)) { + return infAddress; + } + } + + /** + * No match so reset infAddress to indicate that the + * interface has changed via means + */ + infAddress = null; + return ia; + } catch (Exception e) { + return ia; + } + } + } + + @Override + public void setNetworkInterface(NetworkInterface netIf) + throws SocketException { + + synchronized (infLock) { + getImpl().setOption(SocketOptions.IP_MULTICAST_IF2, netIf); + infAddress = null; + interfaceSet = true; + } + } + + @Override + public NetworkInterface getNetworkInterface() throws SocketException { + NetworkInterface ni + = (NetworkInterface)getImpl().getOption(SocketOptions.IP_MULTICAST_IF2); + if (ni == null) { + InetAddress[] addrs = new InetAddress[1]; + addrs[0] = InetAddress.anyLocalAddress(); + return new NetworkInterface(addrs[0].getHostName(), 0, addrs); + } else { + return ni; + } + } + + @Override + @Deprecated + public void setLoopbackMode(boolean disable) throws SocketException { + getImpl().setOption(SocketOptions.IP_MULTICAST_LOOP, Boolean.valueOf(disable)); + } + + @Override + @Deprecated + public boolean getLoopbackMode() throws SocketException { + return ((Boolean)getImpl().getOption(SocketOptions.IP_MULTICAST_LOOP)).booleanValue(); + } + + @Deprecated + @Override + public void send(DatagramPacket p, byte ttl) + throws IOException { + if (isClosed()) + throw new SocketException("Socket is closed"); + synchronized(ttlLock) { + synchronized(p) { + InetAddress packetAddress = p.getAddress(); + checkAddress(packetAddress, "send"); + if (connectState == NetMulticastSocket.ST_NOT_CONNECTED) { + if (packetAddress == null) { + throw new IllegalArgumentException("Address not set"); + } + // Security manager makes sure that the multicast address + // is allowed one and that the ttl used is less + // than the allowed maxttl. + SecurityManager security = System.getSecurityManager(); + if (security != null) { + if (packetAddress.isMulticastAddress()) { + security.checkMulticast(packetAddress, ttl); + } else { + security.checkConnect(packetAddress.getHostAddress(), + p.getPort()); + } + } + } else { + // we're connected + if (packetAddress == null) { + p.setAddress(connectedAddress); + p.setPort(connectedPort); + } else if ((!packetAddress.equals(connectedAddress)) || + p.getPort() != connectedPort) { + throw new IllegalArgumentException("connected address and packet address" + + " differ"); + } + } + byte dttl = getTTL(); + try { + if (ttl != dttl) { + // set the ttl + getImpl().setTTL(ttl); + } + if (p.getPort() == 0) { + throw new SocketException("Can't send to port 0"); + } + // call the datagram method to send + getImpl().send(p); + } finally { + // set it back to default + if (ttl != dttl) { + getImpl().setTTL(dttl); + } + } + } // synch p + } //synch ttl + } //method +} diff --git a/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java b/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java index 6148133e9f6..652252f8dde 100644 --- a/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java +++ b/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java @@ -74,7 +74,7 @@ public class DatagramSocketAdaptor private volatile int timeout; private DatagramSocketAdaptor(DatagramChannelImpl dc) throws IOException { - super(/*SocketAddress*/null); + super(/*SocketAddress*/ DatagramSockets.NO_DELEGATE); this.dc = dc; } @@ -769,4 +769,24 @@ public class DatagramSocketAdaptor } } } + + /** + * Provides access to the value of the private static DatagramSocket.NO_DELEGATE + */ + private static class DatagramSockets { + private static final SocketAddress NO_DELEGATE; + + static { + try { + PrivilegedExceptionAction pa = () -> + MethodHandles.privateLookupIn(DatagramSocket.class, MethodHandles.lookup()); + MethodHandles.Lookup l = AccessController.doPrivileged(pa); + NO_DELEGATE = (SocketAddress) + l.findStaticVarHandle(DatagramSocket.class, "NO_DELEGATE", + SocketAddress.class).get(); + } catch (Exception e) { + throw new ExceptionInInitializerError(e); + } + } + } } \ No newline at end of file diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 8e7cb07d032..cb626e94045 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -627,8 +627,6 @@ java/net/MulticastSocket/Test.java 7145658 macosx-a java/net/MulticastSocket/SetGetNetworkInterfaceTest.java 8219083 windows-all -java/net/DatagramSocket/SendDatagramToBadAddress.java 7143960 macosx-all - java/net/ServerSocket/AcceptInheritHandle.java 8211854 aix-ppc64 @@ -638,8 +636,6 @@ java/net/ServerSocket/AcceptInheritHandle.java 8211854 aix-ppc6 java/nio/Buffer/EqualsCompareTest.java 8193917 solaris-all -java/nio/channels/DatagramChannel/ChangingAddress.java 7141822 macosx-all - java/nio/channels/DatagramChannel/Unref.java 8233519 generic-all java/nio/channels/AsynchronousSocketChannel/StressLoopback.java 8211851 aix-ppc64 diff --git a/test/jdk/java/net/DatagramSocket/AddressNotSet.java b/test/jdk/java/net/DatagramSocket/AddressNotSet.java index e9e2b094554..9a80d2eaf03 100644 --- a/test/jdk/java/net/DatagramSocket/AddressNotSet.java +++ b/test/jdk/java/net/DatagramSocket/AddressNotSet.java @@ -27,6 +27,7 @@ * @summary DatagramSocket.send should throw IllegalArgumentException * when the packet address is not correctly set. * @run main AddressNotSet + * @run main/othervm -Djdk.net.usePlainDatagramSocketImpl AddressNotSet */ import java.net.DatagramPacket; diff --git a/test/jdk/java/net/DatagramSocket/B6411513.java b/test/jdk/java/net/DatagramSocket/B6411513.java index 0fb4732afca..968a613be1d 100644 --- a/test/jdk/java/net/DatagramSocket/B6411513.java +++ b/test/jdk/java/net/DatagramSocket/B6411513.java @@ -70,6 +70,9 @@ public class B6411513 { System.out.print("disconnect..."); s.disconnect(); + System.out.println("local addr: " + s.getLocalAddress()); + System.out.println("local port: " + s.getLocalPort()); + byte[] data = { 0, 1, 2 }; DatagramPacket p = new DatagramPacket(data, data.length, s.getLocalAddress(), s.getLocalPort()); diff --git a/test/jdk/java/net/DatagramSocket/DatagramTimeout.java b/test/jdk/java/net/DatagramSocket/DatagramTimeout.java index 69489a6159b..6dbdd352819 100644 --- a/test/jdk/java/net/DatagramSocket/DatagramTimeout.java +++ b/test/jdk/java/net/DatagramSocket/DatagramTimeout.java @@ -27,52 +27,90 @@ * @summary Test to see if timeout hangs. Also checks that * negative timeout value fails as expected. * @run testng DatagramTimeout + * @run testng/othervm -Djdk.net.usePlainDatagramSocketImpl DatagramTimeout */ + import java.net.DatagramPacket; import java.net.DatagramSocket; +import java.net.MulticastSocket; +import java.net.SocketException; import java.net.SocketTimeoutException; import java.nio.channels.DatagramChannel; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import static org.testng.Assert.expectThrows; - +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertThrows; public class DatagramTimeout { - private static final Class IAE = IllegalArgumentException.class; - private static final Class STE = SocketTimeoutException.class; + private static final Class IAE = + IllegalArgumentException.class; + private static final Class STE = + SocketTimeoutException.class; + private static final Class SE = SocketException.class; - /** - * Test DatagramSocket setSoTimeout with a valid timeout value. - */ - @Test - public void testSetTimeout() throws Exception { - try (DatagramSocket s = new DatagramSocket()) { - byte[] buffer = new byte[50]; - DatagramPacket p = new DatagramPacket(buffer, buffer.length); - s.setSoTimeout(2); - expectThrows(STE, () -> s.receive(p)); - } + private DatagramSocket datagramSocket, multicastSocket, + datagramSocketAdaptor; + + @BeforeTest + public void setUp() throws Exception { + datagramSocket = new DatagramSocket(); + multicastSocket = new MulticastSocket(); + datagramSocketAdaptor = DatagramChannel.open().socket(); } - /** - * Test DatagramSocket setSoTimeout with a negative timeout. - */ - @Test - public void testSetNegativeTimeout() throws Exception { - try (DatagramSocket s = new DatagramSocket()) { - expectThrows(IAE, () -> s.setSoTimeout(-1)); - } + @DataProvider(name = "data") + public Object[][] variants() { + return new Object[][]{ + { datagramSocket }, + { datagramSocketAdaptor }, + { multicastSocket }, + }; + } + + @Test(dataProvider = "data") + public void testSetNegTimeout(DatagramSocket ds) { + assertThrows(IAE, () -> ds.setSoTimeout(-1)); + } + + @Test(dataProvider = "data") + public void testSetTimeout(DatagramSocket ds) throws Exception { + byte[] buffer = new byte[50]; + DatagramPacket pkt = new DatagramPacket(buffer, buffer.length); + ds.setSoTimeout(2); + assertThrows(STE, () -> ds.receive(pkt)); + } + + @Test(dataProvider = "data") + public void testGetTimeout(DatagramSocket ds) throws Exception { + ds.setSoTimeout(10); + assertEquals(10, ds.getSoTimeout()); + } + + @AfterTest + public void tearDown() { + datagramSocket.close(); + multicastSocket.close(); + datagramSocketAdaptor.close(); } - /** - * Test DatagramSocketAdaptor setSoTimeout with a negative timeout. - */ @Test - public void testNegativeTimeout() throws Exception { - try (DatagramChannel dc = DatagramChannel.open()) { - var s = dc.socket(); - expectThrows(IAE, () -> s.setSoTimeout(-1)); - } + public void testSetGetAfterClose() throws Exception { + var ds = new DatagramSocket(); + var ms = new MulticastSocket(); + var dsa = DatagramChannel.open().socket(); + + ds.close(); + ms.close(); + dsa.close(); + assertThrows(SE, () -> ds.setSoTimeout(10)); + assertThrows(SE, () -> ds.getSoTimeout()); + assertThrows(SE, () -> ms.setSoTimeout(10)); + assertThrows(SE, () -> ms.getSoTimeout()); + assertThrows(SE, () -> dsa.setSoTimeout(10)); + assertThrows(SE, () -> dsa.getSoTimeout()); } } diff --git a/test/jdk/java/net/DatagramSocket/InterruptibleDatagramSocket.java b/test/jdk/java/net/DatagramSocket/InterruptibleDatagramSocket.java index 399972842f1..2a250491725 100644 --- a/test/jdk/java/net/DatagramSocket/InterruptibleDatagramSocket.java +++ b/test/jdk/java/net/DatagramSocket/InterruptibleDatagramSocket.java @@ -36,6 +36,8 @@ import static java.lang.Thread.sleep; * @test * @summary Check interrupt mechanism for DatagramSocket, * MulticastSocket, and DatagramSocketAdaptor + * @run main InterruptibleDatagramSocket + * @run main/othervm -Djdk.net.usePlainDatagramSocketImpl InterruptibleDatagramSocket */ public class InterruptibleDatagramSocket { diff --git a/test/jdk/java/net/DatagramSocket/ReuseAddressTest.java b/test/jdk/java/net/DatagramSocket/ReuseAddressTest.java index 2b96173a6cf..6179d297efd 100644 --- a/test/jdk/java/net/DatagramSocket/ReuseAddressTest.java +++ b/test/jdk/java/net/DatagramSocket/ReuseAddressTest.java @@ -36,6 +36,7 @@ import java.net.SocketException; * @summary Expected SocketException not thrown when calling bind() with * setReuseAddress(false) * @run main/othervm ReuseAddressTest + * @run main/othervm -Djdk.net.usePlainDatagramSocketImpl ReuseAddressTest */ public class ReuseAddressTest { diff --git a/test/jdk/java/net/DatagramSocket/SendCheck.java b/test/jdk/java/net/DatagramSocket/SendCheck.java index 5931f44bd2e..474cb7eb743 100644 --- a/test/jdk/java/net/DatagramSocket/SendCheck.java +++ b/test/jdk/java/net/DatagramSocket/SendCheck.java @@ -47,7 +47,8 @@ import static org.testng.Assert.expectThrows; * DatagramSocketAdaptor and DatagramChannel all * throw expected Execption when passed a DatagramPacket * with invalid details - * @run testng/othervm SendCheck + * @run testng SendCheck + * @run testng/othervm -Djdk.net.usePlainDatagramSocketImpl SendCheck */ public class SendCheck { diff --git a/test/jdk/java/net/DatagramSocket/SendPortZero.java b/test/jdk/java/net/DatagramSocket/SendPortZero.java index f7c0376d6ca..b66eb60fc9f 100644 --- a/test/jdk/java/net/DatagramSocket/SendPortZero.java +++ b/test/jdk/java/net/DatagramSocket/SendPortZero.java @@ -48,7 +48,8 @@ import static org.testng.Assert.assertThrows; * @bug 8236105 8240533 * @summary Check that DatagramSocket throws expected * Exception when sending a DatagramPacket with port 0 - * @run testng/othervm SendPortZero + * @run testng SendPortZero + * @run testng/othervm -Djdk.net.usePlainDatagramSocketImpl SendPortZero */ public class SendPortZero { diff --git a/test/jdk/java/net/DatagramSocket/SetGetReceiveBufferSize.java b/test/jdk/java/net/DatagramSocket/SetGetReceiveBufferSize.java index 7c7c9a07227..14b32b17c4a 100644 --- a/test/jdk/java/net/DatagramSocket/SetGetReceiveBufferSize.java +++ b/test/jdk/java/net/DatagramSocket/SetGetReceiveBufferSize.java @@ -27,6 +27,7 @@ * @summary Check that setReceiveBufferSize and getReceiveBufferSize work as expected * @run testng SetGetReceiveBufferSize * @run testng/othervm -Djava.net.preferIPv4Stack=true SetGetReceiveBufferSize + * @run testng/othervm -Djdk.net.usePlainDatagramSocketImpl SetGetReceiveBufferSize */ import org.testng.annotations.DataProvider; diff --git a/test/jdk/java/net/DatagramSocket/SetGetSendBufferSize.java b/test/jdk/java/net/DatagramSocket/SetGetSendBufferSize.java index 70ed4eef750..dda6fc45f89 100644 --- a/test/jdk/java/net/DatagramSocket/SetGetSendBufferSize.java +++ b/test/jdk/java/net/DatagramSocket/SetGetSendBufferSize.java @@ -29,6 +29,7 @@ * @summary Check that setSendBufferSize and getSendBufferSize work as expected * @run testng SetGetSendBufferSize * @run testng/othervm -Djava.net.preferIPv4Stack=true SetGetSendBufferSize + * @run testng/othervm -Djdk.net.usePlainDatagramSocketImpl SetGetSendBufferSize */ import org.testng.annotations.DataProvider; diff --git a/test/jdk/java/net/DatagramSocket/TestAfterClose.java b/test/jdk/java/net/DatagramSocket/TestAfterClose.java index a1150d85363..d39d27a535c 100644 --- a/test/jdk/java/net/DatagramSocket/TestAfterClose.java +++ b/test/jdk/java/net/DatagramSocket/TestAfterClose.java @@ -25,6 +25,8 @@ * @test * @bug 6505016 * @summary Socket spec should clarify what getInetAddress/getPort/etc return after the Socket is closed + * @run main TestAfterClose + * @run main/othervm -Djdk.net.usePlainDatagramSocketImpl TestAfterClose */ import java.net.*; diff --git a/test/jdk/java/net/DatagramSocket/UnreferencedDatagramSockets.java b/test/jdk/java/net/DatagramSocket/UnreferencedDatagramSockets.java index 90759ba9358..1619af1decc 100644 --- a/test/jdk/java/net/DatagramSocket/UnreferencedDatagramSockets.java +++ b/test/jdk/java/net/DatagramSocket/UnreferencedDatagramSockets.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 @@ -25,8 +25,10 @@ * @test * @library /test/lib * @modules java.management java.base/java.io:+open java.base/java.net:+open + * java.base/sun.net * @run main/othervm UnreferencedDatagramSockets * @run main/othervm -Djava.net.preferIPv4Stack=true UnreferencedDatagramSockets + * @run main/othervm -Djdk.net.usePlainDatagramSocketImpl UnreferencedDatagramSockets * @summary Check that unreferenced datagram sockets are closed */ @@ -37,14 +39,18 @@ import java.lang.ref.ReferenceQueue; import java.lang.ref.WeakReference; import java.lang.reflect.Field; import java.io.IOException; +import java.lang.reflect.Method; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.DatagramSocketImpl; import java.net.InetAddress; import java.net.UnknownHostException; +import java.nio.channels.DatagramChannel; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.ArrayDeque; import java.util.List; import java.util.Optional; @@ -54,6 +60,7 @@ import java.util.concurrent.CountDownLatch; import com.sun.management.UnixOperatingSystemMXBean; import jdk.test.lib.net.IPSupport; +import sun.net.NetProperties; public class UnreferencedDatagramSockets { @@ -185,32 +192,62 @@ public class UnreferencedDatagramSockets { : -1L; } + private static boolean usePlainDatagramSocketImpl() { + PrivilegedAction pa = () -> NetProperties.get("jdk.net.usePlainDatagramSocketImpl"); + String s = AccessController.doPrivileged(pa); + return (s != null) && (s.isEmpty() || s.equalsIgnoreCase("true")); + } + // Reflect to find references in the datagram implementation that will be gc'd private static void extractRefs(DatagramSocket s, String name) { try { + Field datagramSocketField = DatagramSocket.class.getDeclaredField("delegate"); + datagramSocketField.setAccessible(true); - Field socketImplField = DatagramSocket.class.getDeclaredField("impl"); - socketImplField.setAccessible(true); - Object socketImpl = socketImplField.get(s); + if (!usePlainDatagramSocketImpl()) { + // DatagramSocket using DatagramSocketAdaptor + Object DatagramSocket = datagramSocketField.get(s); + assert DatagramSocket.getClass() == Class.forName("sun.nio.ch.DatagramSocketAdaptor"); - Field fileDescriptorField = DatagramSocketImpl.class.getDeclaredField("fd"); - fileDescriptorField.setAccessible(true); - FileDescriptor fileDescriptor = (FileDescriptor) fileDescriptorField.get(socketImpl); - extractRefs(fileDescriptor, name); + Method m = DatagramSocket.class.getDeclaredMethod("getChannel"); + m.setAccessible(true); + DatagramChannel datagramChannel = (DatagramChannel) m.invoke(DatagramSocket); - Class socketImplClass = socketImpl.getClass(); - System.out.printf("socketImplClass: %s%n", socketImplClass); - if (socketImplClass.getName().equals("java.net.TwoStacksPlainDatagramSocketImpl")) { - Field fileDescriptor1Field = socketImplClass.getDeclaredField("fd1"); - fileDescriptor1Field.setAccessible(true); - FileDescriptor fileDescriptor1 = (FileDescriptor) fileDescriptor1Field.get(socketImpl); - extractRefs(fileDescriptor1, name + "::twoStacksFd1"); + assert datagramChannel.getClass() == Class.forName("sun.nio.ch.DatagramChannelImpl"); + + Field fileDescriptorField = datagramChannel.getClass().getDeclaredField("fd"); + fileDescriptorField.setAccessible(true); + FileDescriptor fileDescriptor = (FileDescriptor) fileDescriptorField.get(datagramChannel); + extractRefs(fileDescriptor, name); } else { - System.out.printf("socketImpl class name not matched: %s != %s%n", - socketImplClass.getName(), "java.net.TwoStacksPlainDatagramSocketImpl"); + // DatagramSocket using PlainDatagramSocketImpl + Object DatagramSocket = datagramSocketField.get(s); + assert DatagramSocket.getClass() == Class.forName("java.net.NetMulticastSocket"); + + Method m = DatagramSocket.getClass().getDeclaredMethod("getImpl"); + m.setAccessible(true); + DatagramSocketImpl datagramSocketImpl = (DatagramSocketImpl) m.invoke(DatagramSocket); + + Field fileDescriptorField = DatagramSocketImpl.class.getDeclaredField("fd"); + fileDescriptorField.setAccessible(true); + FileDescriptor fileDescriptor = (FileDescriptor) fileDescriptorField.get(datagramSocketImpl); + extractRefs(fileDescriptor, name); + + Class socketImplClass = datagramSocketImpl.getClass(); + System.out.printf("socketImplClass: %s%n", socketImplClass); + if (socketImplClass.getName().equals("java.net.TwoStacksPlainDatagramSocketImpl")) { + Field fileDescriptor1Field = socketImplClass.getDeclaredField("fd1"); + fileDescriptor1Field.setAccessible(true); + FileDescriptor fileDescriptor1 = (FileDescriptor) fileDescriptor1Field.get(datagramSocketImpl); + extractRefs(fileDescriptor1, name + "::twoStacksFd1"); + + } else { + System.out.printf("socketImpl class name not matched: %s != %s%n", + socketImplClass.getName(), "java.net.TwoStacksPlainDatagramSocketImpl"); + } } - } catch (NoSuchFieldException | IllegalAccessException ex) { + } catch (Exception ex) { ex.printStackTrace(); throw new AssertionError("missing field", ex); } diff --git a/test/jdk/java/net/DatagramSocketImpl/TestCreate.java b/test/jdk/java/net/DatagramSocketImpl/TestCreate.java index d3b0d0e3d27..5a0fdf63283 100644 --- a/test/jdk/java/net/DatagramSocketImpl/TestCreate.java +++ b/test/jdk/java/net/DatagramSocketImpl/TestCreate.java @@ -60,10 +60,10 @@ public class TestCreate { Iterator iterator = List.of(dsi2, dsi3).iterator(); DatagramSocket.setDatagramSocketImplFactory(() -> iterator.next()); - DatagramSocket ds2 = new DatagramSocket(); + DatagramSocket ds2 = new DatagramSocket(null); assertTrue(dsi2.created.get(), "new DatagramSocket()"); - MulticastSocket ds3 = new MulticastSocket(); + MulticastSocket ds3 = new MulticastSocket(null); assertTrue(dsi3.created.get(), "new MulticastSocket()"); } diff --git a/test/jdk/java/net/InetAddress/CheckJNI.java b/test/jdk/java/net/InetAddress/CheckJNI.java index d66e2f5adc4..7e540c50d77 100644 --- a/test/jdk/java/net/InetAddress/CheckJNI.java +++ b/test/jdk/java/net/InetAddress/CheckJNI.java @@ -83,6 +83,10 @@ public class CheckJNI { static void testDatagram(InetAddress ia) throws Exception { DatagramSocket s1 = new DatagramSocket(0, ia); DatagramSocket s2 = new DatagramSocket(0, ia); + System.out.println("s1: local address=" + s1.getLocalAddress() + + ", local port=" + s1.getLocalPort()); + System.out.println("s2: local address=" + s2.getLocalAddress() + + ", local port=" + s2.getLocalPort()); DatagramPacket p1 = new DatagramPacket ( "hello world".getBytes(), diff --git a/test/jdk/java/net/MulticastSocket/B6427403.java b/test/jdk/java/net/MulticastSocket/B6427403.java index d6e87899ce9..a61b9751972 100644 --- a/test/jdk/java/net/MulticastSocket/B6427403.java +++ b/test/jdk/java/net/MulticastSocket/B6427403.java @@ -25,6 +25,8 @@ * @test * @bug 6427403 * @summary java.net.MulticastSocket.joinGroup() reports 'socket closed' + * @run main B6427403 + * @run main/othervm -Djdk.net.usePlainDatagramSocketImpl B6427403 */ import java.net.*; import java.io.*; diff --git a/test/jdk/java/net/MulticastSocket/MulticastAddresses.java b/test/jdk/java/net/MulticastSocket/MulticastAddresses.java index cb1458499f1..1a75e37f90c 100644 --- a/test/jdk/java/net/MulticastSocket/MulticastAddresses.java +++ b/test/jdk/java/net/MulticastSocket/MulticastAddresses.java @@ -27,6 +27,8 @@ * @library /test/lib * @summary Test that MutlicastSocket.joinGroup is working for * various multicast and non-multicast addresses. + * @run main MulticastAddresses + * @run main/othervm -Djdk.net.usePlainDatagramSocketImpl MulticastAddresses */ import jdk.test.lib.NetworkConfiguration; diff --git a/test/jdk/java/net/MulticastSocket/NoSetNetworkInterface.java b/test/jdk/java/net/MulticastSocket/NoSetNetworkInterface.java index 240f6486079..233c8850a63 100644 --- a/test/jdk/java/net/MulticastSocket/NoSetNetworkInterface.java +++ b/test/jdk/java/net/MulticastSocket/NoSetNetworkInterface.java @@ -28,6 +28,7 @@ * @run main/othervm NoSetNetworkInterface * @run main/othervm -Djava.net.preferIPv4Stack=true NoSetNetworkInterface * @run main/othervm -Djava.net.preferIPv6Addresses=true NoSetNetworkInterface + * @run main/othervm -Djdk.net.usePlainDatagramSocketImpl NoSetNetworkInterface * @summary Check that methods that are used to set and get the NetworkInterface * for a MulticastSocket work as expected. This test also checks that getOption * returns null correctly when a NetworkInterface has not been set diff --git a/test/jdk/java/net/MulticastSocket/Promiscuous.java b/test/jdk/java/net/MulticastSocket/Promiscuous.java index b32ef648675..ed99408c754 100644 --- a/test/jdk/java/net/MulticastSocket/Promiscuous.java +++ b/test/jdk/java/net/MulticastSocket/Promiscuous.java @@ -26,6 +26,7 @@ * @library /test/lib * @summary Test for interference when two sockets are bound to the same * port but joined to different multicast groups + * @run main/othervm -Djdk.net.usePlainDatagramSocketImpl Promiscuous * @run main Promiscuous * @run main/othervm -Djava.net.preferIPv4Stack=true Promiscuous */ diff --git a/test/jdk/java/net/MulticastSocket/SendPortZero.java b/test/jdk/java/net/MulticastSocket/SendPortZero.java index 579b84b23e9..335e769d2e5 100644 --- a/test/jdk/java/net/MulticastSocket/SendPortZero.java +++ b/test/jdk/java/net/MulticastSocket/SendPortZero.java @@ -48,7 +48,8 @@ import static org.testng.Assert.assertThrows; * @bug 8243408 * @summary Check that MulticastSocket throws expected * Exception when sending a DatagramPacket with port 0 - * @run testng/othervm SendPortZero + * @run testng SendPortZero + * @run testng/othervm -Djdk.net.usePlainDatagramSocketImpl SendPortZero */ public class SendPortZero { diff --git a/test/jdk/java/net/MulticastSocket/SetLoopbackMode.java b/test/jdk/java/net/MulticastSocket/SetLoopbackMode.java index 4ccc10f0b31..372a8812057 100644 --- a/test/jdk/java/net/MulticastSocket/SetLoopbackMode.java +++ b/test/jdk/java/net/MulticastSocket/SetLoopbackMode.java @@ -30,6 +30,7 @@ * @build jdk.test.lib.NetworkConfiguration * jdk.test.lib.Platform * @run main/othervm SetLoopbackMode + * @run main/othervm -Djdk.net.usePlainDatagramSocketImpl SetLoopbackMode */ import java.lang.reflect.Method; @@ -53,6 +54,8 @@ public class SetLoopbackMode { System.out.println("Loopback mode is enabled."); } + System.out.println(mc.getLocalSocketAddress()); + byte b[] = "hello".getBytes(); DatagramPacket p = new DatagramPacket(b, b.length, grp, mc.getLocalPort()); diff --git a/test/jdk/java/net/MulticastSocket/SetLoopbackModeIPv4.java b/test/jdk/java/net/MulticastSocket/SetLoopbackModeIPv4.java index 7dac8e0f7af..f95dc82495f 100644 --- a/test/jdk/java/net/MulticastSocket/SetLoopbackModeIPv4.java +++ b/test/jdk/java/net/MulticastSocket/SetLoopbackModeIPv4.java @@ -32,6 +32,8 @@ * SetLoopbackMode * SetLoopbackModeIPv4 * @run main/othervm -Djava.net.preferIPv4Stack=true SetLoopbackModeIPv4 + * @run main/othervm -Djava.net.preferIPv4Stack=true + * -Djdk.net.usePlainDatagramSocketImpl SetLoopbackModeIPv4 */ import jdk.test.lib.net.IPSupport; diff --git a/test/jdk/java/net/MulticastSocket/SetLoopbackOption.java b/test/jdk/java/net/MulticastSocket/SetLoopbackOption.java index af5bd89c2ea..948248dc727 100644 --- a/test/jdk/java/net/MulticastSocket/SetLoopbackOption.java +++ b/test/jdk/java/net/MulticastSocket/SetLoopbackOption.java @@ -31,6 +31,7 @@ * @run testng/othervm SetLoopbackOption * @run testng/othervm -Djava.net.preferIPv4Stack=true SetLoopbackOption * @run testng/othervm -Djava.net.preferIPv6Addresses=true SetLoopbackOption + * @run testng/othervm -Djdk.net.usePlainDatagramSocketImpl SetLoopbackOption */ import java.io.FileDescriptor; diff --git a/test/jdk/java/net/MulticastSocket/SetOutgoingIf.java b/test/jdk/java/net/MulticastSocket/SetOutgoingIf.java index 5eec51565cc..a2852963a59 100644 --- a/test/jdk/java/net/MulticastSocket/SetOutgoingIf.java +++ b/test/jdk/java/net/MulticastSocket/SetOutgoingIf.java @@ -26,6 +26,7 @@ * @bug 4742177 8241786 * @library /test/lib * @run main/othervm SetOutgoingIf + * @run main/othervm -Djdk.net.usePlainDatagramSocketImpl SetOutgoingIf * @summary Re-test IPv6 (and specifically MulticastSocket) with latest Linux & USAGI code */ import java.io.IOException; diff --git a/test/jdk/java/net/MulticastSocket/SetTTLAndGetTTL.java b/test/jdk/java/net/MulticastSocket/SetTTLAndGetTTL.java index 672949afeca..5b1df4effc3 100644 --- a/test/jdk/java/net/MulticastSocket/SetTTLAndGetTTL.java +++ b/test/jdk/java/net/MulticastSocket/SetTTLAndGetTTL.java @@ -24,6 +24,8 @@ /* @test * @bug 4189640 * @summary Make setTTL/getTTL works + * @run main SetTTLAndGetTTL + * @run main/othervm -Djdk.net.usePlainDatagramSocketImpl SetTTLAndGetTTL */ import java.net.*; diff --git a/test/jdk/java/net/MulticastSocket/SetTTLTo0.java b/test/jdk/java/net/MulticastSocket/SetTTLTo0.java index 1f561f6b041..77234d15017 100644 --- a/test/jdk/java/net/MulticastSocket/SetTTLTo0.java +++ b/test/jdk/java/net/MulticastSocket/SetTTLTo0.java @@ -24,6 +24,8 @@ /* @test * @bug 4148757 * @summary Make sure TTL can be set to 0 + * @run main SetTTLTo0 + * @run main/othervm -Djdk.net.usePlainDatagramSocketImpl SetTTLTo0 */ import java.net.*; diff --git a/test/jdk/java/net/MulticastSocket/UnreferencedMulticastSockets.java b/test/jdk/java/net/MulticastSocket/UnreferencedMulticastSockets.java index f9b31a2b526..0dd22b47cd7 100644 --- a/test/jdk/java/net/MulticastSocket/UnreferencedMulticastSockets.java +++ b/test/jdk/java/net/MulticastSocket/UnreferencedMulticastSockets.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 @@ -25,7 +25,9 @@ * @test * @library /test/lib * @modules java.management java.base/java.io:+open java.base/java.net:+open + * java.base/sun.net * @run main/othervm -Djava.net.preferIPv4Stack=true UnreferencedMulticastSockets + * @run main/othervm -Djdk.net.usePlainDatagramSocketImpl UnreferencedMulticastSockets * @run main/othervm UnreferencedMulticastSockets * @summary Check that unreferenced multicast sockets are closed */ @@ -37,6 +39,7 @@ import java.lang.ref.ReferenceQueue; import java.lang.ref.WeakReference; import java.lang.reflect.Field; import java.io.IOException; +import java.lang.reflect.Method; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.DatagramSocketImpl; @@ -44,9 +47,12 @@ import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.MulticastSocket; import java.net.UnknownHostException; +import java.nio.channels.DatagramChannel; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.ArrayDeque; import java.util.List; import java.util.Optional; @@ -56,6 +62,7 @@ import java.util.concurrent.TimeUnit; import jdk.test.lib.net.IPSupport; import com.sun.management.UnixOperatingSystemMXBean; +import sun.net.NetProperties; public class UnreferencedMulticastSockets { @@ -223,32 +230,62 @@ public class UnreferencedMulticastSockets { : -1L; } - // Reflect to find references in the socket implementation that will be gc'd - private static void extractRefs(MulticastSocket s, String name) { + private static boolean usePlainDatagramSocketImpl() { + PrivilegedAction pa = () -> NetProperties.get("jdk.net.usePlainDatagramSocketImpl"); + String s = AccessController.doPrivileged(pa); + return (s != null) && (s.isEmpty() || s.equalsIgnoreCase("true")); + } + + // Reflect to find references in the datagram implementation that will be gc'd + private static void extractRefs(DatagramSocket s, String name) { + try { + Field datagramSocketField = DatagramSocket.class.getDeclaredField("delegate"); + datagramSocketField.setAccessible(true); - Field socketImplField = DatagramSocket.class.getDeclaredField("impl"); - socketImplField.setAccessible(true); - Object socketImpl = socketImplField.get(s); + if (!usePlainDatagramSocketImpl()) { + // MulticastSocket using DatagramSocketAdaptor + Object MulticastSocket = datagramSocketField.get(s); - Field fileDescriptorField = DatagramSocketImpl.class.getDeclaredField("fd"); - fileDescriptorField.setAccessible(true); - FileDescriptor fileDescriptor = (FileDescriptor) fileDescriptorField.get(socketImpl); - extractRefs(fileDescriptor, name); + Method m = DatagramSocket.class.getDeclaredMethod("getChannel"); + m.setAccessible(true); + DatagramChannel datagramChannel = (DatagramChannel) m.invoke(MulticastSocket); - Class socketImplClass = socketImpl.getClass(); - System.out.printf("socketImplClass: %s%n", socketImplClass); - if (socketImplClass.getName().equals("java.net.TwoStacksPlainDatagramSocketImpl")) { - Field fileDescriptor1Field = socketImplClass.getDeclaredField("fd1"); - fileDescriptor1Field.setAccessible(true); - FileDescriptor fileDescriptor1 = (FileDescriptor) fileDescriptor1Field.get(socketImpl); - extractRefs(fileDescriptor1, name + "::twoStacksFd1"); + assert datagramChannel.getClass() == Class.forName("sun.nio.ch.DatagramChannelImpl"); + + Field fileDescriptorField = datagramChannel.getClass().getDeclaredField("fd"); + fileDescriptorField.setAccessible(true); + FileDescriptor fileDescriptor = (FileDescriptor) fileDescriptorField.get(datagramChannel); + extractRefs(fileDescriptor, name); } else { - System.out.printf("socketImpl class name not matched: %s != %s%n", - socketImplClass.getName(), "java.net.TwoStacksPlainDatagramSocketImpl"); + // MulticastSocket using PlainDatagramSocketImpl + Object MulticastSocket = datagramSocketField.get(s); + assert MulticastSocket.getClass() == Class.forName("java.net.NetMulticastSocket"); + + Method m = MulticastSocket.getClass().getDeclaredMethod("getImpl"); + m.setAccessible(true); + DatagramSocketImpl datagramSocketImpl = (DatagramSocketImpl) m.invoke(MulticastSocket); + + Field fileDescriptorField = DatagramSocketImpl.class.getDeclaredField("fd"); + fileDescriptorField.setAccessible(true); + FileDescriptor fileDescriptor = (FileDescriptor) fileDescriptorField.get(datagramSocketImpl); + extractRefs(fileDescriptor, name); + + Class socketImplClass = datagramSocketImpl.getClass(); + System.out.printf("socketImplClass: %s%n", socketImplClass); + if (socketImplClass.getName().equals("java.net.TwoStacksPlainDatagramSocketImpl")) { + Field fileDescriptor1Field = socketImplClass.getDeclaredField("fd1"); + fileDescriptor1Field.setAccessible(true); + FileDescriptor fileDescriptor1 = (FileDescriptor) fileDescriptor1Field.get(datagramSocketImpl); + extractRefs(fileDescriptor1, name + "::twoStacksFd1"); + + } else { + System.out.printf("socketImpl class name not matched: %s != %s%n", + socketImplClass.getName(), "java.net.TwoStacksPlainDatagramSocketImpl"); + } } - } catch (NoSuchFieldException | IllegalAccessException ex) { + } catch (Exception ex) { ex.printStackTrace(); throw new AssertionError("missing field", ex); } diff --git a/test/jdk/java/net/Socket/AddressTest.java b/test/jdk/java/net/Socket/AddressTest.java index 79fd3d879f5..b1cef8e3e09 100644 --- a/test/jdk/java/net/Socket/AddressTest.java +++ b/test/jdk/java/net/Socket/AddressTest.java @@ -29,6 +29,7 @@ * SocketAddress * @run main AddressTest * @run main/othervm -Djava.net.preferIPv4Stack=true AddressTest + * @run main/othervm -Djdk.net.usePlainDatagramSocketImpl AddressTest */ import java.net.*; diff --git a/test/jdk/java/net/SocketOption/AfterClose.java b/test/jdk/java/net/SocketOption/AfterClose.java index f0582dc43e5..5d07beb3e76 100644 --- a/test/jdk/java/net/SocketOption/AfterClose.java +++ b/test/jdk/java/net/SocketOption/AfterClose.java @@ -27,6 +27,7 @@ * @summary Ensures that IOException is thrown after the socket is closed * @run testng AfterClose * @run testng/othervm -Djdk.net.usePlainSocketImpl AfterClose + * @run testng/othervm -Djdk.net.usePlainDatagramSocketImpl AfterClose */ import java.io.IOException; @@ -48,6 +49,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; + import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import static java.lang.Boolean.*; diff --git a/test/jdk/java/net/SocketOption/OptionsTest.java b/test/jdk/java/net/SocketOption/OptionsTest.java index ce4fc18b355..f0efc2780c0 100644 --- a/test/jdk/java/net/SocketOption/OptionsTest.java +++ b/test/jdk/java/net/SocketOption/OptionsTest.java @@ -28,6 +28,7 @@ * @requires !vm.graal.enabled * @run main/othervm -Xcheck:jni OptionsTest * @run main/othervm -Djdk.net.usePlainSocketImpl OptionsTest + * @run main/othervm -Djdk.net.usePlainDatagramSocketImpl OptionsTest * @run main/othervm -Xcheck:jni -Djava.net.preferIPv4Stack=true OptionsTest * @run main/othervm --limit-modules=java.base OptionsTest */ From adf1d4757b068ee33a64c797def9b30b6eb71548 Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Fri, 15 May 2020 18:13:20 +0200 Subject: [PATCH 075/143] 8245093: WSL support broke cygwin toolchain detection Reviewed-by: erikj --- make/autoconf/basic_tools.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/make/autoconf/basic_tools.m4 b/make/autoconf/basic_tools.m4 index 47ea9442ff5..7a0040f650e 100644 --- a/make/autoconf/basic_tools.m4 +++ b/make/autoconf/basic_tools.m4 @@ -97,7 +97,7 @@ AC_DEFUN_ONCE([BASIC_SETUP_FUNDAMENTAL_TOOLS], UTIL_PATH_PROGS(NICE, nice) UTIL_PATH_PROGS(LSB_RELEASE, lsb_release) - UTIL_PATH_PROGS(CMD, cmd.exe, /mnt/c/Windows/System32) + UTIL_PATH_PROGS(CMD, cmd.exe, $PATH /cygdrive/c/Windows/System32 /mnt/c/Windows/System32) ]) ############################################################################### From e83968799ec605e6f5c62c36f5213d276cf5be20 Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Fri, 15 May 2020 18:14:58 +0200 Subject: [PATCH 076/143] 8245096: Better windows environment output in configure Reviewed-by: erikj --- make/autoconf/basic_windows.m4 | 40 ++++++++++++++++++++++------------ make/autoconf/help.m4 | 6 ++++- 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/make/autoconf/basic_windows.m4 b/make/autoconf/basic_windows.m4 index 11fb231d825..310f58adf43 100644 --- a/make/autoconf/basic_windows.m4 +++ b/make/autoconf/basic_windows.m4 @@ -31,18 +31,30 @@ AC_DEFUN([BASIC_CHECK_PATHS_WINDOWS], AC_MSG_ERROR([Your base path is too long. It is $SRC_ROOT_LENGTH characters long, but only 100 is supported]) fi + AC_MSG_CHECKING([Windows version]) + # Additional [] needed to keep m4 from mangling shell constructs. + [ WINDOWS_VERSION=`$CMD /c ver.exe | $EGREP -o '([0-9]+\.)+[0-9]+'` ] + AC_MSG_RESULT([$WINDOWS_VERSION]) + if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then AC_MSG_CHECKING([cygwin release]) - CYGWIN_VERSION=`$UNAME -r` - AC_MSG_RESULT([$CYGWIN_VERSION]) - WINDOWS_ENV_VENDOR='cygwin' - WINDOWS_ENV_VERSION="$CYGWIN_VERSION" + CYGWIN_RELEASE=`$UNAME -r` + AC_MSG_RESULT([$CYGWIN_RELEASE]) - CYGWIN_VERSION_OLD=`$ECHO $CYGWIN_VERSION | $GREP -e '^1\.[0-6]'` + AC_MSG_CHECKING([cygwin version]) + CYGWIN_VERSION=`$UNAME -v` + AC_MSG_RESULT([$CYGWIN_VERSION]) + + # Additional [] needed to keep m4 from mangling shell constructs. + [ CYGWIN_VERSION_OLD=`$ECHO $CYGWIN_RELEASE | $GREP -e '^1\.[0-6]'` ] if test "x$CYGWIN_VERSION_OLD" != x; then - AC_MSG_NOTICE([Your cygwin is too old. You are running $CYGWIN_VERSION, but at least cygwin 1.7 is required. Please upgrade.]) + AC_MSG_NOTICE([Your cygwin is too old. You are running $CYGWIN_RELEASE, but at least cygwin 1.7 is required. Please upgrade.]) AC_MSG_ERROR([Cannot continue]) fi + + WINDOWS_ENV_VENDOR='cygwin' + WINDOWS_ENV_VERSION="$CYGWIN_RELEASE, $CYGWIN_VERSION" + if test "x$CYGPATH" = x; then AC_MSG_ERROR([Something is wrong with your cygwin installation since I cannot find cygpath.exe in your path]) fi @@ -59,11 +71,15 @@ AC_DEFUN([BASIC_CHECK_PATHS_WINDOWS], fi elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then AC_MSG_CHECKING([msys release]) - MSYS_VERSION=`$UNAME -r` + MSYS_RELEASE=`$UNAME -r` + AC_MSG_RESULT([$MSYS_RELEASE]) + + AC_MSG_CHECKING([msys version]) + MSYS_VERSION=`$UNAME -v` AC_MSG_RESULT([$MSYS_VERSION]) WINDOWS_ENV_VENDOR='msys' - WINDOWS_ENV_VERSION="$MSYS_VERSION" + WINDOWS_ENV_VERSION="$MSYS_RELEASE, $MSYS_VERSION" AC_MSG_CHECKING([msys root directory as unix-style path]) # The cmd output ends with Windows line endings (CR/LF), the grep command will strip that away @@ -72,10 +88,6 @@ AC_DEFUN([BASIC_CHECK_PATHS_WINDOWS], AC_MSG_RESULT([$MSYS_ROOT_PATH]) WINDOWS_ENV_ROOT_PATH="$MSYS_ROOT_PATH" elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.wsl"; then - AC_MSG_CHECKING([Windows version]) - # m4 replaces [ and ] so we use @<:@ and @:>@ instead - WINDOWS_VERSION=`$CMD /c ver.exe | $EGREP -o '(@<:@0-9@:>@+\.)+@<:@0-9@:>@+'` - AC_MSG_RESULT([$WINDOWS_VERSION]) AC_MSG_CHECKING([WSL kernel version]) WSL_KERNEL_VERSION=`$UNAME -v` @@ -89,8 +101,8 @@ AC_DEFUN([BASIC_CHECK_PATHS_WINDOWS], WSL_DISTRIBUTION=`$LSB_RELEASE -d | sed 's/Description:\t//'` AC_MSG_RESULT([$WSL_DISTRIBUTION]) - WINDOWS_ENV_VENDOR='WSL' - WINDOWS_ENV_VERSION="$WSL_DISTRIBUTION $WSL_KERNEL_VERSION $WSL_KERNEL_RELEASE (on Windows build $WINDOWS_VERSION)" + WINDOWS_ENV_VENDOR='wsl' + WINDOWS_ENV_VERSION="$WSL_KERNEL_RELEASE, $WSL_KERNEL_VERSION ($WSL_DISTRIBUTION)" else AC_MSG_ERROR([Unknown Windows environment. Neither cygwin, msys, nor wsl was detected.]) fi diff --git a/make/autoconf/help.m4 b/make/autoconf/help.m4 index 7507cd4c93e..af3a2acc0d6 100644 --- a/make/autoconf/help.m4 +++ b/make/autoconf/help.m4 @@ -250,7 +250,11 @@ AC_DEFUN_ONCE([HELP_PRINT_SUMMARY_AND_WARNINGS], printf "\n" printf "Tools summary:\n" if test "x$OPENJDK_BUILD_OS" = "xwindows"; then - printf "* Environment: $WINDOWS_ENV_VENDOR version $WINDOWS_ENV_VERSION (root at $WINDOWS_ENV_ROOT_PATH)\n" + printf "* Environment: $WINDOWS_ENV_VENDOR version $WINDOWS_ENV_VERSION. Windows version $WINDOWS_VERSION" + if test "x$WINDOWS_ENV_ROOT_PATH" != "x"; then + printf ". Root at $WINDOWS_ENV_ROOT_PATH" + fi + printf "\n" fi printf "* Boot JDK: $BOOT_JDK_VERSION (at $BOOT_JDK)\n" printf "* Toolchain: $TOOLCHAIN_TYPE ($TOOLCHAIN_DESCRIPTION)\n" From 150d6cfea81afd3900ff69a7ab60efdadf5de76d Mon Sep 17 00:00:00 2001 From: Claes Redestad Date: Fri, 15 May 2020 18:37:08 +0200 Subject: [PATCH 077/143] 8245094: Reduce overhead of initializing the default StringConcatFactory strategy Reviewed-by: psandoz, jlaskey --- src/java.base/share/classes/java/lang/System.java | 4 ++++ .../classes/java/lang/invoke/StringConcatFactory.java | 7 +------ .../share/classes/jdk/internal/access/JavaLangAccess.java | 5 +++++ 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/java.base/share/classes/java/lang/System.java b/src/java.base/share/classes/java/lang/System.java index 7fc959ae1be..6ac9d5535e4 100644 --- a/src/java.base/share/classes/java/lang/System.java +++ b/src/java.base/share/classes/java/lang/System.java @@ -2283,6 +2283,10 @@ public final class System { return StringConcatHelper.lookupStatic(name, methodType); } + public long stringConcatInitialCoder() { + return StringConcatHelper.initialCoder(); + } + public Object classData(Class c) { return c.getClassData(); } diff --git a/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java b/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java index 9d14352215a..88b0d6d6d45 100644 --- a/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java +++ b/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java @@ -1724,12 +1724,7 @@ public final class StringConcatFactory { private static final long INITIAL_CODER; static { - try { - MethodHandle initCoder = JLA.stringConcatHelper("initialCoder", methodType(long.class)); - INITIAL_CODER = (long) initCoder.invoke(); - } catch (Throwable e) { - throw new AssertionError(e); - } + INITIAL_CODER = JLA.stringConcatInitialCoder(); PREPENDERS = new ConcurrentHashMap<>(); MIXERS = new ConcurrentHashMap<>(); diff --git a/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java b/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java index fb4130481c4..729bd7bc21c 100644 --- a/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java +++ b/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java @@ -333,6 +333,11 @@ public interface JavaLangAccess { */ MethodHandle stringConcatHelper(String name, MethodType methodType); + /** + * Get the string concat initial coder + */ + long stringConcatInitialCoder(); + /* * Get the class data associated with the given class. * @param c the class From fb6e7b06fb7810fcb3aef994e45f1158425a94e6 Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Fri, 15 May 2020 18:58:17 +0200 Subject: [PATCH 078/143] 8245119: Fix include path for hotspot-ide-project Reviewed-by: erikj --- make/Main.gmk | 1 + 1 file changed, 1 insertion(+) diff --git a/make/Main.gmk b/make/Main.gmk index f19622477cd..0b303fa52f8 100644 --- a/make/Main.gmk +++ b/make/Main.gmk @@ -263,6 +263,7 @@ $(foreach v, $(JVM_VARIANTS), $(eval $(call DeclareHotspotLibsRecipe,$v))) $(eval $(call SetupTarget, hotspot-ide-project, \ MAKEFILE := hotspot/ide/CreateVSProject, \ DEPS := hotspot exploded-image, \ + ARGS := -I$(TOPDIR)/make/hotspot, \ )) ALL_TARGETS += $(HOTSPOT_VARIANT_TARGETS) $(HOTSPOT_VARIANT_GENSRC_TARGETS) \ From b61c88c69387c5280b2b775cf4ae89fa26465da9 Mon Sep 17 00:00:00 2001 From: Roland Westrelin Date: Fri, 15 May 2020 19:57:37 +0200 Subject: [PATCH 079/143] 8245083: [REDO] Shenandoah: Remove null-handling in LRB expansion Reviewed-by: shade --- .../shenandoah/c2/shenandoahBarrierSetC2.cpp | 6 +- .../gc/shenandoah/c2/shenandoahSupport.cpp | 243 ++---------------- .../gc/shenandoah/c2/shenandoahSupport.hpp | 4 - 3 files changed, 19 insertions(+), 234 deletions(-) diff --git a/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp b/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp index 05c45b4e955..184b290b2ac 100644 --- a/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp +++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp @@ -483,14 +483,14 @@ const TypeFunc* ShenandoahBarrierSetC2::shenandoah_clone_barrier_Type() { const TypeFunc* ShenandoahBarrierSetC2::shenandoah_load_reference_barrier_Type() { const Type **fields = TypeTuple::fields(2); - fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // original field value - fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM; // original load address + fields[TypeFunc::Parms+0] = TypeOopPtr::BOTTOM; // original field value + fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM; // original load address const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields); // create result type (range) fields = TypeTuple::fields(1); - fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; + fields[TypeFunc::Parms+0] = TypeOopPtr::BOTTOM; const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields); return TypeFunc::make(domain, range); diff --git a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp index 3f1991a6889..aac3d39a1fc 100644 --- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp +++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp @@ -919,76 +919,6 @@ void ShenandoahBarrierC2Support::test_null(Node*& ctrl, Node* val, Node*& null_c } } -Node* ShenandoahBarrierC2Support::clone_null_check(Node*& c, Node* val, Node* unc_ctrl, PhaseIdealLoop* phase) { - IdealLoopTree *loop = phase->get_loop(c); - Node* iff = unc_ctrl->in(0); - assert(iff->is_If(), "broken"); - Node* new_iff = iff->clone(); - new_iff->set_req(0, c); - phase->register_control(new_iff, loop, c); - Node* iffalse = new IfFalseNode(new_iff->as_If()); - phase->register_control(iffalse, loop, new_iff); - Node* iftrue = new IfTrueNode(new_iff->as_If()); - phase->register_control(iftrue, loop, new_iff); - c = iftrue; - const Type *t = phase->igvn().type(val); - assert(val->Opcode() == Op_CastPP, "expect cast to non null here"); - Node* uncasted_val = val->in(1); - val = new CastPPNode(uncasted_val, t); - val->init_req(0, c); - phase->register_new_node(val, c); - return val; -} - -void ShenandoahBarrierC2Support::fix_null_check(Node* unc, Node* unc_ctrl, Node* new_unc_ctrl, - Unique_Node_List& uses, PhaseIdealLoop* phase) { - IfNode* iff = unc_ctrl->in(0)->as_If(); - Node* proj = iff->proj_out(0); - assert(proj != unc_ctrl, "bad projection"); - Node* use = proj->unique_ctrl_out(); - - assert(use == unc || use->is_Region(), "what else?"); - - uses.clear(); - if (use == unc) { - phase->set_idom(use, new_unc_ctrl, phase->dom_depth(use)); - for (uint i = 1; i < unc->req(); i++) { - Node* n = unc->in(i); - if (phase->has_ctrl(n) && phase->get_ctrl(n) == proj) { - uses.push(n); - } - } - } else { - assert(use->is_Region(), "what else?"); - uint idx = 1; - for (; use->in(idx) != proj; idx++); - for (DUIterator_Fast imax, i = use->fast_outs(imax); i < imax; i++) { - Node* u = use->fast_out(i); - if (u->is_Phi() && phase->get_ctrl(u->in(idx)) == proj) { - uses.push(u->in(idx)); - } - } - } - for(uint next = 0; next < uses.size(); next++ ) { - Node *n = uses.at(next); - assert(phase->get_ctrl(n) == proj, "bad control"); - phase->set_ctrl_and_loop(n, new_unc_ctrl); - if (n->in(0) == proj) { - phase->igvn().replace_input_of(n, 0, new_unc_ctrl); - } - for (uint i = 0; i < n->req(); i++) { - Node* m = n->in(i); - if (m != NULL && phase->has_ctrl(m) && phase->get_ctrl(m) == proj) { - uses.push(m); - } - } - } - - phase->igvn().rehash_node_delayed(use); - int nb = use->replace_edge(proj, new_unc_ctrl); - assert(nb == 1, "only use expected"); -} - void ShenandoahBarrierC2Support::test_in_cset(Node*& ctrl, Node*& not_cset_ctrl, Node* val, Node* raw_mem, PhaseIdealLoop* phase) { Node* old_ctrl = ctrl; PhaseIterGVN& igvn = phase->igvn(); @@ -1198,80 +1128,15 @@ void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) { continue; } - phase->igvn().replace_input_of(u, 1, val); - phase->igvn().replace_input_of(lrb, ShenandoahLoadReferenceBarrierNode::ValueIn, u); - phase->set_ctrl(u, u->in(0)); - phase->set_ctrl(lrb, u->in(0)); - unc = u->in(0)->as_Proj()->is_uncommon_trap_if_pattern(Deoptimization::Reason_none); - unc_ctrl = u->in(0); - val = u; - - for (DUIterator_Fast jmax, j = val->fast_outs(jmax); j < jmax; j++) { - Node* u = val->fast_out(j); - if (u == lrb) continue; - phase->igvn().rehash_node_delayed(u); - int nb = u->replace_edge(val, lrb); - --j; jmax -= nb; - } - - RegionNode* r = new RegionNode(3); - IfNode* iff = unc_ctrl->in(0)->as_If(); - - Node* ctrl_use = unc_ctrl->unique_ctrl_out(); - Node* unc_ctrl_clone = unc_ctrl->clone(); - phase->register_control(unc_ctrl_clone, loop, iff); - Node* c = unc_ctrl_clone; - Node* new_cast = clone_null_check(c, val, unc_ctrl_clone, phase); - r->init_req(1, new_cast->in(0)->in(0)->as_If()->proj_out(0)); - - phase->igvn().replace_input_of(unc_ctrl, 0, c->in(0)); - phase->set_idom(unc_ctrl, c->in(0), phase->dom_depth(unc_ctrl)); - phase->lazy_replace(c, unc_ctrl); - c = NULL;; - phase->igvn().replace_input_of(val, 0, unc_ctrl_clone); - phase->set_ctrl(val, unc_ctrl_clone); - - IfNode* new_iff = new_cast->in(0)->in(0)->as_If(); - fix_null_check(unc, unc_ctrl_clone, r, uses, phase); - Node* iff_proj = iff->proj_out(0); - r->init_req(2, iff_proj); - phase->register_control(r, phase->ltree_root(), iff); - - Node* new_bol = new_iff->in(1)->clone(); - Node* new_cmp = new_bol->in(1)->clone(); - assert(new_cmp->Opcode() == Op_CmpP, "broken"); - assert(new_cmp->in(1) == val->in(1), "broken"); - new_bol->set_req(1, new_cmp); - new_cmp->set_req(1, lrb); - phase->register_new_node(new_bol, new_iff->in(0)); - phase->register_new_node(new_cmp, new_iff->in(0)); - phase->igvn().replace_input_of(new_iff, 1, new_bol); - phase->igvn().replace_input_of(new_cast, 1, lrb); - - for (DUIterator_Fast imax, i = lrb->fast_outs(imax); i < imax; i++) { - Node* u = lrb->fast_out(i); - if (u == new_cast || u == new_cmp) { - continue; - } - phase->igvn().rehash_node_delayed(u); - int nb = u->replace_edge(lrb, new_cast); - assert(nb > 0, "no update?"); - --i; imax -= nb; - } - - for (DUIterator_Fast imax, i = val->fast_outs(imax); i < imax; i++) { - Node* u = val->fast_out(i); - if (u == lrb) { - continue; - } - phase->igvn().rehash_node_delayed(u); - int nb = u->replace_edge(val, new_cast); - assert(nb > 0, "no update?"); - --i; imax -= nb; - } - - ctrl = unc_ctrl_clone; - phase->set_ctrl_and_loop(lrb, ctrl); + Node* iff = u->in(0)->in(0); + Node* bol = iff->in(1)->clone(); + Node* cmp = bol->in(1)->clone(); + cmp->set_req(1, lrb); + bol->set_req(1, cmp); + phase->igvn().replace_input_of(iff, 1, bol); + phase->set_ctrl(lrb, iff->in(0)); + phase->register_new_node(cmp, iff->in(0)); + phase->register_new_node(bol, iff->in(0)); break; } } @@ -1424,20 +1289,6 @@ void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) { Node* raw_mem_for_ctrl = fixer.find_mem(ctrl, NULL); IdealLoopTree *loop = phase->get_loop(ctrl); - CallStaticJavaNode* unc = lrb->pin_and_expand_null_check(phase->igvn()); - Node* unc_ctrl = NULL; - if (unc != NULL) { - if (val->in(ShenandoahLoadReferenceBarrierNode::Control) != ctrl) { - unc = NULL; - } else { - unc_ctrl = val->in(ShenandoahLoadReferenceBarrierNode::Control); - } - } - - Node* uncasted_val = val; - if (unc != NULL) { - uncasted_val = val->in(1); - } Node* heap_stable_ctrl = NULL; Node* null_ctrl = NULL; @@ -1445,9 +1296,9 @@ void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) { assert(val->bottom_type()->make_oopptr(), "need oop"); assert(val->bottom_type()->make_oopptr()->const_oop() == NULL, "expect non-constant"); - enum { _heap_stable = 1, _not_cset, _evac_path, _null_path, PATH_LIMIT }; + enum { _heap_stable = 1, _not_cset, _evac_path, PATH_LIMIT }; Node* region = new RegionNode(PATH_LIMIT); - Node* val_phi = new PhiNode(region, uncasted_val->bottom_type()->is_oopptr()); + Node* val_phi = new PhiNode(region, val->bottom_type()->is_oopptr()); Node* raw_mem_phi = PhiNode::make(region, raw_mem, Type::MEMORY, TypeRawPtr::BOTTOM); // Stable path. @@ -1456,50 +1307,25 @@ void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) { // Heap stable case region->init_req(_heap_stable, heap_stable_ctrl); - val_phi->init_req(_heap_stable, uncasted_val); + val_phi->init_req(_heap_stable, val); raw_mem_phi->init_req(_heap_stable, raw_mem); - Node* reg2_ctrl = NULL; - // Null case - test_null(ctrl, val, null_ctrl, phase); - if (null_ctrl != NULL) { - reg2_ctrl = null_ctrl->in(0); - region->init_req(_null_path, null_ctrl); - val_phi->init_req(_null_path, uncasted_val); - raw_mem_phi->init_req(_null_path, raw_mem); - } else { - region->del_req(_null_path); - val_phi->del_req(_null_path); - raw_mem_phi->del_req(_null_path); - } - // Test for in-cset. // Wires !in_cset(obj) to slot 2 of region and phis Node* not_cset_ctrl = NULL; - test_in_cset(ctrl, not_cset_ctrl, uncasted_val, raw_mem, phase); + test_in_cset(ctrl, not_cset_ctrl, val, raw_mem, phase); if (not_cset_ctrl != NULL) { - if (reg2_ctrl == NULL) reg2_ctrl = not_cset_ctrl->in(0); region->init_req(_not_cset, not_cset_ctrl); - val_phi->init_req(_not_cset, uncasted_val); + val_phi->init_req(_not_cset, val); raw_mem_phi->init_req(_not_cset, raw_mem); } // Resolve object when orig-value is in cset. // Make the unconditional resolve for fwdptr. - Node* new_val = uncasted_val; - if (unc_ctrl != NULL) { - // Clone the null check in this branch to allow implicit null check - new_val = clone_null_check(ctrl, val, unc_ctrl, phase); - fix_null_check(unc, unc_ctrl, ctrl->in(0)->as_If()->proj_out(0), uses, phase); - - IfNode* iff = unc_ctrl->in(0)->as_If(); - phase->igvn().replace_input_of(iff, 1, phase->igvn().intcon(1)); - } // Call lrb-stub and wire up that path in slots 4 Node* result_mem = NULL; - Node* fwd = new_val; Node* addr; if (ShenandoahSelfFixing) { VectorSet visited(Thread::current()->resource_area()); @@ -1532,9 +1358,9 @@ void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) { } } } - call_lrb_stub(ctrl, fwd, addr, result_mem, raw_mem, lrb->is_native(), phase); + call_lrb_stub(ctrl, val, addr, result_mem, raw_mem, lrb->is_native(), phase); region->init_req(_evac_path, ctrl); - val_phi->init_req(_evac_path, fwd); + val_phi->init_req(_evac_path, val); raw_mem_phi->init_req(_evac_path, result_mem); phase->register_control(region, loop, heap_stable_iff); @@ -1546,20 +1372,6 @@ void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) { ctrl = orig_ctrl; - if (unc != NULL) { - for (DUIterator_Fast imax, i = val->fast_outs(imax); i < imax; i++) { - Node* u = val->fast_out(i); - Node* c = phase->ctrl_or_self(u); - if (u != lrb && (c != ctrl || is_dominator_same_ctrl(c, lrb, u, phase))) { - phase->igvn().rehash_node_delayed(u); - int nb = u->replace_edge(val, out_val); - --i, imax -= nb; - } - } - if (val->outcnt() == 0) { - phase->igvn()._worklist.push(val); - } - } phase->igvn().replace_node(lrb, out_val); follow_barrier_uses(out_val, ctrl, uses, phase); @@ -3328,26 +3140,3 @@ bool ShenandoahLoadReferenceBarrierNode::is_redundant() { // No need for barrier found. return true; } - -CallStaticJavaNode* ShenandoahLoadReferenceBarrierNode::pin_and_expand_null_check(PhaseIterGVN& igvn) { - Node* val = in(ValueIn); - - const Type* val_t = igvn.type(val); - - if (val_t->meet(TypePtr::NULL_PTR) != val_t && - val->Opcode() == Op_CastPP && - val->in(0) != NULL && - val->in(0)->Opcode() == Op_IfTrue && - val->in(0)->as_Proj()->is_uncommon_trap_if_pattern(Deoptimization::Reason_none) && - val->in(0)->in(0)->is_If() && - val->in(0)->in(0)->in(1)->Opcode() == Op_Bool && - val->in(0)->in(0)->in(1)->as_Bool()->_test._test == BoolTest::ne && - val->in(0)->in(0)->in(1)->in(1)->Opcode() == Op_CmpP && - val->in(0)->in(0)->in(1)->in(1)->in(1) == val->in(1) && - val->in(0)->in(0)->in(1)->in(1)->in(2)->bottom_type() == TypePtr::NULL_PTR) { - assert(val->in(0)->in(0)->in(1)->in(1)->in(1) == val->in(1), ""); - CallStaticJavaNode* unc = val->in(0)->as_Proj()->is_uncommon_trap_if_pattern(Deoptimization::Reason_none); - return unc; - } - return NULL; -} diff --git a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp index 1fbd24a0cbd..3e15fa09937 100644 --- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp +++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp @@ -63,9 +63,6 @@ private: static void call_lrb_stub(Node*& ctrl, Node*& val, Node* load_addr, Node*& result_mem, Node* raw_mem, bool is_native, PhaseIdealLoop* phase); static void test_in_cset(Node*& ctrl, Node*& not_cset_ctrl, Node* val, Node* raw_mem, PhaseIdealLoop* phase); static void move_gc_state_test_out_of_loop(IfNode* iff, PhaseIdealLoop* phase); - static Node* clone_null_check(Node*& c, Node* val, Node* unc_ctrl, PhaseIdealLoop* phase); - static void fix_null_check(Node* unc, Node* unc_ctrl, Node* new_unc_ctrl, Unique_Node_List& uses, - PhaseIdealLoop* phase); static void merge_back_to_back_tests(Node* n, PhaseIdealLoop* phase); static bool identical_backtoback_ifs(Node *n, PhaseIdealLoop* phase); static void fix_ctrl(Node* barrier, Node* region, const MemoryGraphFixer& fixer, Unique_Node_List& uses, Unique_Node_List& uses_to_ignore, uint last, PhaseIdealLoop* phase); @@ -254,7 +251,6 @@ public: virtual bool cmp( const Node &n ) const; bool is_redundant(); - CallStaticJavaNode* pin_and_expand_null_check(PhaseIterGVN& igvn); private: bool needs_barrier(PhaseGVN* phase, Node* n); From 35a7eff951e2f5cd2e9da0239412c6210d8b52ad Mon Sep 17 00:00:00 2001 From: Roland Westrelin Date: Fri, 15 May 2020 10:24:38 +0200 Subject: [PATCH 080/143] 8244721: CTW: C2 (Shenandoah) compilation fails with "unexpected infinite loop graph shape" Reviewed-by: shade --- .../gc/shenandoah/c2/shenandoahSupport.cpp | 37 +++++++++++------- .../compiler/BarrierInInfiniteLoop.java | 38 +++++++++++++++++-- 2 files changed, 58 insertions(+), 17 deletions(-) diff --git a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp index aac3d39a1fc..cdd900e02e5 100644 --- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp +++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp @@ -2101,17 +2101,7 @@ void MemoryGraphFixer::collect_memory_nodes() { mem = call->in(TypeFunc::Memory); } else if (in->Opcode() == Op_NeverBranch) { Node* head = in->in(0); - assert(head->is_Region() && head->req() == 3, "unexpected infinite loop graph shape"); - assert(_phase->is_dominator(head, head->in(1)) || _phase->is_dominator(head, head->in(2)), "no back branch?"); - Node* tail = _phase->is_dominator(head, head->in(1)) ? head->in(1) : head->in(2); - Node* c = tail; - while (c != head) { - if (c->is_SafePoint() && !c->is_CallLeaf()) { - mem = c->in(TypeFunc::Memory); - } - c = _phase->idom(c); - } - assert(mem != NULL, "should have found safepoint"); + assert(head->is_Region(), "unexpected infinite loop graph shape"); Node* phi_mem = NULL; for (DUIterator_Fast jmax, j = head->fast_outs(jmax); j < jmax; j++) { @@ -2128,7 +2118,28 @@ void MemoryGraphFixer::collect_memory_nodes() { } } } - if (phi_mem != NULL) { + if (phi_mem == NULL) { + for (uint j = 1; j < head->req(); j++) { + Node* tail = head->in(j); + if (!_phase->is_dominator(head, tail)) { + continue; + } + Node* c = tail; + while (c != head) { + if (c->is_SafePoint() && !c->is_CallLeaf()) { + Node* m =c->in(TypeFunc::Memory); + if (m->is_MergeMem()) { + m = m->as_MergeMem()->memory_at(_alias); + } + assert(mem == NULL || mem == m, "several memory states"); + mem = m; + } + c = _phase->idom(c); + } + assert(mem != NULL, "should have found safepoint"); + } + assert(mem != NULL, "should have found safepoint"); + } else { mem = phi_mem; } } @@ -2237,7 +2248,7 @@ void MemoryGraphFixer::collect_memory_nodes() { assert(m != NULL || (c->is_Loop() && j == LoopNode::LoopBackControl && iteration == 1) || _phase->C->has_irreducible_loop() || has_never_branch(_phase->C->root()), "expect memory state"); if (m != NULL) { if (m == prev_region && ((c->is_Loop() && j == LoopNode::LoopBackControl) || (prev_region->is_Phi() && prev_region->in(0) == c))) { - assert(c->is_Loop() && j == LoopNode::LoopBackControl || _phase->C->has_irreducible_loop(), ""); + assert(c->is_Loop() && j == LoopNode::LoopBackControl || _phase->C->has_irreducible_loop() || has_never_branch(_phase->C->root()), ""); // continue } else if (unique == NULL) { unique = m; diff --git a/test/hotspot/jtreg/gc/shenandoah/compiler/BarrierInInfiniteLoop.java b/test/hotspot/jtreg/gc/shenandoah/compiler/BarrierInInfiniteLoop.java index f391cfb5628..edf5c0036da 100644 --- a/test/hotspot/jtreg/gc/shenandoah/compiler/BarrierInInfiniteLoop.java +++ b/test/hotspot/jtreg/gc/shenandoah/compiler/BarrierInInfiniteLoop.java @@ -23,29 +23,59 @@ /** * @test - * @bug 8237837 + * @bug 8237837 8244721 * @summary Shenandoah: assert(mem == __null) failed: only one safepoint * @key gc * @requires vm.flavor == "server" * @requires vm.gc.Shenandoah & !vm.graal.enabled * - * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xcomp -XX:CompileOnly=BarrierInInfiniteLoop::test -XX:CompileCommand=quiet BarrierInInfiniteLoop + * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xcomp -XX:CompileOnly=BarrierInInfiniteLoop::test1 + * -XX:CompileOnly=BarrierInInfiniteLoop::test2 -XX:CompileOnly=BarrierInInfiniteLoop::test3 -XX:CompileCommand=quiet BarrierInInfiniteLoop * */ public class BarrierInInfiniteLoop { private static Object field1 = new Object(); private static Object field2 = new Object(); + private static int field3; public static void main(String[] args) { - test(false); + test1(false); + test2(false, false); + test3(false); } - private static void test(boolean flag) { + private static void test1(boolean flag) { if (flag) { for (;;) { field1 = field2; } } } + + private static void test2(boolean flag1, boolean flag2) { + if (flag1) { + for (;;) { + for (;;) { + if (flag2) { + break; + } + field1 = field2; + } + } + } + } + + private static void test3(boolean flag) { + if (flag) { + for (;;) { + for (;;) { + field3 = 42; + if (field1 == field2) { + break; + } + } + } + } + } } From 36fb21dc2f007c4879dbfbef0dbdebf93f20aa35 Mon Sep 17 00:00:00 2001 From: Pavel Rappo Date: Fri, 15 May 2020 20:38:28 +0100 Subject: [PATCH 081/143] 8245111: Update doc comments for improved processing by the Standard Doclet Reviewed-by: dfuchs, joehw, lancea, rriggs --- src/java.base/share/classes/java/lang/StackTraceElement.java | 4 ++-- .../share/classes/java/lang/invoke/MethodHandles.java | 4 ++-- src/java.base/share/classes/java/util/jar/Attributes.java | 4 ++-- .../share/classes/java/util/logging/SimpleFormatter.java | 4 ++-- .../share/classes/javax/naming/NameNotFoundException.java | 4 ++-- .../share/classes/javax/xml/transform/TransformerFactory.java | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/java.base/share/classes/java/lang/StackTraceElement.java b/src/java.base/share/classes/java/lang/StackTraceElement.java index 960e4e3865c..cbbae0e248d 100644 --- a/src/java.base/share/classes/java/lang/StackTraceElement.java +++ b/src/java.base/share/classes/java/lang/StackTraceElement.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2019, 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 @@ -302,7 +302,7 @@ public final class StackTraceElement implements java.io.Serializable { * * *

The first example shows a stack trace element consisting of - * three elements, each separated by {@code "/"} followed with + * three elements, each separated by {@code "/"}, followed by * the source file name and the line number of the source line * containing the execution point. * diff --git a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java index 21cc3912593..133250e0437 100644 --- a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java +++ b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java @@ -2227,8 +2227,8 @@ public class MethodHandles { } /** - * Displays the name of the class from which lookups are to be made. - * followed with "/" and the name of the {@linkplain #previousLookupClass() + * Displays the name of the class from which lookups are to be made, + * followed by "/" and the name of the {@linkplain #previousLookupClass() * previous lookup class} if present. * (The name is the one reported by {@link java.lang.Class#getName() Class.getName}.) * If there are restrictions on the access permitted to this lookup, diff --git a/src/java.base/share/classes/java/util/jar/Attributes.java b/src/java.base/share/classes/java/util/jar/Attributes.java index db8217dfbd8..79cb2fe1c47 100644 --- a/src/java.base/share/classes/java/util/jar/Attributes.java +++ b/src/java.base/share/classes/java/util/jar/Attributes.java @@ -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 @@ -591,7 +591,7 @@ public class Attributes implements Map, Cloneable { public static final Name EXTENSION_LIST; /** - * {@code Name} object for {@code Extension-Name} manifest attribute. + * {@code Name} object for {@code Extension-Name} manifest attribute * used for the extension mechanism that is no longer supported. */ public static final Name EXTENSION_NAME; diff --git a/src/java.logging/share/classes/java/util/logging/SimpleFormatter.java b/src/java.logging/share/classes/java/util/logging/SimpleFormatter.java index ff74db9f61c..601b3b78417 100644 --- a/src/java.logging/share/classes/java/util/logging/SimpleFormatter.java +++ b/src/java.logging/share/classes/java/util/logging/SimpleFormatter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2018, 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 @@ -114,7 +114,7 @@ public class SimpleFormatter extends Formatter { *

This prints 2 lines where the first line includes * the timestamp ({@code 1$}) and the source ({@code 2$}); * the second line includes the log level ({@code 4$}) and - * the log message ({@code 5$}) followed with the throwable + * the log message ({@code 5$}) followed by the throwable * and its backtrace ({@code 6$}), if any: *

      *     Tue Mar 22 13:11:31 PDT 2011 MyClass fatal
diff --git a/src/java.naming/share/classes/javax/naming/NameNotFoundException.java b/src/java.naming/share/classes/javax/naming/NameNotFoundException.java
index e3dec4ead51..c1fd5eb0594 100644
--- a/src/java.naming/share/classes/javax/naming/NameNotFoundException.java
+++ b/src/java.naming/share/classes/javax/naming/NameNotFoundException.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 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
@@ -52,7 +52,7 @@ public class NameNotFoundException extends NamingException {
 
     /**
       * Constructs a new instance of NameNotFoundException.
-      * all name resolution fields and explanation initialized to null.
+      * All name resolution fields and explanation are initialized to null.
       */
     public NameNotFoundException() {
         super();
diff --git a/src/java.xml/share/classes/javax/xml/transform/TransformerFactory.java b/src/java.xml/share/classes/javax/xml/transform/TransformerFactory.java
index 42410d7629a..0f2a9c852d6 100644
--- a/src/java.xml/share/classes/javax/xml/transform/TransformerFactory.java
+++ b/src/java.xml/share/classes/javax/xml/transform/TransformerFactory.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2017, 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
@@ -205,7 +205,7 @@ public abstract class TransformerFactory {
 
     /**
      * Create a new {@code Transformer} that performs a copy
-     * of the {@code Source} to the {@code Result}.
+     * of the {@code Source} to the {@code Result},
      * i.e. the "identity transform".
      *
      * @return A Transformer object that may be used to perform a transformation

From 6d985025509b2197f441e2e1ef3cf9b686ddc407 Mon Sep 17 00:00:00 2001
From: Roland Westrelin 
Date: Fri, 15 May 2020 21:54:28 +0200
Subject: [PATCH 082/143] 8244663: Shenandoah: C2 assertion fails in
 Matcher::collect_null_checks

Reviewed-by: shade
---
 .../gc/shenandoah/c2/shenandoahSupport.cpp    | 34 +++++++-
 .../compiler/TestShenandoahCmpPAfterCall.java | 80 +++++++++++++++++++
 2 files changed, 111 insertions(+), 3 deletions(-)
 create mode 100644 test/hotspot/jtreg/gc/shenandoah/compiler/TestShenandoahCmpPAfterCall.java

diff --git a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp
index cdd900e02e5..19f1deab8d8 100644
--- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp
+++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp
@@ -1178,6 +1178,9 @@ void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) {
       CallProjections projs;
       call->extract_projections(&projs, false, false);
 
+#ifdef ASSERT
+      VectorSet cloned(Thread::current()->resource_area());
+#endif
       Node* lrb_clone = lrb->clone();
       phase->register_new_node(lrb_clone, projs.catchall_catchproj);
       phase->set_ctrl(lrb, projs.fallthrough_catchproj);
@@ -1206,6 +1209,7 @@ void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) {
             stack.set_index(idx+1);
             assert(!u->is_CFG(), "");
             stack.push(u, 0);
+            assert(!cloned.test_set(u->_idx), "only one clone");
             Node* u_clone = u->clone();
             int nb = u_clone->replace_edge(n, n_clone);
             assert(nb > 0, "should have replaced some uses");
@@ -1233,9 +1237,33 @@ void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) {
                 assert(nb > 0, "should have replaced some uses");
                 replaced = true;
               } else if (!phase->is_dominator(projs.fallthrough_catchproj, c)) {
-                phase->igvn().rehash_node_delayed(u);
-                int nb = u->replace_edge(n, create_phis_on_call_return(ctrl, c, n, n_clone, projs, phase));
-                assert(nb > 0, "should have replaced some uses");
+                if (u->is_If()) {
+                  // Can't break If/Bool/Cmp chain
+                  assert(n->is_Bool(), "unexpected If shape");
+                  assert(stack.node_at(stack.size()-2)->is_Cmp(), "unexpected If shape");
+                  assert(n_clone->is_Bool(), "unexpected clone");
+                  assert(clones.at(clones.size()-2)->is_Cmp(), "unexpected clone");
+                  Node* bol_clone = n->clone();
+                  Node* cmp_clone = stack.node_at(stack.size()-2)->clone();
+                  bol_clone->set_req(1, cmp_clone);
+
+                  Node* nn = stack.node_at(stack.size()-3);
+                  Node* nn_clone = clones.at(clones.size()-3);
+                  assert(nn->Opcode() == nn_clone->Opcode(), "mismatch");
+
+                  int nb = cmp_clone->replace_edge(nn, create_phis_on_call_return(ctrl, c, nn, nn_clone, projs, phase));
+                  assert(nb > 0, "should have replaced some uses");
+
+                  phase->register_new_node(bol_clone, u->in(0));
+                  phase->register_new_node(cmp_clone, u->in(0));
+
+                  phase->igvn().replace_input_of(u, 1, bol_clone);
+
+                } else {
+                  phase->igvn().rehash_node_delayed(u);
+                  int nb = u->replace_edge(n, create_phis_on_call_return(ctrl, c, n, n_clone, projs, phase));
+                  assert(nb > 0, "should have replaced some uses");
+                }
                 replaced = true;
               }
             }
diff --git a/test/hotspot/jtreg/gc/shenandoah/compiler/TestShenandoahCmpPAfterCall.java b/test/hotspot/jtreg/gc/shenandoah/compiler/TestShenandoahCmpPAfterCall.java
new file mode 100644
index 00000000000..9d4512db436
--- /dev/null
+++ b/test/hotspot/jtreg/gc/shenandoah/compiler/TestShenandoahCmpPAfterCall.java
@@ -0,0 +1,80 @@
+/*
+ * 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 8244663
+ * @summary Shenandoah: C2 assertion fails in Matcher::collect_null_checks
+ * @key gc
+ * @requires vm.flavor == "server"
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ *
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:-TieredCompilation -XX:-BackgroundCompilation -XX:-UseOnStackReplacement
+ *                   -XX:CompileCommand=dontinline,TestShenandoahCmpPAfterCall::not_inlined TestShenandoahCmpPAfterCall
+ *
+ */
+
+public class TestShenandoahCmpPAfterCall {
+    private static Object field1 = new Object();
+    private static Object field2 = new Object();
+    private static Object o3;
+    private static volatile int barrier;
+
+    public static void main(String[] args) {
+        for (int i = 0; i < 20_000; i++) {
+            test();
+        }
+    }
+
+    private static void test() {
+        Object o1 = null;
+        Object o2 = field2;
+        try {
+            not_inlined();
+            o1 = field1;
+            if (o1 == o2) {
+
+            }
+        } catch (Exception1 ex1) {
+            o1 = field1;
+            if (o1 == o2) {
+
+            }
+        }
+        barrier = 42;
+        if (o1 == o2) {
+
+        }
+    }
+
+    static int count = 0;
+    private static void not_inlined() throws Exception1 {
+        count++;
+        if ((count % 100) == 0) {
+            throw new Exception1();
+        }
+    }
+
+    private static class Exception1 extends Exception {
+    }
+}

From 1e251e9471931c1bfbbe6dcf84691cc24f054ba3 Mon Sep 17 00:00:00 2001
From: Roland Westrelin 
Date: Wed, 13 May 2020 17:00:59 +0200
Subject: [PATCH 083/143] 8241070: Shenandoah: remove unused local variables in
 C2 support

Reviewed-by: shade
---
 src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp | 1 -
 src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp      | 4 +---
 2 files changed, 1 insertion(+), 4 deletions(-)

diff --git a/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp b/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp
index 184b290b2ac..01aa950120e 100644
--- a/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp
+++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp
@@ -525,7 +525,6 @@ Node* ShenandoahBarrierSetC2::store_at_resolved(C2Access& access, C2AccessValue&
     assert(((decorators & C2_TIGHTLY_COUPLED_ALLOC) != 0 || !ShenandoahSATBBarrier) && (decorators & C2_ARRAY_COPY) != 0, "unexpected caller of this code");
     C2OptAccess& opt_access = static_cast(access);
     PhaseGVN& gvn =  opt_access.gvn();
-    MergeMemNode* mm = opt_access.mem();
 
     if (ShenandoahStoreValEnqueueBarrier) {
       Node* enqueue = gvn.transform(new ShenandoahEnqueueBarrierNode(val.node()));
diff --git a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp
index 19f1deab8d8..edc78a11999 100644
--- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp
+++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp
@@ -788,7 +788,6 @@ Node* ShenandoahBarrierC2Support::find_bottom_mem(Node* ctrl, PhaseIdealLoop* ph
   Node* c = ctrl;
   do {
     if (c->is_Region()) {
-      Node* phi_bottom = NULL;
       for (DUIterator_Fast imax, i = c->fast_outs(imax); i < imax && mem == NULL; i++) {
         Node* u = c->fast_out(i);
         if (u->is_Phi() && u->bottom_type() == Type::MEMORY) {
@@ -1672,7 +1671,6 @@ void ShenandoahBarrierC2Support::move_gc_state_test_out_of_loop(IfNode* iff, Pha
     bol->set_req(1, cmp);
     phase->register_new_node(bol, entry_c);
 
-    Node* old_bol =iff->in(1);
     phase->igvn().replace_input_of(iff, 1, bol);
   }
 }
@@ -2263,7 +2261,7 @@ void MemoryGraphFixer::collect_memory_nodes() {
     iteration++;
     assert(iteration <= 2+max_depth || _phase->C->has_irreducible_loop() || has_never_branch(_phase->C->root()), "");
     if (trace) { tty->print_cr("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"); }
-    IdealLoopTree* last_updated_ilt = NULL;
+
     for (int i = rpo_list.size() - 1; i >= 0; i--) {
       Node* c = rpo_list.at(i);
 

From 46cf294250bdbb59566fe0e261b6f6d354acde48 Mon Sep 17 00:00:00 2001
From: John Jiang 
Date: Sat, 16 May 2020 05:49:47 +0800
Subject: [PATCH 084/143] 8245005:
 javax/net/ssl/compatibility/BasicConnectTest.java failed with No enum
 constant

Reviewed-by: xuelei
---
 .../javax/net/ssl/TLSCommon/CipherSuite.java  | 26 ++++++++++++++++---
 .../net/ssl/TLSCommon/interop/Utilities.java  |  6 ++---
 test/jdk/javax/net/ssl/compatibility/README   |  4 +--
 3 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/test/jdk/javax/net/ssl/TLSCommon/CipherSuite.java b/test/jdk/javax/net/ssl/TLSCommon/CipherSuite.java
index 3ff943b199f..a47a6e82afc 100644
--- a/test/jdk/javax/net/ssl/TLSCommon/CipherSuite.java
+++ b/test/jdk/javax/net/ssl/TLSCommon/CipherSuite.java
@@ -172,12 +172,32 @@ public enum CipherSuite {
             0x0032, KeyExAlgorithm.DHE_DSS, Protocol.SSLV3, Protocol.TLSV1_2),
     TLS_RSA_WITH_AES_128_CBC_SHA(
             0x002F, KeyExAlgorithm.RSA, Protocol.SSLV3, Protocol.TLSV1_2),
+    TLS_KRB5_EXPORT_WITH_RC4_40_MD5(
+            0x002B, KeyExAlgorithm.KRB5, Protocol.SSLV3, Protocol.TLSV1_2),
+    TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5(
+            0x002A, KeyExAlgorithm.KRB5, Protocol.SSLV3, Protocol.TLSV1_2),
+    TLS_KRB5_EXPORT_WITH_RC4_40_SHA(
+            0x0028, KeyExAlgorithm.KRB5, Protocol.SSLV3, Protocol.TLSV1_2),
+    TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5(
+            0x0029, KeyExAlgorithm.KRB5, Protocol.SSLV3, Protocol.TLSV1_1),
+    TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA(
+            0x0027, KeyExAlgorithm.KRB5, Protocol.SSLV3, Protocol.TLSV1_2),
+    TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA(
+            0x0026, KeyExAlgorithm.KRB5, Protocol.SSLV3, Protocol.TLSV1_1),
+    TLS_KRB5_WITH_IDEA_CBC_MD5(
+            0x0025, KeyExAlgorithm.KRB5, Protocol.SSLV3, Protocol.TLSV1_1),
+    TLS_KRB5_WITH_RC4_128_MD5(
+            0x0024, KeyExAlgorithm.KRB5, Protocol.SSLV3, Protocol.TLSV1_2),
     TLS_KRB5_WITH_3DES_EDE_CBC_MD5(
-            0x0023, KeyExAlgorithm.KRB5, Protocol.SSLV3, Protocol.TLSV1_2),
+            0x0023, KeyExAlgorithm.KRB5, Protocol.SSLV3, Protocol.TLSV1_1),
     TLS_KRB5_WITH_DES_CBC_MD5(
-            0x0022,KeyExAlgorithm.KRB5,  Protocol.SSLV3, Protocol.TLSV1_1),
+            0x0022, KeyExAlgorithm.KRB5,  Protocol.SSLV3, Protocol.TLSV1_1),
+    TLS_KRB5_WITH_IDEA_CBC_SHA(
+            0x0021, KeyExAlgorithm.KRB5, Protocol.SSLV3, Protocol.TLSV1_1),
+    TLS_KRB5_WITH_RC4_128_SHA(
+            0x0020, KeyExAlgorithm.KRB5, Protocol.SSLV3, Protocol.TLSV1_2),
     TLS_KRB5_WITH_3DES_EDE_CBC_SHA(
-            0x001F, KeyExAlgorithm.KRB5, Protocol.SSLV3, Protocol.TLSV1_2),
+            0x001F, KeyExAlgorithm.KRB5, Protocol.SSLV3, Protocol.TLSV1_1),
     TLS_KRB5_WITH_DES_CBC_SHA(
             0x001E, KeyExAlgorithm.KRB5, Protocol.SSLV3, Protocol.TLSV1_2),
     SSL_DH_anon_WITH_3DES_EDE_CBC_SHA(
diff --git a/test/jdk/javax/net/ssl/TLSCommon/interop/Utilities.java b/test/jdk/javax/net/ssl/TLSCommon/interop/Utilities.java
index 36c6f0ec0e7..735c72ac3a9 100644
--- a/test/jdk/javax/net/ssl/TLSCommon/interop/Utilities.java
+++ b/test/jdk/javax/net/ssl/TLSCommon/interop/Utilities.java
@@ -80,8 +80,7 @@ public class Utilities {
     public static final String PARAM_DELIMITER = ";";
     public static final String VALUE_DELIMITER = ",";
 
-    public static final CipherSuite[] ALL_CIPHER_SUITES
-            = Utilities.getAllCipherSuites();
+    public static final CipherSuite[] ALL_CIPHER_SUITES = getAllCipherSuites();
 
     /*
      * Gets all supported cipher suites.
@@ -101,8 +100,7 @@ public class Utilities {
                 .map(cipherSuite -> {
                     return CipherSuite.cipherSuite(cipherSuite);})
                 .filter(cipherSuite -> {
-                    return cipherSuite
-                            != CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV;})
+                    return cipherSuite != CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV; })
                 .toArray(CipherSuite[]::new);
 
         return cipherSuites;
diff --git a/test/jdk/javax/net/ssl/compatibility/README b/test/jdk/javax/net/ssl/compatibility/README
index a0367da7c59..e07623c311e 100644
--- a/test/jdk/javax/net/ssl/compatibility/README
+++ b/test/jdk/javax/net/ssl/compatibility/README
@@ -30,7 +30,7 @@ different JDK releases can load and run associated classes.
 jtreg [-options] \
     [-Dtest.debug=] \
     [-Dtest.jdk.list.file=] \
-    $JDK_WORKSPACE/test/jdk/javax/net/ssl/compatibility/Compatibility.java
+    $JDK_WORKSPACE/test/jdk/javax/net/ssl/compatibility/
 
 Besides the common jtreg options, like -jdk, this test introduces some more
 properties:
@@ -54,7 +54,7 @@ $ cat /path/to/jdkList
 $ jtreg -jdk:/path/to/latest/jdk \
     -Ddebug=true \
     -Dtest.jdk.list.file=/path/to/jdkList \
-    $JDK_WS/jdk/test/javax/net/ssl/compatibility/Compatibility.java
+    $JDK_WS/jdk/test/javax/net/ssl/compatibility/
 The above example uses a file "/path/to/jdkList" to contain the paths of local
 different JDK builds through 8 to 10. The execution uses each of JDK builds as
 server and client respectively. And it enables SSL debug flag, and tests the

From a09720f2ee56f52ee858edf3ad22f8612c7bc4a5 Mon Sep 17 00:00:00 2001
From: Claes Redestad 
Date: Sat, 16 May 2020 01:35:38 +0200
Subject: [PATCH 085/143] 8232213: runtime/MemberName/MemberNameLeak.java fails
 intermittently

Reviewed-by: dcubed, coleenp
---
 test/hotspot/jtreg/runtime/MemberName/MemberNameLeak.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test/hotspot/jtreg/runtime/MemberName/MemberNameLeak.java b/test/hotspot/jtreg/runtime/MemberName/MemberNameLeak.java
index 6b1399e7243..e52396f2593 100644
--- a/test/hotspot/jtreg/runtime/MemberName/MemberNameLeak.java
+++ b/test/hotspot/jtreg/runtime/MemberName/MemberNameLeak.java
@@ -103,7 +103,7 @@ public class MemberNameLeak {
             System.gc();  // make mh unused
           }
 
-          if (after != wb.resolvedMethodItemsCount()) {
+          if (after > wb.resolvedMethodItemsCount() + 50) {
             // Entries have been removed.
             break;
           }

From a2057ad44096e40ecd318e545861f30b57c920ae Mon Sep 17 00:00:00 2001
From: Magnus Ihse Bursie 
Date: Sat, 16 May 2020 09:43:44 +0200
Subject: [PATCH 086/143] 8240228: "make hotspot-ide-project" on Windows
 creates a Visual Studio project with empty preprocessor defines

Reviewed-by: erikj
---
 make/hotspot/ide/CreateVSProject.gmk | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/make/hotspot/ide/CreateVSProject.gmk b/make/hotspot/ide/CreateVSProject.gmk
index d001499d408..6bd1f71c939 100644
--- a/make/hotspot/ide/CreateVSProject.gmk
+++ b/make/hotspot/ide/CreateVSProject.gmk
@@ -35,8 +35,8 @@ ifeq ($(call isTargetOs, windows), true)
   # The next part is a bit hacky. We include the CompileJvm.gmk to be
   # able to extact flags, but we do not wish to execute the rules.
 
-  # Use client as base for defines and includes
-  JVM_VARIANT=client
+  # Use server as base for defines and includes
+  JVM_VARIANT=server
 
   include HotspotCommon.gmk
   include lib/CompileJvm.gmk

From 9efdaacc31696b762bee25ea5c74dc1f514905fe Mon Sep 17 00:00:00 2001
From: Vicente Romero 
Date: Sun, 17 May 2020 11:09:52 -0400
Subject: [PATCH 087/143] 8242478: compiler implementation for records (Second
 Preview)

Reviewed-by: mcimadamore, jlahoda, darcy
---
 .../classes/java/io/ObjectStreamClass.java    |   2 +-
 .../com/sun/tools/javac/code/Flags.java       |   2 +-
 .../com/sun/tools/javac/code/Symbol.java      |  16 +-
 .../com/sun/tools/javac/comp/Attr.java        |  47 +-
 .../com/sun/tools/javac/comp/Check.java       |  35 +-
 .../com/sun/tools/javac/comp/TypeEnter.java   |  34 +-
 .../sun/tools/javac/parser/JavacParser.java   |  14 +-
 .../tools/javac/resources/compiler.properties |  16 +-
 .../records/ConstructorPermissionTest.java    |   4 +-
 .../javac/combo/CompilationTestCase.java      |  22 +
 .../combo/tools/javac/combo/Diagnostics.java  |   2 +-
 .../javac/combo/JavacTemplateTestBase.java    |   5 +-
 .../tools/javac/IllegalAnnotation.java        |   1 +
 .../tools/javac/IllegalAnnotation.out         |   2 +-
 .../tools/javac/InterfaceInInner.out          |   2 +-
 .../langtools/tools/javac/LocalInterface.java |  13 +
 test/langtools/tools/javac/LocalInterface.out |   2 +
 test/langtools/tools/javac/LocalRecord.java   |  34 ++
 ...icalCantHaveStrongerAccessPrivileges.java} |   9 +-
 .../diags/examples/EnumsMustBeStatic.java     |   4 +-
 .../RecordsNotAllowedInInnerClasses.java      |   4 +-
 .../langtools/tools/javac/enum/LocalEnum.java |   1 +
 test/langtools/tools/javac/enum/LocalEnum.out |   2 +-
 .../langtools/tools/javac/enum/NestedEnum.out |   2 +-
 test/langtools/tools/javac/enum/T5081785.out  |   8 +-
 .../CheckingTypeAnnotationsOnRecords.java     |   3 +-
 .../model/element/TestRecordDesugar.java      |   8 +-
 .../records/LocalStaticDeclarations.java      | 229 +++++++++
 .../javac/records/RecordCompilationTests.java | 451 +++++++++++++++---
 .../javac/records/RecordMemberTests.java      |  33 +-
 .../javac/records/VarargsRecordsTest.java     |   8 +-
 31 files changed, 833 insertions(+), 182 deletions(-)
 create mode 100644 test/langtools/tools/javac/LocalInterface.java
 create mode 100644 test/langtools/tools/javac/LocalInterface.out
 create mode 100644 test/langtools/tools/javac/LocalRecord.java
 rename test/langtools/tools/javac/diags/examples/{CanonicalConstructorMustBePublic.java => CanonicalCantHaveStrongerAccessPrivileges.java} (83%)
 create mode 100644 test/langtools/tools/javac/records/LocalStaticDeclarations.java

diff --git a/src/java.base/share/classes/java/io/ObjectStreamClass.java b/src/java.base/share/classes/java/io/ObjectStreamClass.java
index dfcb558e497..0a912063d2e 100644
--- a/src/java.base/share/classes/java/io/ObjectStreamClass.java
+++ b/src/java.base/share/classes/java/io/ObjectStreamClass.java
@@ -1585,7 +1585,7 @@ public class ObjectStreamClass implements Serializable {
                                           .map(RecordComponent::getType)
                                           .toArray(Class[]::new);
             try {
-                Constructor ctr = cls.getConstructor(paramTypes);
+                Constructor ctr = cls.getDeclaredConstructor(paramTypes);
                 ctr.setAccessible(true);
                 return MethodHandles.lookup().unreflectConstructor(ctr);
             } catch (IllegalAccessException | NoSuchMethodException e) {
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java
index 7038c73c12f..b5e9436d5e5 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java
@@ -371,7 +371,7 @@ public class Flags {
     public static final int
         AccessFlags           = PUBLIC | PROTECTED | PRIVATE,
         LocalClassFlags       = FINAL | ABSTRACT | STRICTFP | ENUM | SYNTHETIC,
-        LocalRecordFlags      = LocalClassFlags | STATIC,
+        StaticLocalFlags      = LocalClassFlags | STATIC | INTERFACE | ANNOTATION,
         MemberClassFlags      = LocalClassFlags | INTERFACE | AccessFlags,
         MemberRecordFlags     = MemberClassFlags | STATIC,
         ClassFlags            = LocalClassFlags | INTERFACE | PUBLIC | ANNOTATION,
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java
index 9d430005c63..79630ecb101 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java
@@ -1491,7 +1491,10 @@ public abstract class Symbol extends AnnoConstruct implements PoolConstant, Elem
 
         public RecordComponent getRecordComponent(JCVariableDecl var, boolean addIfMissing, List annotations) {
             for (RecordComponent rc : recordComponents) {
-                if (rc.name == var.name) {
+                /* it could be that a record erroneously declares two record components with the same name, in that
+                 * case we need to use the position to disambiguate
+                 */
+                if (rc.name == var.name && var.pos == rc.pos) {
                     return rc;
                 }
             }
@@ -1753,7 +1756,13 @@ public abstract class Symbol extends AnnoConstruct implements PoolConstant, Elem
     public static class RecordComponent extends VarSymbol implements RecordComponentElement {
         public MethodSymbol accessor;
         public JCTree.JCMethodDecl accessorMeth;
+        /* the original annotations applied to the record component
+         */
         private final List originalAnnos;
+        /* if the user happens to erroneously declare two components with the same name, we need a way to differentiate
+         * them, the code will fail anyway but we need to keep the information for better error recovery
+         */
+        private final int pos;
 
         /**
          * Construct a record component, given its flags, name, type and owner.
@@ -1761,10 +1770,15 @@ public abstract class Symbol extends AnnoConstruct implements PoolConstant, Elem
         public RecordComponent(JCVariableDecl fieldDecl, List annotations) {
             super(PUBLIC, fieldDecl.sym.name, fieldDecl.sym.type, fieldDecl.sym.owner);
             this.originalAnnos = annotations;
+            this.pos = fieldDecl.pos;
         }
 
         public List getOriginalAnnos() { return originalAnnos; }
 
+        public boolean isVarargs() {
+            return type.hasTag(TypeTag.ARRAY) && ((ArrayType)type).isVarargs();
+        }
+
         @Override @DefinedBy(Api.LANGUAGE_MODEL)
         @SuppressWarnings("preview")
         public ElementKind getKind() {
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java
index 100ba6684f3..6e2023abb9c 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java
@@ -274,7 +274,7 @@ public class Attr extends JCTree.Visitor {
         Symbol owner = env.info.scope.owner;
            // owner refers to the innermost variable, method or
            // initializer block declaration at this point.
-        return
+        boolean isAssignable =
             v.owner == owner
             ||
             ((owner.name == names.init ||    // i.e. we are in a constructor
@@ -284,6 +284,8 @@ public class Attr extends JCTree.Visitor {
              v.owner == owner.owner
              &&
              ((v.flags() & STATIC) != 0) == Resolve.isStatic(env));
+        boolean insideCompactConstructor = env.enclMethod != null && TreeInfo.isCompactConstructor(env.enclMethod);
+        return isAssignable & !insideCompactConstructor;
     }
 
     /** Check that variable can be assigned to.
@@ -1078,15 +1080,34 @@ public class Attr extends JCTree.Visitor {
                     } else {
                         // but if it is the canonical:
 
-                        // if user generated, then it shouldn't explicitly invoke any other constructor
+                        /* if user generated, then it shouldn't:
+                         *     - have an accessibility stricter than that of the record type
+                         *     - explicitly invoke any other constructor
+                         */
                         if ((tree.sym.flags_field & GENERATEDCONSTR) == 0) {
+                            if (Check.protection(m.flags()) > Check.protection(env.enclClass.sym.flags())) {
+                                log.error(tree,
+                                        (env.enclClass.sym.flags() & AccessFlags) == 0 ?
+                                            Errors.InvalidCanonicalConstructorInRecord(
+                                                Fragments.Canonical,
+                                                env.enclClass.sym.name,
+                                                Fragments.CanonicalMustNotHaveStrongerAccess("package")
+                                            ) :
+                                            Errors.InvalidCanonicalConstructorInRecord(
+                                                    Fragments.Canonical,
+                                                    env.enclClass.sym.name,
+                                                    Fragments.CanonicalMustNotHaveStrongerAccess(asFlagSet(env.enclClass.sym.flags() & AccessFlags))
+                                            )
+                                );
+                            }
+
                             JCMethodInvocation app = TreeInfo.firstConstructorCall(tree);
                             if (app != null &&
                                     (TreeInfo.name(app.meth) == names._this ||
                                             TreeInfo.name(app.meth) == names._super) &&
                                     checkFirstConstructorStat(app, tree, false)) {
                                 log.error(tree, Errors.InvalidCanonicalConstructorInRecord(
-                                        Fragments.Canonical, tree.sym.name,
+                                        Fragments.Canonical, env.enclClass.sym.name,
                                         Fragments.CanonicalMustNotContainExplicitConstructorInvocation));
                             }
                         }
@@ -1094,19 +1115,24 @@ public class Attr extends JCTree.Visitor {
                         // also we want to check that no type variables have been defined
                         if (!tree.typarams.isEmpty()) {
                             log.error(tree, Errors.InvalidCanonicalConstructorInRecord(
-                                    Fragments.Canonical, tree.sym.name, Fragments.CanonicalMustNotDeclareTypeVariables));
+                                    Fragments.Canonical, env.enclClass.sym.name, Fragments.CanonicalMustNotDeclareTypeVariables));
                         }
 
                         /* and now we need to check that the constructor's arguments are exactly the same as those of the
                          * record components
                          */
-                        List recordComponentTypes = TreeInfo.recordFields(env.enclClass).map(vd -> vd.sym.type);
+                        List recordComponents = env.enclClass.sym.getRecordComponents();
+                        List recordFieldTypes = TreeInfo.recordFields(env.enclClass).map(vd -> vd.sym.type);
                         for (JCVariableDecl param: tree.params) {
-                            if (!types.isSameType(param.type, recordComponentTypes.head)) {
+                            boolean paramIsVarArgs = (param.sym.flags_field & VARARGS) != 0;
+                            if (!types.isSameType(param.type, recordFieldTypes.head) ||
+                                    (recordComponents.head.isVarargs() != paramIsVarArgs)) {
                                 log.error(param, Errors.InvalidCanonicalConstructorInRecord(
-                                        Fragments.Canonical, tree.sym.name, Fragments.TypeMustBeIdenticalToCorrespondingRecordComponentType));
+                                        Fragments.Canonical, env.enclClass.sym.name,
+                                        Fragments.TypeMustBeIdenticalToCorrespondingRecordComponentType));
                             }
-                            recordComponentTypes = recordComponentTypes.tail;
+                            recordComponents = recordComponents.tail;
+                            recordFieldTypes = recordFieldTypes.tail;
                         }
                     }
                 }
@@ -1180,11 +1206,6 @@ public class Attr extends JCTree.Visitor {
                             log.error(tree, Errors.InvalidCanonicalConstructorInRecord(
                                     Fragments.Canonical, env.enclClass.sym.name, Fragments.CanonicalWithNameMismatch));
                         }
-                        if (!tree.sym.isPublic()) {
-                            log.error(tree, Errors.InvalidCanonicalConstructorInRecord(
-                                    TreeInfo.isCompactConstructor(tree) ? Fragments.Compact : Fragments.Canonical,
-                                    env.enclClass.sym.name, Fragments.CanonicalConstructorMustBePublic));
-                        }
                         if (tree.sym.type.asMethodType().thrown != null && !tree.sym.type.asMethodType().thrown.isEmpty()) {
                             log.error(tree,
                                     Errors.InvalidCanonicalConstructorInRecord(
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java
index af8f98977f3..fffe5b16ac0 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java
@@ -1211,26 +1211,23 @@ public class Check {
             break;
         case TYP:
             if (sym.isLocal()) {
-                mask = (flags & RECORD) != 0 ? LocalRecordFlags : LocalClassFlags;
-                if ((flags & RECORD) != 0) {
-                    implicit = STATIC;
+                boolean implicitlyStatic = !sym.isAnonymous() &&
+                        ((flags & RECORD) != 0 || (flags & ENUM) != 0 || (flags & INTERFACE) != 0);
+                boolean staticOrImplicitlyStatic = (flags & STATIC) != 0 || implicitlyStatic;
+                mask = staticOrImplicitlyStatic && allowRecords ? StaticLocalFlags : LocalClassFlags;
+                implicit = implicitlyStatic ? STATIC : implicit;
+                if (staticOrImplicitlyStatic) {
                     if (sym.owner.kind == TYP) {
-                        log.error(pos, Errors.RecordDeclarationNotAllowedInInnerClasses);
+                        log.error(pos, Errors.StaticDeclarationNotAllowedInInnerClasses);
                     }
                 }
-                if ((sym.owner.flags_field & STATIC) == 0 &&
-                    (flags & ENUM) != 0) {
-                    log.error(pos, Errors.EnumsMustBeStatic);
-                }
             } else if (sym.owner.kind == TYP) {
                 mask = (flags & RECORD) != 0 ? MemberRecordFlags : MemberClassFlags;
                 if (sym.owner.owner.kind == PCK ||
                     (sym.owner.flags_field & STATIC) != 0)
                     mask |= STATIC;
-                else if ((flags & ENUM) != 0) {
-                    log.error(pos, Errors.EnumsMustBeStatic);
-                } else if ((flags & RECORD) != 0) {
-                    log.error(pos, Errors.RecordDeclarationNotAllowedInInnerClasses);
+                else if ((flags & ENUM) != 0 || (flags & RECORD) != 0) {
+                    log.error(pos, Errors.StaticDeclarationNotAllowedInInnerClasses);
                 }
                 // Nested interfaces and enums are always STATIC (Spec ???)
                 if ((flags & (INTERFACE | ENUM | RECORD)) != 0 ) implicit = STATIC;
@@ -1264,7 +1261,7 @@ public class Check {
             }
             else {
                 log.error(pos,
-                          Errors.ModNotAllowedHere(asFlagSet(illegal)));
+                        Errors.ModNotAllowedHere(asFlagSet(illegal)));
             }
         }
         else if ((sym.kind == TYP ||
@@ -2070,11 +2067,21 @@ public class Check {
      */
     void checkOverride(Env env, JCMethodDecl tree, MethodSymbol m) {
         ClassSymbol origin = (ClassSymbol)m.owner;
-        if ((origin.flags() & ENUM) != 0 && names.finalize.equals(m.name))
+        if ((origin.flags() & ENUM) != 0 && names.finalize.equals(m.name)) {
             if (m.overrides(syms.enumFinalFinalize, origin, types, false)) {
                 log.error(tree.pos(), Errors.EnumNoFinalize);
                 return;
             }
+        }
+        if (allowRecords && origin.isRecord()) {
+            // let's find out if this is a user defined accessor in which case the @Override annotation is acceptable
+            Optional recordComponent = origin.getRecordComponents().stream()
+                    .filter(rc -> rc.accessor == tree.sym && (rc.accessor.flags_field & GENERATED_MEMBER) == 0).findFirst();
+            if (recordComponent.isPresent()) {
+                return;
+            }
+        }
+
         for (Type t = origin.type; t.hasTag(CLASS);
              t = types.supertype(t)) {
             if (t != origin.type) {
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java
index 96513e06348..56eccf7e21c 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java
@@ -57,7 +57,6 @@ import static com.sun.tools.javac.code.TypeTag.ERROR;
 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
 
 import static com.sun.tools.javac.code.TypeTag.*;
-import static com.sun.tools.javac.code.TypeTag.BOT;
 import static com.sun.tools.javac.tree.JCTree.Tag.*;
 
 import com.sun.tools.javac.util.Dependencies.CompletionCause;
@@ -1025,7 +1024,6 @@ public class TypeEnter implements Completer {
             List defsToEnter = isRecord ?
                     tree.defs.diff(alreadyEntered) : tree.defs;
             memberEnter.memberEnter(defsToEnter, env);
-            List defsBeforeAddingNewMembers = tree.defs;
             if (isRecord) {
                 addRecordMembersIfNeeded(tree, env);
             }
@@ -1048,7 +1046,7 @@ public class TypeEnter implements Completer {
                         new TreeCopier(make.at(tree.pos)).copy(rec.getOriginalAnnos());
                 JCMethodDecl getter = make.at(tree.pos).
                         MethodDef(
-                                make.Modifiers(Flags.PUBLIC | Flags.GENERATED_MEMBER, originalAnnos),
+                                make.Modifiers(PUBLIC | Flags.GENERATED_MEMBER, originalAnnos),
                           tree.sym.name,
                           /* we need to special case for the case when the user declared the type as an ident
                            * if we don't do that then we can have issues if type annotations are applied to the
@@ -1123,7 +1121,7 @@ public class TypeEnter implements Completer {
         private void addRecordMembersIfNeeded(JCClassDecl tree, Env env) {
             if (lookupMethod(tree.sym, names.toString, List.nil()) == null) {
                 JCMethodDecl toString = make.
-                    MethodDef(make.Modifiers(Flags.PUBLIC | Flags.RECORD | Flags.GENERATED_MEMBER),
+                    MethodDef(make.Modifiers(Flags.PUBLIC | Flags.RECORD | Flags.FINAL | Flags.GENERATED_MEMBER),
                               names.toString,
                               make.Type(syms.stringType),
                               List.nil(),
@@ -1223,9 +1221,6 @@ public class TypeEnter implements Completer {
                     (types.supertype(owner().type).tsym == syms.enumSym)) {
                     // constructors of true enums are private
                     flags = PRIVATE | GENERATEDCONSTR;
-                } else if ((owner().flags_field & RECORD) != 0) {
-                    // record constructors are public
-                    flags = PUBLIC | GENERATEDCONSTR;
                 } else {
                     flags = (owner().flags() & AccessFlags) | GENERATEDCONSTR;
                 }
@@ -1313,21 +1308,25 @@ public class TypeEnter implements Completer {
     }
 
     class RecordConstructorHelper extends BasicConstructorHelper {
-
-        List recordFieldSymbols;
+        boolean lastIsVarargs;
         List recordFieldDecls;
 
-        RecordConstructorHelper(TypeSymbol owner, List recordFieldDecls) {
+        RecordConstructorHelper(ClassSymbol owner, List recordFieldDecls) {
             super(owner);
             this.recordFieldDecls = recordFieldDecls;
-            this.recordFieldSymbols = recordFieldDecls.map(vd -> vd.sym);
+            this.lastIsVarargs = owner.getRecordComponents().stream().anyMatch(rc -> rc.isVarargs());
         }
 
         @Override
         public Type constructorType() {
             if (constructorType == null) {
-                List argtypes = recordFieldSymbols.map(v -> (v.flags_field & Flags.VARARGS) != 0 ? types.elemtype(v.type) : v.type);
-                constructorType = new MethodType(argtypes, syms.voidType, List.nil(), syms.methodClass);
+                ListBuffer argtypes = new ListBuffer<>();
+                JCVariableDecl lastField = recordFieldDecls.last();
+                for (JCVariableDecl field : recordFieldDecls) {
+                    argtypes.add(field == lastField && lastIsVarargs ? types.elemtype(field.sym.type) : field.sym.type);
+                }
+
+                constructorType = new MethodType(argtypes.toList(), syms.voidType, List.nil(), syms.methodClass);
             }
             return constructorType;
         }
@@ -1340,11 +1339,14 @@ public class TypeEnter implements Completer {
              */
             csym.flags_field |= Flags.COMPACT_RECORD_CONSTRUCTOR | GENERATEDCONSTR;
             ListBuffer params = new ListBuffer<>();
-            for (VarSymbol p : recordFieldSymbols) {
-                params.add(new VarSymbol(GENERATED_MEMBER | PARAMETER | RECORD | ((p.flags_field & Flags.VARARGS) != 0 ? Flags.VARARGS : 0), p.name, p.type, csym));
+            JCVariableDecl lastField = recordFieldDecls.last();
+            for (JCVariableDecl field : recordFieldDecls) {
+                params.add(new VarSymbol(
+                        GENERATED_MEMBER | PARAMETER | RECORD | (field == lastField && lastIsVarargs ? Flags.VARARGS : 0),
+                        field.name, field.sym.type, csym));
             }
             csym.params = params.toList();
-            csym.flags_field |= RECORD | PUBLIC;
+            csym.flags_field |= RECORD;
             return csym;
         }
 
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java
index d898757ffbe..d6197223dac 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java
@@ -2573,7 +2573,9 @@ public class JavacParser implements Parser {
             dc = token.comment(CommentStyle.JAVADOC);
             return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
         case ENUM:
-            log.error(DiagnosticFlag.SYNTAX, token.pos, Errors.LocalEnum);
+            if (!allowRecords) {
+                log.error(DiagnosticFlag.SYNTAX, token.pos, Errors.LocalEnum);
+            }
             dc = token.comment(CommentStyle.JAVADOC);
             return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
         case IDENTIFIER:
@@ -3895,7 +3897,10 @@ public class JavacParser implements Parser {
     }
 
     private EnumeratorEstimate estimateEnumeratorOrMember(Name enumName) {
-        if (token.kind == TokenKind.IDENTIFIER && token.name() != enumName) {
+        // if we are seeing a record declaration inside of an enum we want the same error message as expected for a
+        // let's say an interface declaration inside an enum
+        if (token.kind == TokenKind.IDENTIFIER && token.name() != enumName &&
+                (!allowRecords || !isRecordStart())) {
             Token next = S.token(1);
             switch (next.kind) {
                 case LPAREN: case LBRACE: case COMMA: case SEMI:
@@ -3904,6 +3909,11 @@ public class JavacParser implements Parser {
         }
         switch (token.kind) {
             case IDENTIFIER: case MONKEYS_AT: case LT:
+                if (token.kind == IDENTIFIER) {
+                    if (allowRecords && isRecordStart()) {
+                        return EnumeratorEstimate.MEMBER;
+                    }
+                }
                 return EnumeratorEstimate.UNKNOWN;
             default:
                 return EnumeratorEstimate.MEMBER;
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties
index f202218b048..f4d5e10867c 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties
@@ -824,9 +824,6 @@ compiler.err.modifier.not.allowed.here=\
 compiler.err.intf.not.allowed.here=\
     interface not allowed here
 
-compiler.err.enums.must.be.static=\
-    enum declarations allowed only in static contexts
-
 # 0: symbol, 1: symbol
 compiler.err.name.clash.same.erasure=\
     name clash: {0} and {1} have the same erasure
@@ -3483,9 +3480,6 @@ compiler.misc.canonical=\
 compiler.misc.compact=\
     compact
 
-compiler.misc.canonical.constructor.must.be.public=\
-    canonical constructor must be public
-
 # 0: fragment
 compiler.misc.throws.clause.not.allowed.for.canonical.constructor=\
     throws clause not allowed for {0} constructor
@@ -3500,11 +3494,15 @@ compiler.misc.canonical.must.not.declare.type.variables=\
     canonical constructor must not declare type variables
 
 compiler.misc.type.must.be.identical.to.corresponding.record.component.type=\
-    type must match that of the corresponding record component\
+    type and arity must match that of the corresponding record component\
 
 compiler.misc.canonical.must.not.contain.explicit.constructor.invocation=\
     canonical constructor must not contain explicit constructor invocation
 
+# 0: set of flag or string
+compiler.misc.canonical.must.not.have.stronger.access=\
+    attempting to assign stronger access privileges; was {0}
+
 # other
 compiler.err.record.cannot.declare.instance.fields=\
     field declaration must be static\n\
@@ -3520,8 +3518,8 @@ compiler.err.first.statement.must.be.call.to.another.constructor=\
 compiler.err.instance.initializer.not.allowed.in.records=\
     instance initializers not allowed in records
 
-compiler.err.record.declaration.not.allowed.in.inner.classes=\
-    record declarations not allowed in inner classes
+compiler.err.static.declaration.not.allowed.in.inner.classes=\
+    static declarations not allowed in inner classes
 
 compiler.err.record.header.expected=\
     record header expected
diff --git a/test/jdk/java/io/Serializable/records/ConstructorPermissionTest.java b/test/jdk/java/io/Serializable/records/ConstructorPermissionTest.java
index 2ea410a96af..d868fffec56 100644
--- a/test/jdk/java/io/Serializable/records/ConstructorPermissionTest.java
+++ b/test/jdk/java/io/Serializable/records/ConstructorPermissionTest.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
@@ -72,7 +72,6 @@ public class ConstructorPermissionTest {
                 try { new Socket("localhost", 8080); }
                 catch (IOException unexpected) { throw new AssertionError(unexpected); }
             }
-            this.x = x;
         }
     }
 
@@ -80,7 +79,6 @@ public class ConstructorPermissionTest {
         public R3 {
             if (firstDataSetCreated)
                 ProcessHandle.current();
-            this.args = args;
         }
     }
 
diff --git a/test/langtools/lib/combo/tools/javac/combo/CompilationTestCase.java b/test/langtools/lib/combo/tools/javac/combo/CompilationTestCase.java
index c0f809dc425..edb41d0b030 100644
--- a/test/langtools/lib/combo/tools/javac/combo/CompilationTestCase.java
+++ b/test/langtools/lib/combo/tools/javac/combo/CompilationTestCase.java
@@ -27,7 +27,9 @@ package tools.javac.combo;
 import java.io.File;
 import java.io.IOException;
 
+import java.util.Arrays;
 import java.util.function.Consumer;
+import java.util.stream.IntStream;
 
 import javax.tools.Diagnostic;
 
@@ -63,6 +65,26 @@ public class CompilationTestCase extends JavacTemplateTestBase {
         compileOptions = options.clone();
     }
 
+    protected void appendCompileOptions(String... additionalOptions) {
+        String[] moreOptions = additionalOptions.clone();
+        String[] newCompileOptions = Arrays.copyOf(compileOptions, compileOptions.length + additionalOptions.length);
+        IntStream.range(0, additionalOptions.length).forEach(i -> {
+            newCompileOptions[newCompileOptions.length - additionalOptions.length + i] = additionalOptions[i];
+        });
+        compileOptions = newCompileOptions;
+    }
+
+    protected void removeLastCompileOptions(int i) {
+        if (i < 0) {
+            throw new AssertionError("unexpected negative value " + i);
+        }
+        if (i >= compileOptions.length) {
+            compileOptions = new String[] {};
+        } else {
+            compileOptions = Arrays.copyOf(compileOptions, compileOptions.length - i);
+        }
+    }
+
     protected void setDefaultFilename(String name) {
         defaultFileName = name;
     }
diff --git a/test/langtools/lib/combo/tools/javac/combo/Diagnostics.java b/test/langtools/lib/combo/tools/javac/combo/Diagnostics.java
index bd3042c21f4..b65fd5fb2ee 100644
--- a/test/langtools/lib/combo/tools/javac/combo/Diagnostics.java
+++ b/test/langtools/lib/combo/tools/javac/combo/Diagnostics.java
@@ -76,7 +76,7 @@ public class Diagnostics implements javax.tools.DiagnosticListener d.getKind() == Diagnostic.Kind.WARNING)
+                    .filter(d -> d.getKind() == Diagnostic.Kind.WARNING || d.getKind() == Diagnostic.Kind.MANDATORY_WARNING)
                     .anyMatch(d -> d.getCode().equals(key));
     }
 
diff --git a/test/langtools/lib/combo/tools/javac/combo/JavacTemplateTestBase.java b/test/langtools/lib/combo/tools/javac/combo/JavacTemplateTestBase.java
index 3f468c3c390..cd1be44745f 100644
--- a/test/langtools/lib/combo/tools/javac/combo/JavacTemplateTestBase.java
+++ b/test/langtools/lib/combo/tools/javac/combo/JavacTemplateTestBase.java
@@ -181,8 +181,9 @@ public abstract class JavacTemplateTestBase {
     protected void assertCompileSucceededWithWarning(String warning) {
         if (diags.errorsFound())
             fail("Expected successful compilation");
-        if (!diags.containsWarningKey(warning))
-            fail("Expected compilation warning " + warning);
+        if (!diags.containsWarningKey(warning)) {
+            fail(String.format("Expected compilation warning with %s, found %s", warning, diags.keys()));
+        }
     }
 
     /**
diff --git a/test/langtools/tools/javac/IllegalAnnotation.java b/test/langtools/tools/javac/IllegalAnnotation.java
index acd88f71cf2..5d8699b0724 100644
--- a/test/langtools/tools/javac/IllegalAnnotation.java
+++ b/test/langtools/tools/javac/IllegalAnnotation.java
@@ -4,6 +4,7 @@
  * @summary javac crash when declare an annotation type illegally
  *
  * @compile/fail/ref=IllegalAnnotation.out -XDrawDiagnostics IllegalAnnotation.java
+ * @compile --enable-preview -source ${jdk.version} IllegalAnnotation.java
  */
 class IllegalAnnotation {
     {
diff --git a/test/langtools/tools/javac/IllegalAnnotation.out b/test/langtools/tools/javac/IllegalAnnotation.out
index 00d7fd4e2a3..6b99a40d084 100644
--- a/test/langtools/tools/javac/IllegalAnnotation.out
+++ b/test/langtools/tools/javac/IllegalAnnotation.out
@@ -1,2 +1,2 @@
-IllegalAnnotation.java:10:10: compiler.err.annotation.decl.not.allowed.here
+IllegalAnnotation.java:11:10: compiler.err.annotation.decl.not.allowed.here
 1 error
diff --git a/test/langtools/tools/javac/InterfaceInInner.out b/test/langtools/tools/javac/InterfaceInInner.out
index 355cb685051..34fd184c004 100644
--- a/test/langtools/tools/javac/InterfaceInInner.out
+++ b/test/langtools/tools/javac/InterfaceInInner.out
@@ -1,2 +1,2 @@
-InterfaceInInner.java:12:13: compiler.err.intf.not.allowed.here
+InterfaceInInner.java:12:13: compiler.err.static.declaration.not.allowed.in.inner.classes
 1 error
diff --git a/test/langtools/tools/javac/LocalInterface.java b/test/langtools/tools/javac/LocalInterface.java
new file mode 100644
index 00000000000..13c2d56bdf1
--- /dev/null
+++ b/test/langtools/tools/javac/LocalInterface.java
@@ -0,0 +1,13 @@
+/**
+ * @test  /nodynamiccopyright/
+ * @bug 8242478
+ * @summary test for local interfaces
+ * @compile/fail/ref=LocalInterface.out -XDrawDiagnostics LocalInterface.java
+ * @compile --enable-preview -source ${jdk.version} LocalInterface.java
+ */
+class LocalInterface {
+    void m() {
+        interface I {}
+    }
+}
+
diff --git a/test/langtools/tools/javac/LocalInterface.out b/test/langtools/tools/javac/LocalInterface.out
new file mode 100644
index 00000000000..2ad6d4011d9
--- /dev/null
+++ b/test/langtools/tools/javac/LocalInterface.out
@@ -0,0 +1,2 @@
+LocalInterface.java:10:9: compiler.err.intf.not.allowed.here
+1 error
diff --git a/test/langtools/tools/javac/LocalRecord.java b/test/langtools/tools/javac/LocalRecord.java
new file mode 100644
index 00000000000..9dda54e04d6
--- /dev/null
+++ b/test/langtools/tools/javac/LocalRecord.java
@@ -0,0 +1,34 @@
+/*
+ * 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 8242478
+ * @summary test local records
+ * @compile --enable-preview -source ${jdk.version} LocalRecord.java
+ */
+class LocalRecord {
+    void m() {
+        record R() {}
+    }
+}
diff --git a/test/langtools/tools/javac/diags/examples/CanonicalConstructorMustBePublic.java b/test/langtools/tools/javac/diags/examples/CanonicalCantHaveStrongerAccessPrivileges.java
similarity index 83%
rename from test/langtools/tools/javac/diags/examples/CanonicalConstructorMustBePublic.java
rename to test/langtools/tools/javac/diags/examples/CanonicalCantHaveStrongerAccessPrivileges.java
index 043f541ece2..7364e698543 100644
--- a/test/langtools/tools/javac/diags/examples/CanonicalConstructorMustBePublic.java
+++ b/test/langtools/tools/javac/diags/examples/CanonicalCantHaveStrongerAccessPrivileges.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -22,12 +22,13 @@
  */
 
 // key: compiler.err.invalid.canonical.constructor.in.record
-// key: compiler.misc.canonical.constructor.must.be.public
+// key: compiler.misc.canonical.must.not.have.stronger.access
 // key: compiler.note.preview.filename
 // key: compiler.note.preview.recompile
 // key: compiler.misc.canonical
 // options: --enable-preview -source ${jdk.version}
 
-record R(int i) {
-    R(int i) { this.i = i; }
+public record CanonicalCantHaveStrongerAccessPrivileges() {
+    private CanonicalCantHaveStrongerAccessPrivileges {}
 }
+
diff --git a/test/langtools/tools/javac/diags/examples/EnumsMustBeStatic.java b/test/langtools/tools/javac/diags/examples/EnumsMustBeStatic.java
index b8eacbb7783..dcfdce8650e 100644
--- a/test/langtools/tools/javac/diags/examples/EnumsMustBeStatic.java
+++ b/test/langtools/tools/javac/diags/examples/EnumsMustBeStatic.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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,7 +21,7 @@
  * questions.
  */
 
-// key: compiler.err.enums.must.be.static
+// key: compiler.err.static.declaration.not.allowed.in.inner.classes
 
 class EnumsMustBeStatic {
     class Nested {
diff --git a/test/langtools/tools/javac/diags/examples/RecordsNotAllowedInInnerClasses.java b/test/langtools/tools/javac/diags/examples/RecordsNotAllowedInInnerClasses.java
index 48f26f76907..99000219c42 100644
--- a/test/langtools/tools/javac/diags/examples/RecordsNotAllowedInInnerClasses.java
+++ b/test/langtools/tools/javac/diags/examples/RecordsNotAllowedInInnerClasses.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
@@ -21,7 +21,7 @@
  * questions.
  */
 
-// key: compiler.err.record.declaration.not.allowed.in.inner.classes
+// key: compiler.err.static.declaration.not.allowed.in.inner.classes
 // key: compiler.note.preview.filename
 // key: compiler.note.preview.recompile
 // options: --enable-preview -source ${jdk.version}
diff --git a/test/langtools/tools/javac/enum/LocalEnum.java b/test/langtools/tools/javac/enum/LocalEnum.java
index f415aee15d8..0cbb0bf438c 100644
--- a/test/langtools/tools/javac/enum/LocalEnum.java
+++ b/test/langtools/tools/javac/enum/LocalEnum.java
@@ -4,6 +4,7 @@
  * @summary javac fails to reject local enums
  * @author gafter
  * @compile/fail/ref=LocalEnum.out -XDrawDiagnostics  LocalEnum.java
+ * @compile --enable-preview -source ${jdk.version}  LocalEnum.java
  */
 
 public class LocalEnum {
diff --git a/test/langtools/tools/javac/enum/LocalEnum.out b/test/langtools/tools/javac/enum/LocalEnum.out
index 20e4e4269aa..ee4cc2d10f5 100644
--- a/test/langtools/tools/javac/enum/LocalEnum.out
+++ b/test/langtools/tools/javac/enum/LocalEnum.out
@@ -1,2 +1,2 @@
-LocalEnum.java:11:9: compiler.err.local.enum
+LocalEnum.java:12:9: compiler.err.local.enum
 1 error
diff --git a/test/langtools/tools/javac/enum/NestedEnum.out b/test/langtools/tools/javac/enum/NestedEnum.out
index c2f9e143b3f..e7d49eef73b 100644
--- a/test/langtools/tools/javac/enum/NestedEnum.out
+++ b/test/langtools/tools/javac/enum/NestedEnum.out
@@ -1,2 +1,2 @@
-NestedEnum.java:12:9: compiler.err.enums.must.be.static
+NestedEnum.java:12:9: compiler.err.static.declaration.not.allowed.in.inner.classes
 1 error
diff --git a/test/langtools/tools/javac/enum/T5081785.out b/test/langtools/tools/javac/enum/T5081785.out
index ef9963304ec..c873019913c 100644
--- a/test/langtools/tools/javac/enum/T5081785.out
+++ b/test/langtools/tools/javac/enum/T5081785.out
@@ -1,5 +1,5 @@
-T5081785.java:29:9: compiler.err.enums.must.be.static
-T5081785.java:12:13: compiler.err.enums.must.be.static
-T5081785.java:19:27: compiler.err.enums.must.be.static
-T5081785.java:24:31: compiler.err.enums.must.be.static
+T5081785.java:29:9: compiler.err.static.declaration.not.allowed.in.inner.classes
+T5081785.java:12:13: compiler.err.static.declaration.not.allowed.in.inner.classes
+T5081785.java:19:27: compiler.err.static.declaration.not.allowed.in.inner.classes
+T5081785.java:24:31: compiler.err.static.declaration.not.allowed.in.inner.classes
 4 errors
diff --git a/test/langtools/tools/javac/processing/model/element/CheckingTypeAnnotationsOnRecords.java b/test/langtools/tools/javac/processing/model/element/CheckingTypeAnnotationsOnRecords.java
index bb55d0151ca..b3d554f2e61 100644
--- a/test/langtools/tools/javac/processing/model/element/CheckingTypeAnnotationsOnRecords.java
+++ b/test/langtools/tools/javac/processing/model/element/CheckingTypeAnnotationsOnRecords.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
@@ -88,7 +88,6 @@ public class CheckingTypeAnnotationsOnRecords extends TestRunner {
     }
 
     public static void main(String... args) throws Exception {
-        System.out.println(System.getProperties());
         new CheckingTypeAnnotationsOnRecords().runTests();
     }
 
diff --git a/test/langtools/tools/javac/processing/model/element/TestRecordDesugar.java b/test/langtools/tools/javac/processing/model/element/TestRecordDesugar.java
index 65b63b9c0b4..fa9058d7c3b 100644
--- a/test/langtools/tools/javac/processing/model/element/TestRecordDesugar.java
+++ b/test/langtools/tools/javac/processing/model/element/TestRecordDesugar.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -258,7 +258,7 @@ public class TestRecordDesugar extends JavacTestingAbstractProcessor {
                                    name = "modulus",
                                    type = TypeKind.DOUBLE),
 
-                      @ElementInfo(modifiers = {Modifier.PUBLIC},
+                      @ElementInfo(modifiers = {Modifier.PUBLIC, Modifier.FINAL},
                                    name = "toString",
                                    type = TypeKind.DECLARED,
                                    origin = Elements.Origin.EXPLICIT),
@@ -284,7 +284,7 @@ public class TestRecordDesugar extends JavacTestingAbstractProcessor {
                                    origin = Elements.Origin.EXPLICIT),
 
                       @ElementInfo(kind = ElementKind.CONSTRUCTOR,
-                                   modifiers = {Modifier.PUBLIC},
+                                   modifiers = {},
                                    name = "",
                                    type = TypeKind.VOID,
                                    origin = Elements.Origin.MANDATED),
@@ -329,7 +329,7 @@ public class TestRecordDesugar extends JavacTestingAbstractProcessor {
                                    name = "modulus",
                                    type = TypeKind.DOUBLE),
 
-                      @ElementInfo(modifiers = {Modifier.PUBLIC},
+                      @ElementInfo(modifiers = {Modifier.PUBLIC, Modifier.FINAL},
                                    name = "toString",
                                    type = TypeKind.DECLARED,
                                    origin = Elements.Origin.EXPLICIT),
diff --git a/test/langtools/tools/javac/records/LocalStaticDeclarations.java b/test/langtools/tools/javac/records/LocalStaticDeclarations.java
new file mode 100644
index 00000000000..23e3f962da2
--- /dev/null
+++ b/test/langtools/tools/javac/records/LocalStaticDeclarations.java
@@ -0,0 +1,229 @@
+/*
+ * 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 8242293
+ * @summary allow for local interfaces and enums plus nested records, interfaces and enums
+ * @library /tools/javac/lib
+ * @modules jdk.compiler/com.sun.tools.javac.api
+ *          jdk.compiler/com.sun.tools.javac.file
+ *          jdk.compiler/com.sun.tools.javac.util
+ * @build combo.ComboTestHelper
+ * @compile --enable-preview -source ${jdk.version} LocalStaticDeclarations.java
+ * @run main/othervm --enable-preview LocalStaticDeclarations
+ */
+
+import javax.lang.model.element.Element;
+import javax.tools.Diagnostic;
+import javax.tools.JavaFileObject;
+
+import com.sun.tools.javac.util.Assert;
+
+import com.sun.tools.javac.api.ClientCodeWrapper;
+import com.sun.tools.javac.util.JCDiagnostic;
+import com.sun.tools.javac.util.List;
+import combo.ComboInstance;
+import combo.ComboParameter;
+import combo.ComboTask;
+import combo.ComboTask.Result;
+import combo.ComboTestHelper;
+
+public class LocalStaticDeclarations extends ComboInstance {
+
+    static final String sourceTemplate =
+            """
+            import java.lang.annotation.*;
+            class Test {
+                int INSTANCE_FIELD = 0;
+                static int STATIC_FIELD = 0;
+                // instance initializer
+                { int LOCAL_VARIABLE = 0;
+                    #{CONTAINER}
+                }
+                Test() {
+                    #{CONTAINER}
+                }
+                void m() {
+                    int LOCAL_VARIABLE = 0;
+                    #{CONTAINER}
+                }
+                static void foo() {
+                    int LOCAL_VARIABLE = 0;
+                    #{CONTAINER}
+                }
+            }
+            """;
+
+    enum Container implements ComboParameter {
+        NO_CONTAINER("#{STATIC_LOCAL}"),
+        INTERFACE("interface CI { #{STATIC_LOCAL} }"),
+        ANNOTATION("@interface CA { #{STATIC_LOCAL} }"),
+        ANONYMOUS(
+                """
+                    new Object() {
+                        // instance initializer
+                        {
+                            #{STATIC_LOCAL}
+                        }
+
+                        void m() {
+                            #{STATIC_LOCAL}
+                        }
+                    };
+                """
+        ),
+        RECORD("record CR() { #{STATIC_LOCAL} }"),
+        CLASS("class CC { #{STATIC_LOCAL} }"),
+        ENUM("enum CE { #{STATIC_LOCAL} }"),
+        LAMBDA("Runnable run = () -> { #{STATIC_LOCAL} };");
+
+        String container;
+
+        Container(String container) {
+            this.container = container;
+        }
+
+        public String expand(String optParameter) {
+            return container;
+        }
+    }
+
+    enum StaticLocalDecl implements ComboParameter {
+        ENUM("enum E { E1; #{MEMBER} }"),
+        RECORD("record R() { #{MEMBER} }"),
+        ANNOTATION("@interface A { #{MEMBER} }"),
+        INTERFACE("interface I { #{MEMBER} }");
+
+        String localDecl;
+
+        StaticLocalDecl(String localDecl) {
+            this.localDecl = localDecl;
+        }
+
+        public String expand(String optParameter) {
+            return localDecl;
+        }
+    }
+
+    enum Member implements ComboParameter {
+        NONE(""),
+        METHOD("int foo() { return #{EXPR}; }"),
+        DEFAULT_METHOD("default int foo() { return #{EXPR}; }");
+
+        String member;
+
+        Member(String member) {
+            this.member = member;
+        }
+
+        public String expand(String optParameter) {
+            return member;
+        }
+    }
+
+    enum Expression implements ComboParameter {
+         LITERAL("1"),
+         STATIC_FIELD("STATIC_FIELD"),
+         LOCAL_VARIABLE("LOCAL_VARIABLE"),
+         INSTANCE_FIELD("INSTANCE_FIELD");
+
+         String expr;
+
+         Expression(String expr) {
+             this.expr = expr;
+         }
+
+        public String expand(String optParameter) {
+            return expr;
+        }
+    }
+
+    public static void main(String... args) throws Exception {
+        new combo.ComboTestHelper()
+                .withFilter(LocalStaticDeclarations::notTriviallyIncorrect)
+                .withDimension("CONTAINER", (x, t) -> { x.container = t; }, Container.values())
+                .withDimension("STATIC_LOCAL", (x, t) -> { x.decl = t; }, StaticLocalDecl.values())
+                .withDimension("MEMBER", (x, t) -> { x.member = t; }, Member.values())
+                .withDimension("EXPR", (x, expr) -> x.expr = expr, Expression.values())
+                .run(LocalStaticDeclarations::new);
+    }
+
+    Container container;
+    StaticLocalDecl decl;
+    Member member;
+    Expression expr;
+
+    @Override
+    public void doWork() throws Throwable {
+        newCompilationTask()
+                .withOptions(new String[]{"--enable-preview", "-source", Integer.toString(Runtime.version().feature())})
+                .withSourceFromTemplate("Test", sourceTemplate)
+                .generate(this::check);
+    }
+
+    boolean notTriviallyIncorrect() {
+        return decl == StaticLocalDecl.INTERFACE && (member == Member.DEFAULT_METHOD || member == Member.NONE) ||
+               decl != StaticLocalDecl.INTERFACE && (member == Member.METHOD || member == Member.NONE) &&
+               ((decl != StaticLocalDecl.ANNOTATION) ||
+               (decl == StaticLocalDecl.ANNOTATION && member == Member.NONE));
+    }
+
+    void check(ComboTask.Result> result) {
+        if (shouldFail()) {
+            Assert.check(result.hasErrors(), result.compilationInfo());
+            if (!expectedDiagFound(result)) {
+                fail("test failing with unexpected error message\n" + result.compilationInfo());
+            }
+        } else {
+            Assert.check(!result.hasErrors(), result.compilationInfo());
+        }
+    }
+
+    boolean shouldFail() {
+        return ((container != Container.NO_CONTAINER &&
+                container != Container.LAMBDA &&
+                container != Container.ANONYMOUS)) ||
+                (member != Member.NONE && !acceptableExpr());
+    }
+
+    boolean acceptableExpr() {
+        return (expr == Expression.LITERAL || expr == Expression.STATIC_FIELD);
+    }
+
+    boolean expectedDiagFound(ComboTask.Result> result) {
+        if ((container == Container.NO_CONTAINER ||
+                container == Container.LAMBDA ||
+                container == Container.ANONYMOUS) &&
+                !acceptableExpr()) {
+            return result.containsKey("compiler.err.non-static.cant.be.ref");
+        } else if (container == Container.ENUM) {
+            if (decl == StaticLocalDecl.ANNOTATION) {
+                return result.containsKey("compiler.err.expected");
+            } else {
+                return result.containsKey("compiler.err.enum.constant.expected" );
+            }
+        }
+        return result.containsKey("compiler.err.static.declaration.not.allowed.in.inner.classes" );
+    }
+}
diff --git a/test/langtools/tools/javac/records/RecordCompilationTests.java b/test/langtools/tools/javac/records/RecordCompilationTests.java
index c9a390c3d78..d721ff8d147 100644
--- a/test/langtools/tools/javac/records/RecordCompilationTests.java
+++ b/test/langtools/tools/javac/records/RecordCompilationTests.java
@@ -36,7 +36,8 @@
  *      jdk.jdeps/com.sun.tools.classfile
  * @build JavacTestingAbstractProcessor
  * @compile --enable-preview -source ${jdk.version} RecordCompilationTests.java
- * @run testng/othervm --enable-preview RecordCompilationTests
+ * @run testng/othervm -DuseAP=false --enable-preview RecordCompilationTests
+ * @run testng/othervm -DuseAP=true --enable-preview RecordCompilationTests
  */
 
 import java.io.File;
@@ -55,6 +56,7 @@ import java.util.stream.Stream;
 
 import com.sun.tools.javac.util.Assert;
 
+import javax.annotation.processing.AbstractProcessor;
 import javax.annotation.processing.RoundEnvironment;
 import javax.annotation.processing.SupportedAnnotationTypes;
 
@@ -70,13 +72,17 @@ import javax.lang.model.element.VariableElement;
 import javax.lang.model.type.ArrayType;
 import javax.lang.model.type.TypeMirror;
 
+import com.sun.tools.classfile.AccessFlags;
 import com.sun.tools.classfile.Annotation;
 import com.sun.tools.classfile.Attribute;
 import com.sun.tools.classfile.Attributes;
 import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.Code_attribute;
 import com.sun.tools.classfile.ConstantPool;
+import com.sun.tools.classfile.ConstantPool.CONSTANT_Fieldref_info;
 import com.sun.tools.classfile.ConstantPool.CPInfo;
 import com.sun.tools.classfile.Field;
+import com.sun.tools.classfile.Instruction;
 import com.sun.tools.classfile.Method;
 import com.sun.tools.classfile.Record_attribute;
 import com.sun.tools.classfile.Record_attribute.ComponentInfo;
@@ -99,20 +105,51 @@ import tools.javac.combo.CompilationTestCase;
 import static java.lang.annotation.ElementType.*;
 import static org.testng.Assert.assertEquals;
 
+/** Records are the first feature which sports automatic injection of (declarative and type) annotations : from a
+ *  given record component to one or more record members, if applicable.
+ *  This implies that the record's implementation can be stressed with the presence of annotation processors. Which is
+ *  something the implementator could easily skip. For this reason this test is executed twice, once without the
+ *  presence of any annotation processor and one with a simple annotation processor (which does not annotation processing
+ *  at all) just to force at least a round of annotation processing.
+ *
+ *  Tests needing special compilation options need to store current options, set its customs options by invoking method
+ *  `setCompileOptions` and then reset the previous compilation options for other tests. To see an example of this check
+ *  method: testAnnos()
+ */
+
 @Test
 public class RecordCompilationTests extends CompilationTestCase {
-
     // @@@ When records become a permanent feature, we don't need these any more
-    private static String[] PREVIEW_OPTIONS = {"--enable-preview", "-source",
-                                               Integer.toString(Runtime.version().feature())};
+    private static String[] PREVIEW_OPTIONS = {
+            "--enable-preview",
+            "-source", Integer.toString(Runtime.version().feature())
+    };
+
+    private static String[] PREVIEW_OPTIONS_WITH_AP = {
+            "--enable-preview",
+            "-source", Integer.toString(Runtime.version().feature()),
+            "-processor", SimplestAP.class.getName()
+    };
 
     private static final List BAD_COMPONENT_NAMES = List.of(
             "clone", "finalize", "getClass", "hashCode",
             "notify", "notifyAll", "toString", "wait");
 
-    {
+    /* simplest annotation processor just to force a round of annotation processing for all tests
+     */
+    @SupportedAnnotationTypes("*")
+    public static class SimplestAP extends AbstractProcessor {
+        @Override
+        public boolean process(Set annotations, RoundEnvironment roundEnv) {
+            return true;
+        }
+    }
+
+    public RecordCompilationTests() {
+        boolean useAP = System.getProperty("useAP") == null ? false : System.getProperty("useAP").equals("true");
         setDefaultFilename("R.java");
-        setCompileOptions(PREVIEW_OPTIONS);
+        setCompileOptions(useAP ? PREVIEW_OPTIONS_WITH_AP : PREVIEW_OPTIONS);
+        System.out.println(useAP ? "running all tests using an annotation processor" : "running all tests without annotation processor");
     }
 
     public void testMalformedDeclarations() {
@@ -130,7 +167,8 @@ public class RecordCompilationTests extends CompilationTestCase {
         assertFail("compiler.err.already.defined", "record R(int x, int x) {}");
         for (String s : List.of("var", "record"))
             assertFail("compiler.err.restricted.type.not.allowed.here", "record R(# x) { }", s);
-        for (String s : List.of("public", "private", "volatile", "final"))
+        for (String s : List.of("public", "protected", "private", "static", "final", "transient", "volatile",
+                "abstract", "synchronized", "native", "strictfp")) // missing: sealed and non-sealed
             assertFail("compiler.err.record.cant.declare.field.modifiers", "record R(# String foo) { }", s);
         assertFail("compiler.err.varargs.must.be.last", "record R(int... x, int... y) {}");
         assertFail("compiler.err.instance.initializer.not.allowed.in.records", "record R(int i) { {} }");
@@ -210,7 +248,14 @@ public class RecordCompilationTests extends CompilationTestCase {
 
     public void testNoExtendRecord() {
         assertFail("compiler.err.invalid.supertype.record",
-                   "class R extends Record { public String toString() { return null; } public int hashCode() { return 0; } public boolean equals(Object o) { return false; } } }");
+                   """
+                   class R extends Record {
+                       public String toString() { return null; }
+                       public int hashCode() { return 0; }
+                       public boolean equals(Object o) { return false; }
+                   }
+                   """
+        );
     }
 
     public void testFieldDeclarations() {
@@ -246,6 +291,14 @@ public class RecordCompilationTests extends CompilationTestCase {
                 "    public int x() { return x; };" +
                 "}");
 
+        assertOK("public record R(int... x) {\n" +
+                "    public int[] x() { return x; };" +
+                "}");
+
+        assertOK("public record R(int x) {\n" +
+                "    public final int x() { return 0; };" +
+                "}");
+
         assertOK("public record R(int x) {\n" +
                 "    public final int x() { return 0; };" +
                 "}");
@@ -293,8 +346,7 @@ public class RecordCompilationTests extends CompilationTestCase {
         for (String goodCtor : List.of(
                 "public R(int x) { this(x, 0); }",
                 "public R(int x, int y) { this.x = x; this.y = y; }",
-                "public R { }",
-                "public R { this.x = 0; }"))
+                "public R { }"))
             assertOK("record R(int x, int y) { # }", goodCtor);
 
         assertOK("import java.util.*; record R(String x, String y) {  public R { Objects.requireNonNull(x); Objects.requireNonNull(y); } }");
@@ -308,12 +360,6 @@ public class RecordCompilationTests extends CompilationTestCase {
                                 "public R(int _x, int _y) { this.x = _x; this.y = _y; }"))
             assertFail("compiler.err.invalid.canonical.constructor.in.record", "record R(int x, int y) { # }", s);
 
-        // canonical ctor must be public
-        for (String s : List.of("", "protected", "private"))
-            assertFail("compiler.err.invalid.canonical.constructor.in.record", "record R(int x, int y) { # }",
-                       "# R(int x, int y) { this.x = x; this.y = y; }",
-                       s);
-
         // ctor args must match types
         assertFail("compiler.err.invalid.canonical.constructor.in.record",
                 "import java.util.*;\n" +
@@ -434,13 +480,7 @@ public class RecordCompilationTests extends CompilationTestCase {
         assertFail("compiler.err.already.defined", template);
     }
 
-    public void testLocalRecords() {
-        assertOK("class R { \n" +
-                "    void m() { \n" +
-                "        record RR(int x) { };\n" +
-                "    }\n" +
-                "}");
-
+    public void testStaticLocalTypes() {
         // local records can also be final
         assertOK("class R { \n" +
                 "    void m() { \n" +
@@ -488,49 +528,26 @@ public class RecordCompilationTests extends CompilationTestCase {
                 "        record RR(int x) { public int x() { return z; }};\n" +
                 "    }\n" +
                 "}");
-        // can be contained inside a lambda
-        assertOK("""
-                class Outer {
-                    Runnable run = () -> {
-                        record TestRecord(int i) {}
-                    };
-                }
-                """);
-
         // Can't self-shadow
         assertFail("compiler.err.already.defined",
-                   "class R { \n" +
-                   "    void m() { \n" +
-                   "        record R(int x) { };\n" +
-                   "    }\n" +
-                   "}");
-    }
-
-    public void testCompactDADU() {
-        // trivial cases
-        assertOK("record R() { public R {} }");
-        assertOK("record R(int x) { public R {} }");
-
-        // throwing an unchecked exception
-        assertOK("record R(int x) { public R { if (x < 0) { this.x = x; throw new RuntimeException(); }} }");
-
-        assertOK("record R(int x) { public R { if (x < 0) { this.x = x; throw new RuntimeException(); }} }");
-
-        // x is not DA nor DU in the body of the constructor hence error
-        assertFail("compiler.err.var.might.not.have.been.initialized", "record R(int x) { # }",
-                "public R { if (x < 0) { this.x = -x; } }");
-
-        // if static fields are not DA then error
-        assertFail("compiler.err.var.might.not.have.been.initialized",
-                "record R() { # }", "static final String x;");
-
-        // ditto
-        assertFail("compiler.err.var.might.not.have.been.initialized",
-                "record R() { # }", "static final String x; public R {}");
-
-        // ditto
-        assertFail("compiler.err.var.might.not.have.been.initialized",
-                "record R(int i) { # }", "static final String x; public R {}");
+                """
+                class R {
+                    void m() {
+                        record R(int x) { };
+                    }
+                }
+                """
+        );
+        // can't be explicitly static
+        assertFail("compiler.err.illegal.start.of.expr",
+                """
+                class R {
+                    void m() {
+                        static record RR(int x) { };
+                    }
+                }
+                """
+        );
     }
 
     public void testReturnInCanonical_Compact() {
@@ -561,13 +578,16 @@ public class RecordCompilationTests extends CompilationTestCase {
     }
 
     public void testRecordsInsideInner() {
-        assertFail("compiler.err.record.declaration.not.allowed.in.inner.classes",
-                "class Outer {\n" +
-                "    class Inner {\n" +
-                "        record R(int a) {}\n" +
-                "    }\n" +
-                "}");
-        assertFail("compiler.err.record.declaration.not.allowed.in.inner.classes",
+        assertFail("compiler.err.static.declaration.not.allowed.in.inner.classes",
+                """
+                class Outer {
+                    class Inner {
+                        record R(int a) {}
+                    }
+                }
+                """
+        );
+        assertFail("compiler.err.static.declaration.not.allowed.in.inner.classes",
                 """
                 class Outer {
                     public void test() {
@@ -577,7 +597,7 @@ public class RecordCompilationTests extends CompilationTestCase {
                     }
                 }
                 """);
-        assertFail("compiler.err.record.declaration.not.allowed.in.inner.classes",
+        assertFail("compiler.err.static.declaration.not.allowed.in.inner.classes",
                 """
                 class Outer {
                     Runnable run = new Runnable() {
@@ -586,7 +606,7 @@ public class RecordCompilationTests extends CompilationTestCase {
                     };
                 }
                 """);
-        assertFail("compiler.err.record.declaration.not.allowed.in.inner.classes",
+        assertFail("compiler.err.static.declaration.not.allowed.in.inner.classes",
                 """
                 class Outer {
                     void m() {
@@ -646,6 +666,47 @@ public class RecordCompilationTests extends CompilationTestCase {
         Assert.check(numberOfFieldRefs == 1);
     }
 
+    /*  check that fields are initialized in a canonical constructor in the same declaration order as the corresponding
+     *  record component
+     */
+    public void testCheckInitializationOrderInCompactConstructor() throws Exception {
+        int putField1 = -1;
+        int putField2 = -1;
+        File dir = assertOK(true, "record R(int i, String s) { R {} }");
+        for (final File fileEntry : dir.listFiles()) {
+            if (fileEntry.getName().equals("R.class")) {
+                ClassFile classFile = ClassFile.read(fileEntry);
+                for (Method method : classFile.methods) {
+                    if (method.getName(classFile.constant_pool).equals("")) {
+                        Code_attribute code_attribute = (Code_attribute) method.attributes.get("Code");
+                        for (Instruction instruction : code_attribute.getInstructions()) {
+                            if (instruction.getMnemonic().equals("putfield")) {
+                                if (putField1 != -1 && putField2 != -1) {
+                                    throw new AssertionError("was expecting only two putfield instructions in this method");
+                                }
+                                if (putField1 == -1) {
+                                    putField1 = instruction.getShort(1);
+                                } else if (putField2 == -1) {
+                                    putField2 = instruction.getShort(1);
+                                }
+                            }
+                        }
+                        // now we need to check that we are assigning to `i` first and to `s` afterwards
+                        CONSTANT_Fieldref_info fieldref_info1 = (CONSTANT_Fieldref_info)classFile.constant_pool.get(putField1);
+                        if (!fieldref_info1.getNameAndTypeInfo().getName().equals("i")) {
+                            throw new AssertionError("was expecting variable name 'i'");
+                        }
+
+                        CONSTANT_Fieldref_info fieldref_info2 = (CONSTANT_Fieldref_info)classFile.constant_pool.get(putField2);
+                        if (!fieldref_info2.getNameAndTypeInfo().getName().equals("s")) {
+                            throw new AssertionError("was expecting variable name 's'");
+                        }
+                    }
+                }
+            }
+        }
+    }
+
     public void testAcceptRecordId() {
         String[] testOptions = {/* no options */};
         setCompileOptions(testOptions);
@@ -982,6 +1043,250 @@ public class RecordCompilationTests extends CompilationTestCase {
                 }
             }
         }
+    }
 
+    public void testMethodsInheritedFromRecordArePublicAndFinal() throws Exception {
+        int numberOfFieldRefs = 0;
+        File dir = assertOK(true, "record R() {}");
+        for (final File fileEntry : dir.listFiles()) {
+            if (fileEntry.getName().equals("R.class")) {
+                ClassFile classFile = ClassFile.read(fileEntry);
+                for (Method method : classFile.methods)
+                    switch (method.getName(classFile.constant_pool)) {
+                        case "toString", "equals", "hashCode" ->
+                            Assert.check(method.access_flags.is(AccessFlags.ACC_PUBLIC) && method.access_flags.is(AccessFlags.ACC_FINAL));
+                        default -> { /* do nothing */ }
+                    }
+            }
+        }
+    }
+
+    private static final List ACCESSIBILITY = List.of(
+            "public", "protected", "", "private");
+
+    public void testCanonicalAccessibility() throws Exception {
+        // accessibility of canonical can't be stronger than that of the record type
+        for (String a1 : ACCESSIBILITY) {
+            for (String a2 : ACCESSIBILITY) {
+                if (protection(a2) > protection(a1)) {
+                    assertFail("compiler.err.invalid.canonical.constructor.in.record", "class R {# record RR() { # RR {} } }", a1, a2);
+                } else {
+                    assertOK("class R {# record RR() { # RR {} } }", a1, a2);
+                }
+            }
+        }
+
+        // now lets check that when compiler the compiler generates the canonical, it has the same accessibility
+        // as the record type
+        for (String a : ACCESSIBILITY) {
+            File dir = assertOK(true, "class R {# record RR() {} }", a);
+            for (final File fileEntry : dir.listFiles()) {
+                if (fileEntry.getName().equals("R$RR.class")) {
+                    ClassFile classFile = ClassFile.read(fileEntry);
+                    for (Method method : classFile.methods)
+                        if (method.getName(classFile.constant_pool).equals("")) {
+                            Assert.check(method.access_flags.flags == accessFlag(a),
+                                    "was expecting access flag " + accessFlag(a) + " but found " + method.access_flags.flags);
+                        }
+                }
+            }
+        }
+    }
+
+    private int protection(String access) {
+        switch (access) {
+            case "private": return 3;
+            case "protected": return 1;
+            case "public": return 0;
+            case "": return 2;
+            default:
+                throw new AssertionError();
+        }
+    }
+
+    private int accessFlag(String access) {
+        switch (access) {
+            case "private": return AccessFlags.ACC_PRIVATE;
+            case "protected": return AccessFlags.ACC_PROTECTED;
+            case "public": return AccessFlags.ACC_PUBLIC;
+            case "": return 0;
+            default:
+                throw new AssertionError();
+        }
+    }
+
+    public void testSameArity() {
+        for (String source : List.of(
+                """
+                record R(int... args) {
+                    public R(int... args) {
+                        this.args = args;
+                    }
+                }
+                """,
+                """
+                record R(int[] args) {
+                    public R(int[] args) {
+                        this.args = args;
+                    }
+                }
+                """
+        )) {
+            assertOK(source);
+        }
+
+        for (String source : List.of(
+                """
+                record R(int... args) {
+                    public R(int[] args) {
+                        this.args = args;
+                    }
+                }
+                """,
+                """
+                record R(int... args) {
+                    public R(int[] args) {
+                        this.args = args;
+                    }
+                }
+                """,
+                """
+                record R(String... args) {
+                    public R(String[] args) {
+                        this.args = args;
+                    }
+                }
+                """,
+                """
+                record R(String... args) {
+                    public R(String[] args) {
+                        this.args = args;
+                    }
+                }
+                """
+        )) {
+            assertFail("compiler.err.invalid.canonical.constructor.in.record", source);
+        }
+    }
+
+    public void testSafeVararsAnno() {
+        assertFail("compiler.err.annotation.type.not.applicable",
+                """
+                @SafeVarargs
+                record R(T... t) {}
+                """,
+                """
+                @SafeVarargs
+                record R(T... t) {
+                    R(T... t) {
+                        this.t = t;
+                    }
+                }
+                """
+        );
+
+        assertOK(
+                """
+                record R(T... t) {
+                    @SafeVarargs
+                    R(T... t) {
+                        this.t = t;
+                    }
+                }
+                """
+        );
+
+        appendCompileOptions("-Xlint:unchecked");
+        assertOKWithWarning("compiler.warn.unchecked.varargs.non.reifiable.type",
+                """
+                record R(T... t) {
+                    R(T... t) {
+                        this.t = t;
+                    }
+                }
+                """
+        );
+        removeLastCompileOptions(1);
+
+        assertOK(
+                """
+                @SuppressWarnings("unchecked")
+                record R(T... t) {
+                    R(T... t) {
+                        this.t = t;
+                    }
+                }
+                """
+        );
+
+        assertOK(
+                """
+                record R(T... t) {
+                    @SuppressWarnings("unchecked")
+                    R(T... t) {
+                        this.t = t;
+                    }
+                }
+                """
+        );
+    }
+
+    public void testOverrideAtAccessor() {
+        assertOK(
+                """
+                record R(int i) {
+                    @Override
+                    public int i() { return i; }
+                }
+                """,
+                """
+                record R(int i, int j) {
+                    @Override
+                    public int i() { return i; }
+                    public int j() { return j; }
+                }
+                """,
+                """
+                interface I { int i(); }
+                record R(int i) implements I {
+                    @Override
+                    public int i() { return i; }
+                }
+                """,
+                """
+                interface I { int i(); }
+                record R(int i) implements I {
+                    public int i() { return i; }
+                }
+                """,
+                """
+                interface I { default int i() { return 0; } }
+                record R(int i) implements I {
+                    @Override
+                    public int i() { return i; }
+                }
+                """
+        );
+    }
+
+    public void testNoAssigmentInsideCompactRecord() {
+        assertFail("compiler.err.cant.assign.val.to.final.var",
+                """
+                record R(int i) {
+                    R {
+                        this.i = i;
+                    }
+                }
+                """
+        );
+        assertFail("compiler.err.cant.assign.val.to.final.var",
+                """
+                record R(int i) {
+                    R {
+                        (this).i = i;
+                    }
+                }
+                """
+        );
     }
 }
diff --git a/test/langtools/tools/javac/records/RecordMemberTests.java b/test/langtools/tools/javac/records/RecordMemberTests.java
index 8f6e051950f..85d9434ffb6 100644
--- a/test/langtools/tools/javac/records/RecordMemberTests.java
+++ b/test/langtools/tools/javac/records/RecordMemberTests.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
@@ -44,46 +44,39 @@ import static org.testng.Assert.*;
 
 @Test
 public class RecordMemberTests {
-    record R1(int i, int j) {}
+    public record R1(int i, int j) {}
 
-    record R2(int i, int j) {
+    public record R2(int i, int j) {
         public R2 {}
     }
 
-    record R3(int i, int j) {
-        public R3 {
-            this.i = i;
-        }
-    }
-
-    record R4(int i, int j) {
-        public R4 {
+    public record R3(int i, int j) {
+        public R3(int i, int j) {
             this.i = i;
             this.j = j;
         }
     }
 
-    record R5(int i, int j) {
-        public R5 { this.i = this.j = 0; }
+    public record R4(int i, int j) {
+        public R4(int i, int j) { this.i = this.j = 0; }
     }
 
     R1 r1 = new R1(1, 2);
     R2 r2 = new R2(1, 2);
     R3 r3 = new R3(1, 2);
     R4 r4 = new R4(1, 2);
-    R5 r5 = new R5(1, 2);
 
     public void testConstruction() {
-        for (int i : new int[] { r1.i, r2.i, r3.i, r4.i,
-                                 r1.i(), r2.i(), r3.i(), r4.i() })
+        for (int i : new int[] { r1.i, r2.i, r3.i,
+                                 r1.i(), r2.i(), r3.i() })
             assertEquals(i, 1);
 
-        for (int j : new int[] { r1.j, r2.j, r3.j, r4.j,
-                                 r1.j(), r2.j(), r3.j(), r4.j() })
+        for (int j : new int[] { r1.j, r2.j, r3.j,
+                                 r1.j(), r2.j(), r3.j() })
             assertEquals(j, 2);
 
-        assertEquals(r5.i, 0);
-        assertEquals(r5.j, 0);
+        assertEquals(r4.i, 0);
+        assertEquals(r4.j, 0);
     }
 
     public void testConstructorParameterNames() throws ReflectiveOperationException {
diff --git a/test/langtools/tools/javac/records/VarargsRecordsTest.java b/test/langtools/tools/javac/records/VarargsRecordsTest.java
index bfbb3767edb..2151db278ac 100644
--- a/test/langtools/tools/javac/records/VarargsRecordsTest.java
+++ b/test/langtools/tools/javac/records/VarargsRecordsTest.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
@@ -41,9 +41,9 @@ import static org.testng.Assert.*;
  */
 @Test
 public class VarargsRecordsTest {
-    record RI(int... xs) { }
-    record RII(int x, int... xs) { }
-    record RX(int[] xs) { }
+    public record RI(int... xs) { }
+    public record RII(int x, int... xs) { }
+    public record RX(int[] xs) { }
 
     RI r1 = new RI();
     RI r2 = new RI(1);

From 42bad03de8673d72b1764bc4a78c0459eca55ed1 Mon Sep 17 00:00:00 2001
From: Joe Darcy 
Date: Sun, 17 May 2020 11:34:32 -0700
Subject: [PATCH 088/143] 8245146: Update description of
 SourceVersion.RELEASE_15 with text blocks

Reviewed-by: jlaskey
---
 .../share/classes/javax/lang/model/SourceVersion.java         | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/java.compiler/share/classes/javax/lang/model/SourceVersion.java b/src/java.compiler/share/classes/javax/lang/model/SourceVersion.java
index aa7f31e3c68..2401bbca32b 100644
--- a/src/java.compiler/share/classes/javax/lang/model/SourceVersion.java
+++ b/src/java.compiler/share/classes/javax/lang/model/SourceVersion.java
@@ -62,7 +62,7 @@ public enum SourceVersion {
      *  13: no changes (switch expressions and text blocks in preview)
      *  14: switch expressions (pattern matching and records in
      *      preview, text blocks in preview again)
-     *  15: TBD
+     *  15: text blocks (records and pattern matching in preview again)
      */
 
     /**
@@ -211,6 +211,8 @@ public enum SourceVersion {
      * The version recognized by the Java Platform, Standard Edition
      * 15.
      *
+     * Additions in this release include text blocks.
+     *
      * @since 15
      */
      RELEASE_15;

From 0f7aeed4164dde9702843205e753dfc09728e39f Mon Sep 17 00:00:00 2001
From: Michael McMahon 
Date: Sun, 17 May 2020 21:15:33 +0100
Subject: [PATCH 089/143] 8241305: Add protocol specific factory creation
 methods to SocketChannel and ServerSocketChannel

Reviewed-by: alanb, chegar, dfuchs
---
 .../java/nio/channels/DatagramChannel.java    |   3 +-
 .../nio/channels/ServerSocketChannel.java     |  32 +-
 .../java/nio/channels/SocketChannel.java      |  32 +-
 .../nio/channels/spi/SelectorProvider.java    |  48 +++
 .../share/classes/sun/nio/ch/Net.java         |  59 ++-
 .../sun/nio/ch/SelectorProviderImpl.java      |  12 +-
 .../sun/nio/ch/ServerSocketChannelImpl.java   |  43 +-
 .../classes/sun/nio/ch/SocketChannelImpl.java |  68 +++-
 .../classes/sun/nio/ch/InheritedChannel.java  |  15 +-
 .../channels/etc/LocalSocketAddressType.java  | 102 +++++
 .../java/nio/channels/etc/OpenAndConnect.java | 282 +++++++++++++
 .../nio/channels/etc/ProtocolFamilies.java    | 381 ++++++++++++++++++
 12 files changed, 1044 insertions(+), 33 deletions(-)
 create mode 100644 test/jdk/java/nio/channels/etc/LocalSocketAddressType.java
 create mode 100644 test/jdk/java/nio/channels/etc/OpenAndConnect.java
 create mode 100644 test/jdk/java/nio/channels/etc/ProtocolFamilies.java

diff --git a/src/java.base/share/classes/java/nio/channels/DatagramChannel.java b/src/java.base/share/classes/java/nio/channels/DatagramChannel.java
index a4319ce0348..2838bce939b 100644
--- a/src/java.base/share/classes/java/nio/channels/DatagramChannel.java
+++ b/src/java.base/share/classes/java/nio/channels/DatagramChannel.java
@@ -33,6 +33,7 @@ import java.net.SocketAddress;
 import java.nio.ByteBuffer;
 import java.nio.channels.spi.AbstractSelectableChannel;
 import java.nio.channels.spi.SelectorProvider;
+import static java.util.Objects.requireNonNull;
 
 /**
  * A selectable channel for datagram-oriented sockets.
@@ -184,7 +185,7 @@ public abstract class DatagramChannel
      * @since   1.7
      */
     public static DatagramChannel open(ProtocolFamily family) throws IOException {
-        return SelectorProvider.provider().openDatagramChannel(family);
+        return SelectorProvider.provider().openDatagramChannel(requireNonNull(family));
     }
 
     /**
diff --git a/src/java.base/share/classes/java/nio/channels/ServerSocketChannel.java b/src/java.base/share/classes/java/nio/channels/ServerSocketChannel.java
index 24992385688..8beecb3ebaf 100644
--- a/src/java.base/share/classes/java/nio/channels/ServerSocketChannel.java
+++ b/src/java.base/share/classes/java/nio/channels/ServerSocketChannel.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2017, 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
@@ -26,11 +26,13 @@
 package java.nio.channels;
 
 import java.io.IOException;
+import java.net.ProtocolFamily;
 import java.net.ServerSocket;
 import java.net.SocketOption;
 import java.net.SocketAddress;
 import java.nio.channels.spi.AbstractSelectableChannel;
 import java.nio.channels.spi.SelectorProvider;
+import static java.util.Objects.requireNonNull;
 
 /**
  * A selectable channel for stream-oriented listening sockets.
@@ -113,6 +115,34 @@ public abstract class ServerSocketChannel
         return SelectorProvider.provider().openServerSocketChannel();
     }
 
+    /**
+     * Opens a server-socket channel.The {@code family} parameter specifies the
+     * {@link ProtocolFamily protocol family} of the channel's socket.
+     *
+     * 

The new channel is created by invoking the {@link + * java.nio.channels.spi.SelectorProvider#openServerSocketChannel(ProtocolFamily) + * openServerSocketChannel(ProtocolFamily)} method of the system-wide default {@link + * java.nio.channels.spi.SelectorProvider} object.

+ * + * @param family + * The protocol family + * + * @return A new socket channel + * + * @throws UnsupportedOperationException + * If the specified protocol family is not supported. For example, + * suppose the parameter is specified as {@link + * java.net.StandardProtocolFamily#INET6 StandardProtocolFamily.INET6} + * but IPv6 is not enabled on the platform. + * @throws IOException + * If an I/O error occurs + * + * @since 15 + */ + public static ServerSocketChannel open(ProtocolFamily family) throws IOException { + return SelectorProvider.provider().openServerSocketChannel(requireNonNull(family)); + } + /** * Returns an operation set identifying this channel's supported * operations. diff --git a/src/java.base/share/classes/java/nio/channels/SocketChannel.java b/src/java.base/share/classes/java/nio/channels/SocketChannel.java index b3b73dd7dfa..d97ebc681c7 100644 --- a/src/java.base/share/classes/java/nio/channels/SocketChannel.java +++ b/src/java.base/share/classes/java/nio/channels/SocketChannel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2017, 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 @@ -26,12 +26,14 @@ package java.nio.channels; import java.io.IOException; +import java.net.ProtocolFamily; import java.net.Socket; import java.net.SocketOption; import java.net.SocketAddress; import java.nio.ByteBuffer; import java.nio.channels.spi.AbstractSelectableChannel; import java.nio.channels.spi.SelectorProvider; +import static java.util.Objects.requireNonNull; /** * A selectable channel for stream-oriented connecting sockets. @@ -150,6 +152,34 @@ public abstract class SocketChannel return SelectorProvider.provider().openSocketChannel(); } + /** + * Opens a socket channel. The {@code family} parameter specifies the + * {@link ProtocolFamily protocol family} of the channel's socket. + * + *

The new channel is created by invoking the {@link + * java.nio.channels.spi.SelectorProvider#openSocketChannel(ProtocolFamily) + * openSocketChannel(ProtocolFamily)} method of the system-wide default. + * {@link java.nio.channels.spi.SelectorProvider} object.

+ * + * @param family + * The protocol family + * + * @return A new socket channel + * + * @throws UnsupportedOperationException + * If the specified protocol family is not supported. For example, + * suppose the parameter is specified as {@link + * java.net.StandardProtocolFamily#INET6 StandardProtocolFamily.INET6} + * but IPv6 is not enabled on the platform. + * @throws IOException + * If an I/O error occurs + * + * @since 15 + */ + public static SocketChannel open(ProtocolFamily family) throws IOException { + return SelectorProvider.provider().openSocketChannel(requireNonNull(family)); + } + /** * Opens a socket channel and connects it to a remote address. * diff --git a/src/java.base/share/classes/java/nio/channels/spi/SelectorProvider.java b/src/java.base/share/classes/java/nio/channels/spi/SelectorProvider.java index 310f28575ba..4aee1cf41c8 100644 --- a/src/java.base/share/classes/java/nio/channels/spi/SelectorProvider.java +++ b/src/java.base/share/classes/java/nio/channels/spi/SelectorProvider.java @@ -36,6 +36,7 @@ import java.nio.channels.SocketChannel; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.Iterator; +import java.util.Objects; import java.util.ServiceLoader; import java.util.ServiceConfigurationError; @@ -315,4 +316,51 @@ public abstract class SelectorProvider { return null; } + /** + * Opens a socket channel. + * + * @implSpec The default implementation of this method first checks that + * the given protocol {@code family} is not {@code null}, + * then throws {@link UnsupportedOperationException}. + * + * @param family + * The protocol family + * + * @return The new channel + * + * @throws UnsupportedOperationException + * If the specified protocol family is not supported + * @throws IOException + * If an I/O error occurs + * + * @since 15 + */ + public SocketChannel openSocketChannel(ProtocolFamily family) throws IOException { + Objects.requireNonNull(family); + throw new UnsupportedOperationException("Protocol family not supported"); + } + + /** + * Opens a server-socket channel. + * + * @implSpec The default implementation of this method first checks that + * the given protocol {@code family} is not {@code null}, + * then throws {@link UnsupportedOperationException}. + * + * @param family + * The protocol family + * + * @return The new channel + * + * @throws UnsupportedOperationException + * If the specified protocol family is not supported + * @throws IOException + * If an I/O error occurs + * + * @since 15 + */ + public ServerSocketChannel openServerSocketChannel(ProtocolFamily family) throws IOException { + Objects.requireNonNull(family); + throw new UnsupportedOperationException("Protocol family not supported"); + } } diff --git a/src/java.base/share/classes/sun/nio/ch/Net.java b/src/java.base/share/classes/sun/nio/ch/Net.java index d442ec94dc5..26f5a5b0fe8 100644 --- a/src/java.base/share/classes/sun/nio/ch/Net.java +++ b/src/java.base/share/classes/sun/nio/ch/Net.java @@ -249,6 +249,57 @@ public class Net { port); } + private static final InetAddress anyLocalInet4Address; + private static final InetAddress anyLocalInet6Address; + private static final InetAddress inet4LoopbackAddress; + private static final InetAddress inet6LoopbackAddress; + static { + try { + anyLocalInet4Address = inet4FromInt(0); + assert anyLocalInet4Address instanceof Inet4Address + && anyLocalInet4Address.isAnyLocalAddress(); + + anyLocalInet6Address = InetAddress.getByAddress(new byte[16]); + assert anyLocalInet6Address instanceof Inet6Address + && anyLocalInet6Address.isAnyLocalAddress(); + + inet4LoopbackAddress = inet4FromInt(0x7f000001); + assert inet4LoopbackAddress instanceof Inet4Address + && inet4LoopbackAddress.isLoopbackAddress(); + + byte[] bytes = new byte[16]; + bytes[15] = 0x01; + inet6LoopbackAddress = InetAddress.getByAddress(bytes); + assert inet6LoopbackAddress instanceof Inet6Address + && inet6LoopbackAddress.isLoopbackAddress(); + } catch (Exception e) { + throw new InternalError(e); + } + } + + static InetAddress inet4LoopbackAddress() { + return inet4LoopbackAddress; + } + + static InetAddress inet6LoopbackAddress() { + return inet6LoopbackAddress; + } + + /** + * Returns the wildcard address that corresponds to the given protocol family. + * + * @see InetAddress#isAnyLocalAddress() + */ + static InetAddress anyLocalAddress(ProtocolFamily family) { + if (family == StandardProtocolFamily.INET) { + return anyLocalInet4Address; + } else if (family == StandardProtocolFamily.INET6) { + return anyLocalInet6Address; + } else { + throw new IllegalArgumentException(); + } + } + /** * Returns any IPv4 address of the given network interface, or * null if the interface does not have any IPv4 addresses. @@ -467,7 +518,13 @@ public class Net { } static FileDescriptor serverSocket(boolean stream) { - return IOUtil.newFD(socket0(isIPv6Available(), stream, true, fastLoopback)); + return serverSocket(UNSPEC, stream); + } + + static FileDescriptor serverSocket(ProtocolFamily family, boolean stream) { + boolean preferIPv6 = isIPv6Available() && + (family != StandardProtocolFamily.INET); + return IOUtil.newFD(socket0(preferIPv6, stream, true, fastLoopback)); } // Due to oddities SO_REUSEADDR on windows reuse is ignored diff --git a/src/java.base/share/classes/sun/nio/ch/SelectorProviderImpl.java b/src/java.base/share/classes/sun/nio/ch/SelectorProviderImpl.java index 9425ecaa050..2fd6a984140 100644 --- a/src/java.base/share/classes/sun/nio/ch/SelectorProviderImpl.java +++ b/src/java.base/share/classes/sun/nio/ch/SelectorProviderImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2019, 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 @@ -72,4 +72,14 @@ public abstract class SelectorProviderImpl public SocketChannel openSocketChannel() throws IOException { return new SocketChannelImpl(this); } + + @Override + public SocketChannel openSocketChannel(ProtocolFamily family) throws IOException { + return new SocketChannelImpl(this, family); + } + + @Override + public ServerSocketChannel openServerSocketChannel(ProtocolFamily family) { + return new ServerSocketChannelImpl(this, family); + } } diff --git a/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java b/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java index 0b88e59becd..06915cb6cc5 100644 --- a/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java +++ b/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java @@ -28,10 +28,12 @@ package sun.nio.ch; import java.io.FileDescriptor; import java.io.IOException; import java.net.InetSocketAddress; +import java.net.ProtocolFamily; import java.net.ServerSocket; import java.net.SocketAddress; import java.net.SocketOption; import java.net.SocketTimeoutException; +import java.net.StandardProtocolFamily; import java.net.StandardSocketOptions; import java.nio.channels.AlreadyBoundException; import java.nio.channels.AsynchronousCloseException; @@ -62,6 +64,9 @@ class ServerSocketChannelImpl // Used to make native close and configure calls private static final NativeDispatcher nd = new SocketDispatcher(); + // The protocol family of the socket + private final ProtocolFamily family; + // Our file descriptor private final FileDescriptor fd; private final int fdVal; @@ -95,10 +100,26 @@ class ServerSocketChannelImpl // -- End of fields protected by stateLock - ServerSocketChannelImpl(SelectorProvider sp) { + this(sp, Net.isIPv6Available() + ? StandardProtocolFamily.INET6 + : StandardProtocolFamily.INET); + } + + ServerSocketChannelImpl(SelectorProvider sp, ProtocolFamily family) { super(sp); - this.fd = Net.serverSocket(true); + Objects.requireNonNull(family, "'family' is null"); + + if ((family != StandardProtocolFamily.INET) && + (family != StandardProtocolFamily.INET6)) { + throw new UnsupportedOperationException("Protocol family not supported"); + } + if (family == StandardProtocolFamily.INET6 && !Net.isIPv6Available()) { + throw new UnsupportedOperationException("IPv6 not available"); + } + + this.family = family; + this.fd = Net.serverSocket(family, true); this.fdVal = IOUtil.fdVal(fd); } @@ -106,8 +127,13 @@ class ServerSocketChannelImpl throws IOException { super(sp); + + this.family = Net.isIPv6Available() + ? StandardProtocolFamily.INET6 + : StandardProtocolFamily.INET; this.fd = fd; this.fdVal = IOUtil.fdVal(fd); + if (bound) { synchronized (stateLock) { localAddress = Net.localAddress(fd); @@ -210,14 +236,17 @@ class ServerSocketChannelImpl ensureOpen(); if (localAddress != null) throw new AlreadyBoundException(); - InetSocketAddress isa = (local == null) - ? new InetSocketAddress(0) - : Net.checkAddress(local); + InetSocketAddress isa; + if (local == null) { + isa = new InetSocketAddress(Net.anyLocalAddress(family), 0); + } else { + isa = Net.checkAddress(local, family); + } SecurityManager sm = System.getSecurityManager(); if (sm != null) sm.checkListen(isa.getPort()); NetHooks.beforeTcpBind(fd, isa.getAddress(), isa.getPort()); - Net.bind(fd, isa.getAddress(), isa.getPort()); + Net.bind(family, fd, isa.getAddress(), isa.getPort()); Net.listen(fd, backlog < 1 ? 50 : backlog); localAddress = Net.localAddress(fd); } @@ -358,7 +387,7 @@ class ServerSocketChannelImpl if (sm != null) { sm.checkAccept(isa.getAddress().getHostAddress(), isa.getPort()); } - return new SocketChannelImpl(provider(), newfd, isa); + return new SocketChannelImpl(provider(), family, newfd, isa); } catch (Exception e) { nd.close(newfd); throw e; diff --git a/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java b/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java index c0faf929c38..ddf8a87955c 100644 --- a/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java +++ b/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java @@ -28,6 +28,7 @@ package sun.nio.ch; import java.io.FileDescriptor; import java.io.IOException; import java.net.InetAddress; +import java.net.Inet4Address; import java.net.InetSocketAddress; import java.net.ProtocolFamily; import java.net.Socket; @@ -71,6 +72,9 @@ class SocketChannelImpl // Used to make native read and write calls private static final NativeDispatcher nd = new SocketDispatcher(); + // The protocol family of the socket + private final ProtocolFamily family; + // Our file descriptor object private final FileDescriptor fd; private final int fdVal; @@ -118,12 +122,26 @@ class SocketChannelImpl // -- End of fields protected by stateLock - // Constructor for normal connecting sockets // SocketChannelImpl(SelectorProvider sp) throws IOException { + this(sp, Net.isIPv6Available() + ? StandardProtocolFamily.INET6 + : StandardProtocolFamily.INET); + } + + SocketChannelImpl(SelectorProvider sp, ProtocolFamily family) throws IOException { super(sp); - this.fd = Net.socket(true); + Objects.requireNonNull(family, "'family' is null"); + if ((family != StandardProtocolFamily.INET) && + (family != StandardProtocolFamily.INET6)) { + throw new UnsupportedOperationException("Protocol family not supported"); + } + if (family == StandardProtocolFamily.INET6 && !Net.isIPv6Available()) { + throw new UnsupportedOperationException("IPv6 not available"); + } + this.family = family; + this.fd = Net.socket(family, true); this.fdVal = IOUtil.fdVal(fd); } @@ -131,8 +149,12 @@ class SocketChannelImpl throws IOException { super(sp); + this.family = Net.isIPv6Available() + ? StandardProtocolFamily.INET6 + : StandardProtocolFamily.INET; this.fd = fd; this.fdVal = IOUtil.fdVal(fd); + if (bound) { synchronized (stateLock) { this.localAddress = Net.localAddress(fd); @@ -142,10 +164,14 @@ class SocketChannelImpl // Constructor for sockets obtained from server sockets // - SocketChannelImpl(SelectorProvider sp, FileDescriptor fd, InetSocketAddress isa) + SocketChannelImpl(SelectorProvider sp, + ProtocolFamily family, + FileDescriptor fd, + InetSocketAddress isa) throws IOException { super(sp); + this.family = family; this.fd = fd; this.fdVal = IOUtil.fdVal(fd); synchronized (stateLock) { @@ -225,8 +251,6 @@ class SocketChannelImpl ensureOpen(); if (name == StandardSocketOptions.IP_TOS) { - ProtocolFamily family = Net.isIPv6Available() ? - StandardProtocolFamily.INET6 : StandardProtocolFamily.INET; Net.setSocketOption(fd, family, name, value); return this; } @@ -260,10 +284,8 @@ class SocketChannelImpl return (T)Boolean.valueOf(isReuseAddress); } - // special handling for IP_TOS: always return 0 when IPv6 + // special handling for IP_TOS if (name == StandardSocketOptions.IP_TOS) { - ProtocolFamily family = Net.isIPv6Available() ? - StandardProtocolFamily.INET6 : StandardProtocolFamily.INET; return (T) Net.getSocketOption(fd, family, name); } @@ -632,14 +654,18 @@ class SocketChannelImpl throw new ConnectionPendingException(); if (localAddress != null) throw new AlreadyBoundException(); - InetSocketAddress isa = (local == null) ? - new InetSocketAddress(0) : Net.checkAddress(local); + InetSocketAddress isa; + if (local == null) { + isa = new InetSocketAddress(Net.anyLocalAddress(family), 0); + } else { + isa = Net.checkAddress(local, family); + } SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkListen(isa.getPort()); } NetHooks.beforeTcpBind(fd, isa.getAddress(), isa.getPort()); - Net.bind(fd, isa.getAddress(), isa.getPort()); + Net.bind(family, fd, isa.getAddress(), isa.getPort()); localAddress = Net.localAddress(fd); } } finally { @@ -723,14 +749,21 @@ class SocketChannelImpl /** * Checks the remote address to which this channel is to be connected. */ - private InetSocketAddress checkRemote(SocketAddress sa) throws IOException { - InetSocketAddress isa = Net.checkAddress(sa); + private InetSocketAddress checkRemote(SocketAddress sa) { + InetSocketAddress isa = Net.checkAddress(sa, family); SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkConnect(isa.getAddress().getHostAddress(), isa.getPort()); } - if (isa.getAddress().isAnyLocalAddress()) { - return new InetSocketAddress(InetAddress.getLocalHost(), isa.getPort()); + InetAddress address = isa.getAddress(); + if (address.isAnyLocalAddress()) { + int port = isa.getPort(); + if (address instanceof Inet4Address) { + return new InetSocketAddress(Net.inet4LoopbackAddress(), port); + } else { + assert family == StandardProtocolFamily.INET6; + return new InetSocketAddress(Net.inet6LoopbackAddress(), port); + } } else { return isa; } @@ -748,7 +781,10 @@ class SocketChannelImpl boolean connected = false; try { beginConnect(blocking, isa); - int n = Net.connect(fd, isa.getAddress(), isa.getPort()); + int n = Net.connect(family, + fd, + isa.getAddress(), + isa.getPort()); if (n > 0) { connected = true; } else if (blocking) { diff --git a/src/java.base/unix/classes/sun/nio/ch/InheritedChannel.java b/src/java.base/unix/classes/sun/nio/ch/InheritedChannel.java index 3c44b4b583f..845433becb1 100644 --- a/src/java.base/unix/classes/sun/nio/ch/InheritedChannel.java +++ b/src/java.base/unix/classes/sun/nio/ch/InheritedChannel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, 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 @@ -29,12 +29,13 @@ import java.lang.reflect.Constructor; import java.io.FileDescriptor; import java.io.IOException; import java.net.InetAddress; +import java.net.Inet6Address; import java.net.InetSocketAddress; +import java.net.ProtocolFamily; import java.nio.channels.Channel; -import java.nio.channels.SocketChannel; -import java.nio.channels.ServerSocketChannel; -import java.nio.channels.DatagramChannel; import java.nio.channels.spi.SelectorProvider; +import static java.net.StandardProtocolFamily.INET6; +import static java.net.StandardProtocolFamily.INET; class InheritedChannel { @@ -81,12 +82,16 @@ class InheritedChannel { */ public static class InheritedSocketChannelImpl extends SocketChannelImpl { + static ProtocolFamily family(InetSocketAddress isa) { + return (isa.getAddress() instanceof Inet6Address) ? INET6 : INET; + } + InheritedSocketChannelImpl(SelectorProvider sp, FileDescriptor fd, InetSocketAddress remote) throws IOException { - super(sp, fd, remote); + super(sp, family(remote), fd, remote); } protected void implCloseSelectableChannel() throws IOException { diff --git a/test/jdk/java/nio/channels/etc/LocalSocketAddressType.java b/test/jdk/java/nio/channels/etc/LocalSocketAddressType.java new file mode 100644 index 00000000000..63be790c478 --- /dev/null +++ b/test/jdk/java/nio/channels/etc/LocalSocketAddressType.java @@ -0,0 +1,102 @@ +/* + * 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 Test local address type + * @library /test/lib + * @build jdk.test.lib.NetworkConfiguration + * @run testng/othervm LocalSocketAddressType + * @run testng/othervm -Djava.net.preferIPv4Stack=true LocalSocketAddressType + */ + +import jdk.test.lib.NetworkConfiguration; +import jdk.test.lib.net.IPSupport; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.net.*; +import java.nio.channels.DatagramChannel; +import java.nio.channels.ServerSocketChannel; +import java.nio.channels.SocketChannel; +import java.util.Iterator; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static java.lang.Boolean.parseBoolean; +import static java.lang.System.getProperty; +import static java.lang.System.out; +import static jdk.test.lib.Asserts.assertEquals; +import static jdk.test.lib.Asserts.assertTrue; +import static jdk.test.lib.net.IPSupport.*; + +public class LocalSocketAddressType { + + @BeforeTest() + public void setup() { + IPSupport.printPlatformSupport(out); + throwSkippedExceptionIfNonOperational(); + } + + @DataProvider(name = "addresses") + public static Iterator addresses() throws Exception { + NetworkConfiguration nc = NetworkConfiguration.probe(); + return Stream.concat(nc.ip4Addresses(), nc.ip6Addresses()) + .map(ia -> new Object[] { new InetSocketAddress(ia, 0) }) + .iterator(); + } + + @Test(dataProvider = "addresses") + public static void testSocketChannel(InetSocketAddress addr) throws Exception { + try (var c = SocketChannel.open()) { + Class cls = addr.getAddress().getClass(); + InetAddress ia = ((InetSocketAddress)c.bind(addr).getLocalAddress()).getAddress(); + assertEquals(ia.getClass(), cls); + ia = c.socket().getLocalAddress(); + assertEquals(ia.getClass(), cls); + } + } + + @Test(dataProvider = "addresses") + public static void testServerSocketChannel(InetSocketAddress addr) throws Exception { + try (var c = ServerSocketChannel.open()) { + Class cls = addr.getAddress().getClass(); + InetAddress ia = ((InetSocketAddress)c.bind(addr).getLocalAddress()).getAddress(); + assertEquals(ia.getClass(), cls); + ia = c.socket().getInetAddress(); + assertEquals(ia.getClass(), cls); + } + } + + @Test(dataProvider = "addresses") + public static void testDatagramChannel(InetSocketAddress addr) throws Exception { + try (var c = DatagramChannel.open()) { + Class cls = addr.getAddress().getClass(); + InetAddress ia = ((InetSocketAddress)c.bind(addr).getLocalAddress()).getAddress(); + assertEquals(ia.getClass(), cls); + ia = c.socket().getLocalAddress(); + assertEquals(ia.getClass(), cls); + } + } +} diff --git a/test/jdk/java/nio/channels/etc/OpenAndConnect.java b/test/jdk/java/nio/channels/etc/OpenAndConnect.java new file mode 100644 index 00000000000..01c38c2ec91 --- /dev/null +++ b/test/jdk/java/nio/channels/etc/OpenAndConnect.java @@ -0,0 +1,282 @@ +/* + * 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 jdk.test.lib.NetworkConfiguration; +import jdk.test.lib.net.IPSupport; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.io.IOException; +import java.net.*; +import java.nio.channels.*; +import java.util.Arrays; +import java.util.List; +import java.util.LinkedList; + +import static java.lang.System.getProperty; +import static java.lang.System.out; +import static java.net.StandardProtocolFamily.INET; +import static java.net.StandardProtocolFamily.INET6; +import static jdk.test.lib.net.IPSupport.*; + +/* + * @test + * @summary Test SocketChannel, ServerSocketChannel and DatagramChannel + * open() and connect(), taking into consideration combinations of + * protocol families (INET, INET6, default), + * addresses (Inet4Address, Inet6Address). + * @library /test/lib + * @build jdk.test.lib.NetworkConfiguration + * @run testng/othervm OpenAndConnect + */ + + +public class OpenAndConnect { + static final Inet4Address IA4ANYLOCAL; + static final Inet6Address IA6ANYLOCAL; + static final Inet4Address IA4LOOPBACK; + static final Inet6Address IA6LOOPBACK; + static Inet4Address IA4LOCAL = null; + static Inet6Address IA6LOCAL = null; + static InetAddress DONT_BIND; + + static { + try { + IA4ANYLOCAL = (Inet4Address) InetAddress.getByName("0.0.0.0"); + IA6ANYLOCAL = (Inet6Address) InetAddress.getByName("::0"); + IA4LOOPBACK = (Inet4Address) InetAddress.getByName("127.0.0.1"); + IA6LOOPBACK = (Inet6Address) InetAddress.getByName("::1"); + + // Special value to tell test not to call bind (address is not used) + DONT_BIND = (Inet4Address) InetAddress.getByName("127.0.0.3"); + + initAddrs(); + } catch (Exception e) { + throw new RuntimeException("Could not initialize addresses", e); + } + } + + @BeforeTest() + public void setup() { + NetworkConfiguration.printSystemConfiguration(out); + IPSupport.printPlatformSupport(out); + throwSkippedExceptionIfNonOperational(); + + out.println("IA4LOCAL: " + IA4LOCAL); + out.println("IA6LOCAL: " + IA6LOCAL); + out.println("IA4ANYLOCAL: " + IA4ANYLOCAL); + out.println("IA6ANYLOCAL: " + IA6ANYLOCAL); + out.println("IA4LOOPBACK: " + IA4LOOPBACK); + out.println("IA6LOOPBACK: " + IA6LOOPBACK); + } + + @DataProvider(name = "openConnect") + public Object[][] openConnect() { + LinkedList l = new LinkedList<>(); + l.addAll(openConnectGenTests); + if (IA4LOCAL != null) { + l.addAll(openConnectV4LocalTests); + } + if (IA6LOCAL != null) { + l.addAll(openConnectV6LocalTests); + } + return l.toArray(new Object[][]{}); + } + + // +----- sfam is server/first socket family + // | + // | +------ saddr is bind address for server/first socket + // | | + // | | +---- cfam is family for client/second socket + // | | | + // | | | +---- caddr is address client/second + // | | | | socket binds to. When the server + // | | | | has bound to a wildcard address + // | | | | this is address used for connect + // | | | | also. + // | | | | + // | | | | + // | | | | + // | | | | + // + + + + + // { sfam, saddr, cfam, caddr, } + + public static List openConnectGenTests = + Arrays.asList(new Object[][] { + { INET, IA4LOOPBACK, INET, IA4LOOPBACK }, + { INET, IA4LOOPBACK, null, IA4LOOPBACK }, + { INET, IA4ANYLOCAL, null, IA4LOOPBACK }, + { INET, IA4ANYLOCAL, INET, IA4LOOPBACK }, + { INET6, IA6ANYLOCAL, null, IA6LOOPBACK }, + { INET6, IA6ANYLOCAL, INET6, IA6LOOPBACK }, + { INET6, IA6LOOPBACK, INET6, IA6LOOPBACK }, + { null, IA4LOOPBACK, INET, IA4ANYLOCAL }, + { null, IA4LOOPBACK, INET, IA4LOOPBACK }, + { null, IA4LOOPBACK, INET, null }, + { null, IA4LOOPBACK, INET6, IA6ANYLOCAL }, + { null, IA6LOOPBACK, INET6, IA6ANYLOCAL }, + { null, IA6LOOPBACK, INET6, IA6LOOPBACK }, + { null, IA6LOOPBACK, INET6, DONT_BIND }, + { null, IA4LOOPBACK, INET6, DONT_BIND }, + { null, IA4LOOPBACK, INET6, null }, + { null, IA6LOOPBACK, INET6, null }, + { null, IA4LOOPBACK, null, IA6ANYLOCAL }, + { null, IA6LOOPBACK, null, IA6ANYLOCAL }, + { null, IA6LOOPBACK, null, IA6LOOPBACK }, + { null, IA4LOOPBACK, null, null }, + { null, IA6LOOPBACK, null, null }, + { null, IA6ANYLOCAL, null, IA6LOCAL }, + { null, IA6ANYLOCAL, null, IA6LOOPBACK }, + { null, IA6ANYLOCAL, INET6, IA6LOCAL }, + { null, IA6ANYLOCAL, INET6, IA6LOOPBACK }, + { INET6, IA6LOOPBACK, INET6, IA6LOOPBACK } + }); + + // Additional tests for when an IPv4 local address or V6 + // local address is available + + public List openConnectV4LocalTests = + Arrays.asList(new Object[][] { + { INET, IA4LOCAL, INET, IA4LOCAL }, + { INET, IA4LOCAL, null, IA4LOCAL }, + { INET, IA4LOCAL, null, DONT_BIND }, + { INET, IA4ANYLOCAL, INET, IA4LOCAL }, + { INET, IA4ANYLOCAL, null, IA4LOCAL }, + { null, IA4LOCAL, INET, IA4ANYLOCAL }, + { null, IA4LOCAL, INET, IA4LOCAL }, + { null, IA4LOCAL, INET, null }, + { null, IA4LOCAL, INET6, IA6ANYLOCAL }, + { null, IA4LOCAL, INET6, null }, + { null, IA4LOCAL, null, IA6ANYLOCAL } + }); + + public List openConnectV6LocalTests = + Arrays.asList(new Object[][] { + { INET6, IA6ANYLOCAL, null, IA6LOCAL }, + { INET6, IA6ANYLOCAL, INET6, IA6LOCAL }, + { INET6, IA6LOCAL, INET6, IA6LOCAL }, + { INET6, IA6LOCAL, null, IA6LOCAL }, + { INET6, IA6LOCAL, null, DONT_BIND }, + { null, IA6LOCAL, INET6, IA6LOCAL }, + { null, IA6LOCAL, INET6, IA6ANYLOCAL }, + { null, IA6LOCAL, null, IA6ANYLOCAL }, + { null, IA6LOCAL, null, IA6LOCAL }, + { null, IA6LOCAL, INET6, null }, + { null, IA6LOCAL, null, null }, + { null, IA4LOCAL, null, null }, + { INET6, IA6LOCAL, INET6, IA6LOCAL } + }); + + + /** + * If the destination address is the wildcard, it is replaced by the alternate + * using the port number from destination. Otherwise destination is returned. + * Only used by dcOpenAndConnect + */ + static InetSocketAddress getDestinationAddress(SocketAddress destination, InetAddress alternate) { + InetSocketAddress isa = (InetSocketAddress)destination; + if (isa.getAddress().isAnyLocalAddress()) + return new InetSocketAddress(alternate, isa.getPort()); + else + return isa; + } + + @Test(dataProvider = "openConnect") + public void scOpenAndConnect(ProtocolFamily sfam, + InetAddress saddr, + ProtocolFamily cfam, + InetAddress caddr) throws IOException + { + out.printf("scOpenAndConnect: server bind: %s client bind: %s\n", saddr, caddr); + try (ServerSocketChannel ssc = openSSC(sfam)) { + ssc.bind(getSocketAddress(saddr)); + InetSocketAddress ssa = (InetSocketAddress)ssc.getLocalAddress(); + ssa = getDestinationAddress(ssa, caddr); + out.println(ssa); + try (SocketChannel csc = openSC(cfam)) { + if (caddr != DONT_BIND) { + csc.bind(getSocketAddress(caddr)); + } + csc.connect(ssa); + } + } + } + + @Test(dataProvider = "openConnect") + public void dcOpenAndConnect(ProtocolFamily sfam, + InetAddress saddr, + ProtocolFamily cfam, + InetAddress caddr) throws IOException + { + try (DatagramChannel sdc = openDC(sfam)) { + sdc.bind(getSocketAddress(saddr)); + SocketAddress ssa = sdc.socket().getLocalSocketAddress(); + ssa = getDestinationAddress(ssa, caddr); + out.println(ssa); + try (DatagramChannel dc = openDC(cfam)) { + if (caddr != DONT_BIND) { + dc.bind(getSocketAddress(caddr)); + } + dc.connect(ssa); + } + } + } + + // Helper methods + + private static SocketChannel openSC(ProtocolFamily fam) throws IOException { + return fam == null ? SocketChannel.open() : SocketChannel.open(fam); + } + + private static ServerSocketChannel openSSC(ProtocolFamily fam) + throws IOException { + return fam == null ? ServerSocketChannel.open() + : ServerSocketChannel.open(fam); + } + + private static DatagramChannel openDC(ProtocolFamily fam) + throws IOException { + return fam == null ? DatagramChannel.open() + : DatagramChannel.open(fam); + } + + private static SocketAddress getSocketAddress(InetAddress ia) { + return ia == null ? null : new InetSocketAddress(ia, 0); + } + + private static void initAddrs() throws IOException { + + NetworkConfiguration cfg = NetworkConfiguration.probe(); + + IA4LOCAL = cfg.ip4Addresses() + .filter(a -> !a.isLoopbackAddress()) + .findFirst() + .orElse(null); + + IA6LOCAL = cfg.ip6Addresses() + .filter(a -> !a.isLoopbackAddress()) + .findFirst() + .orElse(null); + } +} diff --git a/test/jdk/java/nio/channels/etc/ProtocolFamilies.java b/test/jdk/java/nio/channels/etc/ProtocolFamilies.java new file mode 100644 index 00000000000..3fee417d684 --- /dev/null +++ b/test/jdk/java/nio/channels/etc/ProtocolFamilies.java @@ -0,0 +1,381 @@ +/* + * 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 jdk.test.lib.NetworkConfiguration; +import jdk.test.lib.Platform; +import jdk.test.lib.net.IPSupport; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; +import org.testng.Assert.ThrowingRunnable; +import java.io.IOException; +import java.net.*; +import java.nio.channels.*; +import java.nio.channels.spi.AbstractSelector; +import java.nio.channels.spi.SelectorProvider; +import static java.lang.System.out; +import static java.lang.System.getProperty; +import static java.lang.Boolean.parseBoolean; +import static java.net.StandardProtocolFamily.INET; +import static java.net.StandardProtocolFamily.INET6; +import static jdk.test.lib.net.IPSupport.*; +import static org.testng.Assert.assertThrows; + +/* + * @test + * @summary Test SocketChannel, ServerSocketChannel and DatagramChannel + * with various ProtocolFamily combinations + * @library /test/lib + * @build jdk.test.lib.NetworkConfiguration + * @run testng ProtocolFamilies + * @run testng/othervm -Djava.net.preferIPv4Stack=true ProtocolFamilies + */ + + +public class ProtocolFamilies { + static final boolean hasIPv6 = hasIPv6(); + static final boolean preferIPv4 = preferIPv4Stack(); + static Inet4Address ia4; + static Inet6Address ia6; + + @BeforeTest() + public void setup() throws Exception { + NetworkConfiguration.printSystemConfiguration(out); + IPSupport.printPlatformSupport(out); + throwSkippedExceptionIfNonOperational(); + + ia4 = getLocalIPv4Address(); + ia6 = getLocalIPv6Address(); + out.println("ia4: " + ia4); + out.println("ia6: " + ia6 + "\n"); + } + + static final Class UATE = UnsupportedAddressTypeException.class; + static final Class UOE = UnsupportedOperationException.class; + + @DataProvider(name = "open") + public Object[][] open() { + if (hasIPv6 && !preferIPv4) { + return new Object[][]{ + { INET, null }, + { INET6, null } + }; + } else { + return new Object[][]{ + { INET, null }, + { INET6, UOE } + }; + } + } + + @Test(dataProvider = "open") + public void scOpen(StandardProtocolFamily family, + Class expectedException) + throws Throwable + { + SocketChannel sc = null; + try { + if (expectedException == UOE) { + try { + sc = openSC(family); + } catch (UnsupportedOperationException e) {} + } else { + sc = openSC(family); + } + } finally { + if (sc != null) + sc.close(); + } + } + + @Test(dataProvider = "open") + public void sscOpen(StandardProtocolFamily family, + Class expectedException) + throws Throwable + { + ServerSocketChannel ssc = null; + try { + if (expectedException == UOE) { + try { + ssc = openSSC(family); + } catch (UnsupportedOperationException e) {} + } else { + openSSC(family); + } + } finally { + if (ssc != null) + ssc.close(); + } + } + + @Test(dataProvider = "open") + public void dcOpen(StandardProtocolFamily family, + Class expectedException) + throws Throwable + { + DatagramChannel dc = null; + try { + if (expectedException == UOE) { + try { + dc = openDC(family); + } catch (UnsupportedOperationException e) {} + } else { + openDC(family); + } + } finally { + if (dc != null) + dc.close(); + } + } + + @DataProvider(name = "openBind") + public Object[][] openBind() { + if (hasIPv6 && !preferIPv4) { + return new Object[][]{ + { INET, INET, null }, + { INET, INET6, UATE }, + { INET, null, null }, + { INET6, INET, null }, + { INET6, INET6, null }, + { INET6, null, null }, + { null, INET, null }, + { null, INET6, null }, + { null, null, null } + }; + } else { + return new Object[][]{ + { INET, INET, null }, + { INET, INET6, UATE }, + { INET, null, null }, + { null, INET, null }, + { null, INET6, UATE }, + { null, null, null } + }; + } + } + + // SocketChannel open - INET, INET6, default + // SocketChannel bind - INET, INET6, null + + @Test(dataProvider = "openBind") + public void scOpenBind(StandardProtocolFamily ofamily, + StandardProtocolFamily bfamily, + Class expectedException) + throws Throwable + { + try (SocketChannel sc = openSC(ofamily)) { + SocketAddress addr = getSocketAddress(bfamily); + ThrowingRunnable bindOp = () -> sc.bind(addr); + if (expectedException == null) + bindOp.run(); + else + assertThrows(expectedException, bindOp); + } + } + + // ServerSocketChannel open - INET, INET6, default + // ServerSocketChannel bind - INET, INET6, null + + @Test(dataProvider = "openBind") + public void sscOpenBind(StandardProtocolFamily ofamily, + StandardProtocolFamily bfamily, + Class expectedException) + throws Throwable + { + try (ServerSocketChannel ssc = openSSC(ofamily)) { + SocketAddress addr = getSocketAddress(bfamily); + ThrowingRunnable bindOp = () -> ssc.bind(addr); + if (expectedException == null) + bindOp.run(); + else + assertThrows(expectedException, bindOp); + } + } + + // DatagramChannel open - INET, INET6, default + // DatagramChannel bind - INET, INET6, null + + @Test(dataProvider = "openBind") + public void dcOpenBind(StandardProtocolFamily ofamily, + StandardProtocolFamily bfamily, + Class expectedException) + throws Throwable + { + try (DatagramChannel dc = openDC(ofamily)) { + SocketAddress addr = getSocketAddress(bfamily); + ThrowingRunnable bindOp = () -> dc.bind(addr); + if (expectedException == null) + bindOp.run(); + else + assertThrows(expectedException, bindOp); + } + } + + // SocketChannel open - INET, INET6, default + // SocketChannel connect - INET, INET6, default + + @DataProvider(name = "openConnect") + public Object[][] openConnect() { + if (hasIPv6 && !preferIPv4) { + return new Object[][]{ + { INET, INET, null }, + { INET, INET6, null }, + { INET, null, null }, + { INET6, INET, UATE }, + { INET6, INET6, null }, + { INET6, null, null }, + { null, INET, UATE }, + { null, INET6, null }, + { null, null, null } + }; + } else { + // INET6 channels cannot be created - UOE - tested elsewhere + return new Object[][]{ + { INET, INET, null }, + { INET, null, null }, + { null, INET, null }, + { null, null, null } + }; + } + } + + @Test(dataProvider = "openConnect") + public void scOpenConnect(StandardProtocolFamily sfamily, + StandardProtocolFamily cfamily, + Class expectedException) + throws Throwable + { + try (ServerSocketChannel ssc = openSSC(sfamily)) { + ssc.bind(null); + SocketAddress saddr = ssc.getLocalAddress(); + try (SocketChannel sc = openSC(cfamily)) { + if (expectedException == null) + sc.connect(saddr); + else + assertThrows(expectedException, () -> sc.connect(saddr)); + } + } + } + + static final Class NPE = NullPointerException.class; + + // Tests null handling + @Test + public void testNulls() { + assertThrows(NPE, () -> SocketChannel.open((ProtocolFamily)null)); + assertThrows(NPE, () -> ServerSocketChannel.open(null)); + assertThrows(NPE, () -> DatagramChannel.open(null)); + + assertThrows(NPE, () -> SelectorProvider.provider().openSocketChannel(null)); + assertThrows(NPE, () -> SelectorProvider.provider().openServerSocketChannel(null)); + assertThrows(NPE, () -> SelectorProvider.provider().openDatagramChannel(null)); + } + + static final ProtocolFamily BAD_PF = () -> "BAD_PROTOCOL_FAMILY"; + + // Tests UOE handling + @Test + public void testUoe() { + assertThrows(UOE, () -> SocketChannel.open(BAD_PF)); + assertThrows(UOE, () -> ServerSocketChannel.open(BAD_PF)); + assertThrows(UOE, () -> DatagramChannel.open(BAD_PF)); + + assertThrows(UOE, () -> SelectorProvider.provider().openSocketChannel(BAD_PF)); + assertThrows(UOE, () -> SelectorProvider.provider().openServerSocketChannel(BAD_PF)); + assertThrows(UOE, () -> SelectorProvider.provider().openDatagramChannel(BAD_PF)); + } + + // A concrete subclass of SelectorProvider, in order to test implSpec + static final SelectorProvider customerSelectorProvider = new SelectorProvider() { + @Override public DatagramChannel openDatagramChannel() { return null; } + @Override public DatagramChannel openDatagramChannel(ProtocolFamily family) { return null; } + @Override public Pipe openPipe() { return null; } + @Override public AbstractSelector openSelector() { return null; } + @Override public ServerSocketChannel openServerSocketChannel() { return null; } + @Override public SocketChannel openSocketChannel() { return null; } + }; + + // Tests the specified default implementation of SelectorProvider + @Test + public void testCustomProvider() { + assertThrows(NPE, () -> customerSelectorProvider.openSocketChannel(null)); + assertThrows(NPE, () -> customerSelectorProvider.openServerSocketChannel(null)); + + assertThrows(UOE, () -> customerSelectorProvider.openSocketChannel(BAD_PF)); + assertThrows(UOE, () -> customerSelectorProvider.openServerSocketChannel(BAD_PF)); + } + + // Helper methods + + private static SocketChannel openSC(StandardProtocolFamily family) + throws IOException { + return family == null ? SocketChannel.open() + : SocketChannel.open(family); + } + + private static ServerSocketChannel openSSC(StandardProtocolFamily family) + throws IOException { + return family == null ? ServerSocketChannel.open() + : ServerSocketChannel.open(family); + } + + private static DatagramChannel openDC(StandardProtocolFamily family) + throws IOException { + return family == null ? DatagramChannel.open() + : DatagramChannel.open(family); + } + + private static SocketAddress getSocketAddress(StandardProtocolFamily family) { + return family == null ? null : switch (family) { + case INET -> new InetSocketAddress(ia4, 0); + case INET6 -> new InetSocketAddress(ia6, 0); + }; + } + + private static SocketAddress getLoopback(StandardProtocolFamily family, int port) + throws UnknownHostException { + if ((family == null || family == INET6) && hasIPv6) { + return new InetSocketAddress(InetAddress.getByName("::1"), port); + } else { + return new InetSocketAddress(InetAddress.getByName("127.0.0.1"), port); + } + } + + private static Inet4Address getLocalIPv4Address() + throws Exception { + return NetworkConfiguration.probe() + .ip4Addresses() + .filter(a -> !a.isLoopbackAddress()) + .findFirst() + .orElse((Inet4Address)InetAddress.getByName("0.0.0.0")); + } + + private static Inet6Address getLocalIPv6Address() + throws Exception { + return NetworkConfiguration.probe() + .ip6Addresses() + .filter(a -> !a.isLoopbackAddress()) + .findFirst() + .orElse((Inet6Address) InetAddress.getByName("::0")); + } +} From d5bd523869b0cf0d99a5d0b5ba5a3bff4869bec4 Mon Sep 17 00:00:00 2001 From: Ioi Lam Date: Sun, 17 May 2020 15:10:06 -0700 Subject: [PATCH 090/143] 8244536: cds/DeterministicDump.java failed: File content different Reviewed-by: ccheung, stuefe --- src/hotspot/share/memory/filemap.cpp | 12 +-- src/hotspot/share/memory/heapShared.hpp | 5 +- test/hotspot/jtreg/ProblemList.txt | 1 - .../jtreg/runtime/cds/DeterministicDump.java | 82 +++++++++++++------ 4 files changed, 65 insertions(+), 35 deletions(-) diff --git a/src/hotspot/share/memory/filemap.cpp b/src/hotspot/share/memory/filemap.cpp index 25d4accb459..f2171e3dae7 100644 --- a/src/hotspot/share/memory/filemap.cpp +++ b/src/hotspot/share/memory/filemap.cpp @@ -207,16 +207,16 @@ void FileMapHeader::populate(FileMapInfo* mapinfo, size_t alignment) { _alignment = alignment; _obj_alignment = ObjectAlignmentInBytes; _compact_strings = CompactStrings; - _narrow_oop_mode = CompressedOops::mode(); - _narrow_oop_base = CompressedOops::base(); - _narrow_oop_shift = CompressedOops::shift(); + if (HeapShared::is_heap_object_archiving_allowed()) { + _narrow_oop_mode = CompressedOops::mode(); + _narrow_oop_base = CompressedOops::base(); + _narrow_oop_shift = CompressedOops::shift(); + _heap_end = CompressedOops::end(); + } _compressed_oops = UseCompressedOops; _compressed_class_ptrs = UseCompressedClassPointers; _max_heap_size = MaxHeapSize; _narrow_klass_shift = CompressedKlassPointers::shift(); - if (HeapShared::is_heap_object_archiving_allowed()) { - _heap_end = CompressedOops::end(); - } // The following fields are for sanity checks for whether this archive // will function correctly with this JVM and the bootclasspath it's diff --git a/src/hotspot/share/memory/heapShared.hpp b/src/hotspot/share/memory/heapShared.hpp index 90204d626c0..e814b4b8bec 100644 --- a/src/hotspot/share/memory/heapShared.hpp +++ b/src/hotspot/share/memory/heapShared.hpp @@ -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 @@ -141,7 +141,8 @@ class HeapShared: AllStatic { } static unsigned klass_hash(Klass* const& klass) { - return primitive_hash
((address)klass); + // Generate deterministic hashcode even if SharedBaseAddress is changed due to ASLR. + return primitive_hash
(address(klass) - SharedBaseAddress); } class DumpTimeKlassSubGraphInfoTable diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt index 82334a65328..9527ea4ec4d 100644 --- a/test/hotspot/jtreg/ProblemList.txt +++ b/test/hotspot/jtreg/ProblemList.txt @@ -95,7 +95,6 @@ gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java 8241293 macosx-x64 runtime/jni/terminatedThread/TestTerminatedThread.java 8219652 aix-ppc64 runtime/ReservedStack/ReservedStackTest.java 8231031 generic-all -runtime/cds/DeterministicDump.java 8244536 windows-all ############################################################################# diff --git a/test/hotspot/jtreg/runtime/cds/DeterministicDump.java b/test/hotspot/jtreg/runtime/cds/DeterministicDump.java index 4a7e7c40664..f8b633e991a 100644 --- a/test/hotspot/jtreg/runtime/cds/DeterministicDump.java +++ b/test/hotspot/jtreg/runtime/cds/DeterministicDump.java @@ -36,39 +36,69 @@ import jdk.test.lib.process.ProcessTools; import jdk.test.lib.process.OutputAnalyzer; import java.io.FileInputStream; import java.io.IOException; +import java.util.ArrayList; public class DeterministicDump { public static void main(String[] args) throws Exception { - for (int c = 0; c < 2; c++) { // oop/klass compression - String sign = (c == 0) ? "+" : "-"; - String coop = "-XX:" + sign + "UseCompressedOops"; - String ckls = "-XX:" + sign + "UseCompressedClassPointers"; + doTest(false); - if (!Platform.is64bit()) { - coop = "-showversion"; // no-op - ckls = "-showversion"; // no-op - } - - for (int gc = 0; gc < 2; gc++) { // should we trigger GC during dump - for (int i = 0; i < 2; i++) { - String metaspaceSize = "-showversion"; // no-op - if (gc == 1 && i == 1) { - // This will cause GC to happen after we've allocated 1MB of metaspace objects - // while processing the built-in SharedClassListFile. - metaspaceSize = "-XX:MetaspaceSize=1M"; - } - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( - coop, ckls, metaspaceSize, - "-XX:SharedArchiveFile=SharedArchiveFile" + i + ".jsa", - "-Xshare:dump", "-Xlog:cds=debug"); - OutputAnalyzer out = CDSTestUtils.executeAndLog(pb, "SharedArchiveFile" + i); - CDSTestUtils.checkDump(out); - } - compare("SharedArchiveFile0.jsa", "SharedArchiveFile1.jsa"); - } + if (Platform.is64bit()) { + // There's no oop/klass compression on 32-bit. + doTest(true); } } + public static void doTest(boolean compressed) throws Exception { + ArrayList baseArgs = new ArrayList<>(); + + // Use the same heap size as make/Images.gmk + baseArgs.add("-Xmx128M"); + + if (Platform.is64bit()) { + // These options are available only on 64-bit. + String sign = (compressed) ? "+" : "-"; + baseArgs.add("-XX:" + sign + "UseCompressedOops"); + baseArgs.add("-XX:" + sign + "UseCompressedClassPointers"); + } + + String baseArchive = dump(baseArgs); + + // (1) Dump with the same args. Should produce the same archive. + String baseArchive2 = dump(baseArgs); + compare(baseArchive, baseArchive2); + + + // (2) This will cause GC to happen after we've allocated 1MB of metaspace objects + // while processing the built-in SharedClassListFile. + String withGCArchive = dump(baseArgs, "-XX:MetaspaceSize=1M"); + compare(baseArchive, withGCArchive); + + // (3) This will cause archive to be relocated during dump time. We should + // still get the same bits. (This simulates relocation that happens when + // Address Space Layout Randomization prevents the archive space to + // be mapped at the default location) + String relocatedArchive = dump(baseArgs, "-XX:+UnlockDiagnosticVMOptions", "-XX:ArchiveRelocationMode=1"); + compare(baseArchive, relocatedArchive); + } + + static int id = 0; + static String dump(ArrayList args, String... more) throws Exception { + String logName = "SharedArchiveFile" + (id++); + String archiveName = logName + ".jsa"; + args = (ArrayList)args.clone(); + args.add("-XX:SharedArchiveFile=" + archiveName); + args.add("-Xshare:dump"); + args.add("-Xlog:cds=debug"); + for (String m : more) { + args.add(m); + } + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args); + OutputAnalyzer out = CDSTestUtils.executeAndLog(pb, logName); + CDSTestUtils.checkDump(out); + + return archiveName; + } + static void compare(String file0, String file1) throws Exception { byte[] buff0 = new byte[4096]; byte[] buff1 = new byte[4096]; From 76b76654d2fcc2ee04766a9cd3cdddedbcd84fe9 Mon Sep 17 00:00:00 2001 From: Martin Doerr Date: Mon, 18 May 2020 10:57:16 +0200 Subject: [PATCH 091/143] 8235673: [C1, C2] Split inlining control flags Reviewed-by: neliasso, kvn, thartmann --- .../cpu/aarch64/c1_globals_aarch64.hpp | 1 - src/hotspot/cpu/arm/c1_globals_arm.hpp | 1 - src/hotspot/cpu/ppc/c1_globals_ppc.hpp | 1 - src/hotspot/cpu/s390/c1_globals_s390.hpp | 1 - src/hotspot/cpu/sparc/c1_globals_sparc.hpp | 1 - src/hotspot/cpu/x86/c1_globals_x86.hpp | 1 - src/hotspot/share/c1/c1_GraphBuilder.cpp | 20 ++++++++----- src/hotspot/share/c1/c1_globals.hpp | 22 ++++++++++++++ .../share/compiler/compilerDefinitions.cpp | 7 +++++ .../share/compiler/compiler_globals.hpp | 1 - src/hotspot/share/opto/c2_globals.hpp | 29 +++++++++++++++++++ src/hotspot/share/runtime/arguments.cpp | 10 +++++++ src/hotspot/share/runtime/globals.hpp | 25 ---------------- .../jtreg/compiler/c2/Test5091921.java | 2 +- .../jtreg/compiler/c2/Test6792161.java | 2 +- .../jtreg/compiler/c2/Test6910605_2.java | 4 +-- .../share/scenario/Command.java | 4 +-- .../string/TestStringIntrinsics2.java | 1 + .../profiling/TestProfileCounterOverflow.java | 2 +- .../ReservedStack/ReservedStackTest.java | 2 +- 20 files changed, 90 insertions(+), 47 deletions(-) diff --git a/src/hotspot/cpu/aarch64/c1_globals_aarch64.hpp b/src/hotspot/cpu/aarch64/c1_globals_aarch64.hpp index b1e04095535..266216e9e84 100644 --- a/src/hotspot/cpu/aarch64/c1_globals_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/c1_globals_aarch64.hpp @@ -44,7 +44,6 @@ define_pd_global(bool, TieredCompilation, false); define_pd_global(intx, CompileThreshold, 1500 ); define_pd_global(intx, OnStackReplacePercentage, 933 ); -define_pd_global(intx, FreqInlineSize, 325 ); define_pd_global(intx, NewSizeThreadIncrease, 4*K ); define_pd_global(intx, InitialCodeCacheSize, 160*K); define_pd_global(intx, ReservedCodeCacheSize, 32*M ); diff --git a/src/hotspot/cpu/arm/c1_globals_arm.hpp b/src/hotspot/cpu/arm/c1_globals_arm.hpp index 4fd8720c816..6318c1068e3 100644 --- a/src/hotspot/cpu/arm/c1_globals_arm.hpp +++ b/src/hotspot/cpu/arm/c1_globals_arm.hpp @@ -45,7 +45,6 @@ define_pd_global(bool, TieredCompilation, false); define_pd_global(intx, CompileThreshold, 1500 ); define_pd_global(intx, OnStackReplacePercentage, 933 ); -define_pd_global(intx, FreqInlineSize, 325 ); define_pd_global(size_t, NewSizeThreadIncrease, 4*K ); define_pd_global(size_t, InitialCodeCacheSize, 160*K); define_pd_global(size_t, ReservedCodeCacheSize, 32*M ); diff --git a/src/hotspot/cpu/ppc/c1_globals_ppc.hpp b/src/hotspot/cpu/ppc/c1_globals_ppc.hpp index 2758727409e..8bcd96ae86b 100644 --- a/src/hotspot/cpu/ppc/c1_globals_ppc.hpp +++ b/src/hotspot/cpu/ppc/c1_globals_ppc.hpp @@ -45,7 +45,6 @@ define_pd_global(intx, CompileThreshold, 1000); define_pd_global(intx, OnStackReplacePercentage, 1400); define_pd_global(bool, UseTLAB, true); define_pd_global(bool, ProfileInterpreter, false); -define_pd_global(intx, FreqInlineSize, 325 ); define_pd_global(bool, ResizeTLAB, true); define_pd_global(uintx, ReservedCodeCacheSize, 32*M); define_pd_global(uintx, NonProfiledCodeHeapSize, 13*M ); diff --git a/src/hotspot/cpu/s390/c1_globals_s390.hpp b/src/hotspot/cpu/s390/c1_globals_s390.hpp index 91788953215..bc03a2050ab 100644 --- a/src/hotspot/cpu/s390/c1_globals_s390.hpp +++ b/src/hotspot/cpu/s390/c1_globals_s390.hpp @@ -46,7 +46,6 @@ define_pd_global(intx, CompileThreshold, 1000); define_pd_global(intx, OnStackReplacePercentage, 1400); define_pd_global(bool, UseTLAB, true); define_pd_global(bool, ProfileInterpreter, false); -define_pd_global(intx, FreqInlineSize, 325); define_pd_global(bool, ResizeTLAB, true); define_pd_global(uintx, ReservedCodeCacheSize, 32*M); define_pd_global(uintx, NonProfiledCodeHeapSize, 13*M); diff --git a/src/hotspot/cpu/sparc/c1_globals_sparc.hpp b/src/hotspot/cpu/sparc/c1_globals_sparc.hpp index 31841bd0f2b..b2b2032a197 100644 --- a/src/hotspot/cpu/sparc/c1_globals_sparc.hpp +++ b/src/hotspot/cpu/sparc/c1_globals_sparc.hpp @@ -44,7 +44,6 @@ define_pd_global(intx, CompileThreshold, 1000 ); // Design center r define_pd_global(intx, OnStackReplacePercentage, 1400 ); define_pd_global(bool, UseTLAB, true ); define_pd_global(bool, ProfileInterpreter, false); -define_pd_global(intx, FreqInlineSize, 325 ); define_pd_global(bool, ResizeTLAB, true ); define_pd_global(uintx, ReservedCodeCacheSize, 32*M ); define_pd_global(uintx, NonProfiledCodeHeapSize, 13*M ); diff --git a/src/hotspot/cpu/x86/c1_globals_x86.hpp b/src/hotspot/cpu/x86/c1_globals_x86.hpp index de754f9f842..515f01444bb 100644 --- a/src/hotspot/cpu/x86/c1_globals_x86.hpp +++ b/src/hotspot/cpu/x86/c1_globals_x86.hpp @@ -43,7 +43,6 @@ define_pd_global(bool, TieredCompilation, false); define_pd_global(intx, CompileThreshold, 1500 ); define_pd_global(intx, OnStackReplacePercentage, 933 ); -define_pd_global(intx, FreqInlineSize, 325 ); define_pd_global(size_t, NewSizeThreadIncrease, 4*K ); define_pd_global(uintx, InitialCodeCacheSize, 160*K); define_pd_global(uintx, ReservedCodeCacheSize, 32*M ); diff --git a/src/hotspot/share/c1/c1_GraphBuilder.cpp b/src/hotspot/share/c1/c1_GraphBuilder.cpp index b9bcf7dc4fe..d8104bc3d98 100644 --- a/src/hotspot/share/c1/c1_GraphBuilder.cpp +++ b/src/hotspot/share/c1/c1_GraphBuilder.cpp @@ -701,10 +701,10 @@ GraphBuilder::ScopeData::ScopeData(ScopeData* parent) if (parent != NULL) { _max_inline_size = (intx) ((float) NestedInliningSizeRatio * (float) parent->max_inline_size() / 100.0f); } else { - _max_inline_size = MaxInlineSize; + _max_inline_size = C1MaxInlineSize; } - if (_max_inline_size < MaxTrivialSize) { - _max_inline_size = MaxTrivialSize; + if (_max_inline_size < C1MaxTrivialSize) { + _max_inline_size = C1MaxTrivialSize; } } @@ -3817,8 +3817,8 @@ bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known, bool ign // now perform tests that are based on flag settings bool inlinee_by_directive = compilation()->directive()->should_inline(callee); if (callee->force_inline() || inlinee_by_directive) { - if (inline_level() > MaxForceInlineLevel ) INLINE_BAILOUT("MaxForceInlineLevel"); - if (recursive_inline_level(callee) > MaxRecursiveInlineLevel) INLINE_BAILOUT("recursive inlining too deep"); + if (inline_level() > MaxForceInlineLevel ) INLINE_BAILOUT("MaxForceInlineLevel"); + if (recursive_inline_level(callee) > C1MaxRecursiveInlineLevel) INLINE_BAILOUT("recursive inlining too deep"); const char* msg = ""; if (callee->force_inline()) msg = "force inline by annotation"; @@ -3826,9 +3826,15 @@ bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known, bool ign print_inlining(callee, msg); } else { // use heuristic controls on inlining - if (inline_level() > MaxInlineLevel ) INLINE_BAILOUT("inlining too deep"); - if (recursive_inline_level(callee) > MaxRecursiveInlineLevel) INLINE_BAILOUT("recursive inlining too deep"); + if (inline_level() > C1MaxInlineLevel ) INLINE_BAILOUT("inlining too deep"); + int callee_recursive_level = recursive_inline_level(callee); + if (callee_recursive_level > C1MaxRecursiveInlineLevel ) INLINE_BAILOUT("recursive inlining too deep"); if (callee->code_size_for_inlining() > max_inline_size() ) INLINE_BAILOUT("callee is too large"); + // Additional condition to limit stack usage for non-recursive calls. + if ((callee_recursive_level == 0) && + (callee->max_stack() + callee->max_locals() - callee->size_of_parameters() > C1InlineStackLimit)) { + INLINE_BAILOUT("callee uses too much stack"); + } // don't inline throwable methods unless the inlining tree is rooted in a throwable class if (callee->name() == ciSymbol::object_initializer_name() && diff --git a/src/hotspot/share/c1/c1_globals.hpp b/src/hotspot/share/c1/c1_globals.hpp index 7d7d440ef5c..ee97a3c29ec 100644 --- a/src/hotspot/share/c1/c1_globals.hpp +++ b/src/hotspot/share/c1/c1_globals.hpp @@ -170,6 +170,28 @@ develop(bool, UseTableRanges, true, \ "Faster versions of lookup table using ranges") \ \ + product(intx, C1MaxInlineSize, 35, \ + "The maximum bytecode size of a method to be inlined by C1") \ + range(0, max_jint) \ + \ + product(intx, C1MaxTrivialSize, 6, \ + "The maximum bytecode size of a trivial method to be inlined by " \ + "C1") \ + range(0, max_jint) \ + \ + product(intx, C1MaxInlineLevel, 9, \ + "The maximum number of nested calls that are inlined by C1") \ + range(0, max_jint) \ + \ + product(intx, C1MaxRecursiveInlineLevel, 1, \ + "maximum number of nested recursive calls that are inlined by C1")\ + range(0, max_jint) \ + \ + product(intx, C1InlineStackLimit, 10, \ + "inlining only allowed for methods which don't exceed this " \ + "number of expression stack and local slots") \ + range(0, max_jint) \ + \ develop(intx, NestedInliningSizeRatio, 90, \ "Percentage of prev. allowed inline size in recursive inlining") \ range(0, 100) \ diff --git a/src/hotspot/share/compiler/compilerDefinitions.cpp b/src/hotspot/share/compiler/compilerDefinitions.cpp index 71b4789fc51..33442dd9b12 100644 --- a/src/hotspot/share/compiler/compilerDefinitions.cpp +++ b/src/hotspot/share/compiler/compilerDefinitions.cpp @@ -278,6 +278,13 @@ void CompilerConfig::set_tiered_flags() { } #endif // INCLUDE_AOT } + + // Reduce stack usage due to inlining of methods which require much stack. + // (High tier compiler can inline better based on profiling information.) + if (FLAG_IS_DEFAULT(C1InlineStackLimit) && + TieredStopAtLevel == CompLevel_full_optimization && !CompilationModeFlag::quick_only()) { + FLAG_SET_DEFAULT(C1InlineStackLimit, 5); + } } #endif // TIERED diff --git a/src/hotspot/share/compiler/compiler_globals.hpp b/src/hotspot/share/compiler/compiler_globals.hpp index 78400294f97..51ac7179bb0 100644 --- a/src/hotspot/share/compiler/compiler_globals.hpp +++ b/src/hotspot/share/compiler/compiler_globals.hpp @@ -52,7 +52,6 @@ define_pd_global(intx, CompileThreshold, 0); define_pd_global(intx, OnStackReplacePercentage, 0); define_pd_global(bool, ResizeTLAB, false); -define_pd_global(intx, FreqInlineSize, 0); define_pd_global(size_t, NewSizeThreadIncrease, 4*K); define_pd_global(bool, InlineClassNatives, true); define_pd_global(bool, InlineUnsafeOps, true); diff --git a/src/hotspot/share/opto/c2_globals.hpp b/src/hotspot/share/opto/c2_globals.hpp index 26173716ad4..2b7ca8d94be 100644 --- a/src/hotspot/share/opto/c2_globals.hpp +++ b/src/hotspot/share/opto/c2_globals.hpp @@ -685,6 +685,35 @@ develop(bool, VerifyAliases, false, \ "perform extra checks on the results of alias analysis") \ \ + product(intx, MaxInlineLevel, 15, \ + "maximum number of nested calls that are inlined by high tier " \ + "compiler") \ + range(0, max_jint) \ + \ + product(intx, MaxRecursiveInlineLevel, 1, \ + "maximum number of nested recursive calls that are inlined by " \ + "high tier compiler") \ + range(0, max_jint) \ + \ + product_pd(intx, InlineSmallCode, \ + "Only inline already compiled methods if their code size is " \ + "less than this") \ + range(0, max_jint) \ + \ + product(intx, MaxInlineSize, 35, \ + "The maximum bytecode size of a method to be inlined by high " \ + "tier compiler") \ + range(0, max_jint) \ + \ + product_pd(intx, FreqInlineSize, \ + "The maximum bytecode size of a frequent method to be inlined") \ + range(0, max_jint) \ + \ + product(intx, MaxTrivialSize, 6, \ + "The maximum bytecode size of a trivial method to be inlined by " \ + "high tier compiler") \ + range(0, max_jint) \ + \ product(bool, IncrementalInline, true, \ "do post parse inlining") \ \ diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index 9f94ca2eb51..dbe9e1048d0 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -570,6 +570,16 @@ static SpecialFlag const special_jvm_flags[] = { { "dup option", JDK_Version::jdk(9), JDK_Version::undefined(), JDK_Version::undefined() }, #endif +#ifndef COMPILER2 + // These flags were generally available, but are C2 only, now. + { "MaxInlineLevel", JDK_Version::undefined(), JDK_Version::jdk(15), JDK_Version::jdk(16) }, + { "MaxRecursiveInlineLevel", JDK_Version::undefined(), JDK_Version::jdk(15), JDK_Version::jdk(16) }, + { "InlineSmallCode", JDK_Version::undefined(), JDK_Version::jdk(15), JDK_Version::jdk(16) }, + { "MaxInlineSize", JDK_Version::undefined(), JDK_Version::jdk(15), JDK_Version::jdk(16) }, + { "FreqInlineSize", JDK_Version::undefined(), JDK_Version::jdk(15), JDK_Version::jdk(16) }, + { "MaxTrivialSize", JDK_Version::undefined(), JDK_Version::jdk(15), JDK_Version::jdk(16) }, +#endif + { NULL, JDK_Version(0), JDK_Version(0) } }; diff --git a/src/hotspot/share/runtime/globals.hpp b/src/hotspot/share/runtime/globals.hpp index c18368bd9c4..f18d7f3f9d2 100644 --- a/src/hotspot/share/runtime/globals.hpp +++ b/src/hotspot/share/runtime/globals.hpp @@ -1455,36 +1455,11 @@ const size_t minimumSymbolTableSize = 1024; notproduct(intx, MaxSubklassPrintSize, 4, \ "maximum number of subklasses to print when printing klass") \ \ - product(intx, MaxInlineLevel, 15, \ - "maximum number of nested calls that are inlined") \ - range(0, max_jint) \ - \ - product(intx, MaxRecursiveInlineLevel, 1, \ - "maximum number of nested recursive calls that are inlined") \ - range(0, max_jint) \ - \ develop(intx, MaxForceInlineLevel, 100, \ "maximum number of nested calls that are forced for inlining " \ "(using CompileCommand or marked w/ @ForceInline)") \ range(0, max_jint) \ \ - product_pd(intx, InlineSmallCode, \ - "Only inline already compiled methods if their code size is " \ - "less than this") \ - range(0, max_jint) \ - \ - product(intx, MaxInlineSize, 35, \ - "The maximum bytecode size of a method to be inlined") \ - range(0, max_jint) \ - \ - product_pd(intx, FreqInlineSize, \ - "The maximum bytecode size of a frequent method to be inlined") \ - range(0, max_jint) \ - \ - product(intx, MaxTrivialSize, 6, \ - "The maximum bytecode size of a trivial method to be inlined") \ - range(0, max_jint) \ - \ product(intx, MinInliningThreshold, 250, \ "The minimum invocation count a method needs to have to be " \ "inlined") \ diff --git a/test/hotspot/jtreg/compiler/c2/Test5091921.java b/test/hotspot/jtreg/compiler/c2/Test5091921.java index 07fa59d11bd..a475bee8565 100644 --- a/test/hotspot/jtreg/compiler/c2/Test5091921.java +++ b/test/hotspot/jtreg/compiler/c2/Test5091921.java @@ -27,7 +27,7 @@ * @bug 5091921 * @summary Sign flip issues in loop optimizer * - * @run main/othervm -Xcomp -XX:MaxInlineSize=1 + * @run main/othervm -Xcomp -XX:+IgnoreUnrecognizedVMOptions -XX:MaxInlineSize=1 -XX:C1MaxInlineSize=1 * -XX:CompileCommand=compileonly,compiler.c2.Test5091921::* * compiler.c2.Test5091921 */ diff --git a/test/hotspot/jtreg/compiler/c2/Test6792161.java b/test/hotspot/jtreg/compiler/c2/Test6792161.java index 9685fbb50e8..cb1a1f49c73 100644 --- a/test/hotspot/jtreg/compiler/c2/Test6792161.java +++ b/test/hotspot/jtreg/compiler/c2/Test6792161.java @@ -26,7 +26,7 @@ * @bug 6792161 * @summary assert("No dead instructions after post-alloc") * - * @run main/othervm/timeout=600 -Xcomp -XX:-TieredCompilation -XX:MaxInlineSize=120 compiler.c2.Test6792161 + * @run main/othervm/timeout=600 -Xcomp -XX:-TieredCompilation -XX:+IgnoreUnrecognizedVMOptions -XX:MaxInlineSize=120 compiler.c2.Test6792161 */ package compiler.c2; diff --git a/test/hotspot/jtreg/compiler/c2/Test6910605_2.java b/test/hotspot/jtreg/compiler/c2/Test6910605_2.java index 6131d6cef0f..678d2eec0d8 100644 --- a/test/hotspot/jtreg/compiler/c2/Test6910605_2.java +++ b/test/hotspot/jtreg/compiler/c2/Test6910605_2.java @@ -27,14 +27,14 @@ * @summary C2: NullPointerException/ClassCaseException is thrown when C2 with DeoptimizeALot is used * * @run main/othervm -Xmx128m -XX:+IgnoreUnrecognizedVMOptions -XX:+DeoptimizeALot - * -XX:+DoEscapeAnalysis -Xbatch -XX:InlineSmallCode=2000 + * -XX:+DoEscapeAnalysis -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:InlineSmallCode=2000 * compiler.c2.Test6910605_2 */ package compiler.c2; /* - * Added InlineSmallCode=2000 to guaranty inlining of StringBuilder::append() to allow scalar replace StringBuilder object. + * Added InlineSmallCode=2000 to guarantee inlining of StringBuilder::append() to allow scalar replace StringBuilder object. * * original test: gc/gctests/StringGC */ diff --git a/test/hotspot/jtreg/compiler/compilercontrol/share/scenario/Command.java b/test/hotspot/jtreg/compiler/compilercontrol/share/scenario/Command.java index b30afd6265e..e60fe0e7fe7 100644 --- a/test/hotspot/jtreg/compiler/compilercontrol/share/scenario/Command.java +++ b/test/hotspot/jtreg/compiler/compilercontrol/share/scenario/Command.java @@ -33,8 +33,8 @@ import java.util.Arrays; public enum Command { COMPILEONLY("compileonly", ".*", "-Xbatch"), EXCLUDE("exclude", "", "-Xbatch"), - INLINE("inline", ".*", "-Xbatch", "-XX:InlineSmallCode=4000"), - DONTINLINE("dontinline", "", "-Xbatch", "-XX:InlineSmallCode=4000"), + INLINE("inline", ".*", "-Xbatch", "-XX:+IgnoreUnrecognizedVMOptions", "-XX:InlineSmallCode=4000"), + DONTINLINE("dontinline", "", "-Xbatch", "-XX:+IgnoreUnrecognizedVMOptions", "-XX:InlineSmallCode=4000"), LOG("log", "", "-XX:+UnlockDiagnosticVMOptions", "-XX:+LogCompilation", "-XX:LogFile=" + LogProcessor.LOG_FILE), PRINT("print", ""), diff --git a/test/hotspot/jtreg/compiler/intrinsics/string/TestStringIntrinsics2.java b/test/hotspot/jtreg/compiler/intrinsics/string/TestStringIntrinsics2.java index 81d4d9feba3..19a90cef305 100644 --- a/test/hotspot/jtreg/compiler/intrinsics/string/TestStringIntrinsics2.java +++ b/test/hotspot/jtreg/compiler/intrinsics/string/TestStringIntrinsics2.java @@ -37,6 +37,7 @@ * -Xmixed * -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI + * -XX:+IgnoreUnrecognizedVMOptions * -XX:MaxInlineSize=70 * -XX:MinInliningThreshold=0 * compiler.intrinsics.string.TestStringIntrinsics2 diff --git a/test/hotspot/jtreg/compiler/profiling/TestProfileCounterOverflow.java b/test/hotspot/jtreg/compiler/profiling/TestProfileCounterOverflow.java index d44a6702e59..a904192997e 100644 --- a/test/hotspot/jtreg/compiler/profiling/TestProfileCounterOverflow.java +++ b/test/hotspot/jtreg/compiler/profiling/TestProfileCounterOverflow.java @@ -25,7 +25,7 @@ * @test * @bug 8224162 * @summary Profile counter for a call site may overflow. - * @run main/othervm -Xbatch -XX:-UseOnStackReplacement -XX:MaxTrivialSize=0 compiler.profiling.TestProfileCounterOverflow + * @run main/othervm -Xbatch -XX:-UseOnStackReplacement -XX:+IgnoreUnrecognizedVMOptions -XX:MaxTrivialSize=0 -XX:C1MaxTrivialSize=0 compiler.profiling.TestProfileCounterOverflow */ package compiler.profiling; diff --git a/test/hotspot/jtreg/runtime/ReservedStack/ReservedStackTest.java b/test/hotspot/jtreg/runtime/ReservedStack/ReservedStackTest.java index d5a9e6f0601..7dff17dce68 100644 --- a/test/hotspot/jtreg/runtime/ReservedStack/ReservedStackTest.java +++ b/test/hotspot/jtreg/runtime/ReservedStack/ReservedStackTest.java @@ -29,7 +29,7 @@ * @modules java.base/jdk.internal.misc * @modules java.base/jdk.internal.vm.annotation * - * @run main/othervm -XX:MaxInlineLevel=2 -XX:CompileCommand=exclude,java/util/concurrent/locks/AbstractOwnableSynchronizer.setExclusiveOwnerThread ReservedStackTest + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:MaxInlineLevel=2 -XX:C1MaxInlineLevel=2 -XX:CompileCommand=exclude,java/util/concurrent/locks/AbstractOwnableSynchronizer.setExclusiveOwnerThread ReservedStackTest */ /* The exclusion of java.util.concurrent.locks.AbstractOwnableSynchronizer.setExclusiveOwnerThread() From dde3b900503e0ec37eadaea71f01fb8a3a0a233d Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Mon, 18 May 2020 10:33:12 +0800 Subject: [PATCH 092/143] 8244981: jpackage error due to missing final newline in Debian control file Reviewed-by: herrick, asemenyuk --- .../jdk/incubator/jpackage/internal/OverridableResource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/OverridableResource.java b/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/OverridableResource.java index edfb6a9608c..c29a8b63840 100644 --- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/OverridableResource.java +++ b/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/OverridableResource.java @@ -305,7 +305,7 @@ final class OverridableResource { try (BufferedReader reader = new BufferedReader( new InputStreamReader(rawResource, StandardCharsets.UTF_8))) { String data = substitute(reader.lines(), substitutionData).collect( - Collectors.joining("\n")); + Collectors.joining("\n", "", "\n")); try (InputStream in = new ByteArrayInputStream(data.getBytes( StandardCharsets.UTF_8))) { dest.consume(in); From 31479a0d480d3e22a1d4a2b367658261dc003d93 Mon Sep 17 00:00:00 2001 From: Ivan Walulya Date: Thu, 14 May 2020 15:27:17 +0200 Subject: [PATCH 093/143] 8244752: Enable Linux support for multiple huge page sizes -XX:LargePageSizeInBytes Reviewed-by: kbarrett, sjohanss, stuefe, tschatzl --- src/hotspot/os/linux/os_linux.cpp | 95 ++++++++++++++++++++++++------- src/hotspot/os/linux/os_linux.hpp | 6 +- 2 files changed, 81 insertions(+), 20 deletions(-) diff --git a/src/hotspot/os/linux/os_linux.cpp b/src/hotspot/os/linux/os_linux.cpp index 277ea9a83b6..3e42d30ec0d 100644 --- a/src/hotspot/os/linux/os_linux.cpp +++ b/src/hotspot/os/linux/os_linux.cpp @@ -154,6 +154,7 @@ int os::Linux::_page_size = -1; bool os::Linux::_supports_fast_thread_cpu_time = false; const char * os::Linux::_glibc_version = NULL; const char * os::Linux::_libpthread_version = NULL; +size_t os::Linux::_default_large_page_size = 0; static jlong initial_time_count=0; @@ -2976,6 +2977,15 @@ void os::pd_commit_memory_or_exit(char* addr, size_t size, bool exec, #define MAP_HUGETLB 0x40000 #endif +// If mmap flags are set with MAP_HUGETLB and the system supports multiple +// huge page sizes, flag bits [26:31] can be used to encode the log2 of the +// desired huge page size. Otherwise, the system's default huge page size will be used. +// See mmap(2) man page for more info (since Linux 3.8). +// https://lwn.net/Articles/533499/ +#ifndef MAP_HUGE_SHIFT + #define MAP_HUGE_SHIFT 26 +#endif + // Define MADV_HUGEPAGE here so we can build HotSpot on old systems. #ifndef MADV_HUGEPAGE #define MADV_HUGEPAGE 14 @@ -3758,7 +3768,10 @@ static void set_coredump_filter(CoredumpFilterBit bit) { static size_t _large_page_size = 0; -size_t os::Linux::find_large_page_size() { +size_t os::Linux::find_default_large_page_size() { + if (_default_large_page_size != 0) { + return _default_large_page_size; + } size_t large_page_size = 0; // large_page_size on Linux is used to round up heap size. x86 uses either @@ -3806,18 +3819,53 @@ size_t os::Linux::find_large_page_size() { } fclose(fp); } - - if (!FLAG_IS_DEFAULT(LargePageSizeInBytes) && LargePageSizeInBytes != large_page_size) { - warning("Setting LargePageSizeInBytes has no effect on this OS. Large page size is " - SIZE_FORMAT "%s.", byte_size_in_proper_unit(large_page_size), - proper_unit_for_byte_size(large_page_size)); - } - return large_page_size; } +size_t os::Linux::find_large_page_size(size_t large_page_size) { + if (_default_large_page_size == 0) { + _default_large_page_size = Linux::find_default_large_page_size(); + } + // We need to scan /sys/kernel/mm/hugepages + // to discover the available page sizes + const char* sys_hugepages = "/sys/kernel/mm/hugepages"; + + DIR *dir = opendir(sys_hugepages); + if (dir == NULL) { + return _default_large_page_size; + } + + struct dirent *entry; + size_t page_size; + while ((entry = readdir(dir)) != NULL) { + if (entry->d_type == DT_DIR && + sscanf(entry->d_name, "hugepages-%zukB", &page_size) == 1) { + // The kernel is using kB, hotspot uses bytes + if (large_page_size == page_size * K) { + closedir(dir); + return large_page_size; + } + } + } + closedir(dir); + return _default_large_page_size; +} + size_t os::Linux::setup_large_page_size() { - _large_page_size = Linux::find_large_page_size(); + _default_large_page_size = Linux::find_default_large_page_size(); + + if (!FLAG_IS_DEFAULT(LargePageSizeInBytes) && LargePageSizeInBytes != _default_large_page_size ) { + _large_page_size = find_large_page_size(LargePageSizeInBytes); + if (_large_page_size == _default_large_page_size) { + warning("Setting LargePageSizeInBytes=" SIZE_FORMAT " has no effect on this OS. Using the default large page size " + SIZE_FORMAT "%s.", + LargePageSizeInBytes, + byte_size_in_proper_unit(_large_page_size), proper_unit_for_byte_size(_large_page_size)); + } + } else { + _large_page_size = _default_large_page_size; + } + const size_t default_page_size = (size_t)Linux::page_size(); if (_large_page_size > default_page_size) { _page_sizes[0] = _large_page_size; @@ -3828,6 +3876,10 @@ size_t os::Linux::setup_large_page_size() { return _large_page_size; } +size_t os::Linux::default_large_page_size() { + return _default_large_page_size; +} + bool os::Linux::setup_large_page_type(size_t page_size) { if (FLAG_IS_DEFAULT(UseHugeTLBFS) && FLAG_IS_DEFAULT(UseSHM) && @@ -4056,9 +4108,12 @@ char* os::Linux::reserve_memory_special_huge_tlbfs_only(size_t bytes, assert(is_aligned(req_addr, os::large_page_size()), "Unaligned address"); int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE; - char* addr = (char*)::mmap(req_addr, bytes, prot, - MAP_PRIVATE|MAP_ANONYMOUS|MAP_HUGETLB, - -1, 0); + int flags = MAP_PRIVATE|MAP_ANONYMOUS|MAP_HUGETLB; + + if (os::large_page_size() != default_large_page_size()) { + flags |= (exact_log2(os::large_page_size()) << MAP_HUGE_SHIFT); + } + char* addr = (char*)::mmap(req_addr, bytes, prot, flags, -1, 0); if (addr == MAP_FAILED) { warn_on_large_pages_failure(req_addr, bytes, errno); @@ -4114,14 +4169,12 @@ char* os::Linux::reserve_memory_special_huge_tlbfs_mixed(size_t bytes, } int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE; - + int flags = MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED; void* result; // Commit small-paged leading area. if (start != lp_start) { - result = ::mmap(start, lp_start - start, prot, - MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, - -1, 0); + result = ::mmap(start, lp_start - start, prot, flags, -1, 0); if (result == MAP_FAILED) { ::munmap(lp_start, end - lp_start); return NULL; @@ -4129,9 +4182,13 @@ char* os::Linux::reserve_memory_special_huge_tlbfs_mixed(size_t bytes, } // Commit large-paged area. - result = ::mmap(lp_start, lp_bytes, prot, - MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED|MAP_HUGETLB, - -1, 0); + flags |= MAP_HUGETLB; + + if (os::large_page_size() != default_large_page_size()) { + flags |= (exact_log2(os::large_page_size()) << MAP_HUGE_SHIFT); + } + + result = ::mmap(lp_start, lp_bytes, prot, flags, -1, 0); if (result == MAP_FAILED) { warn_on_large_pages_failure(lp_start, lp_bytes, errno); // If the mmap above fails, the large pages region will be unmapped and we diff --git a/src/hotspot/os/linux/os_linux.hpp b/src/hotspot/os/linux/os_linux.hpp index 9b98ba98581..3b62bee7d4d 100644 --- a/src/hotspot/os/linux/os_linux.hpp +++ b/src/hotspot/os/linux/os_linux.hpp @@ -56,6 +56,8 @@ class Linux { static GrowableArray* _cpu_to_node; static GrowableArray* _nindex_to_node; + static size_t _default_large_page_size; + protected: static julong _physical_memory; @@ -81,7 +83,9 @@ class Linux { static GrowableArray* cpu_to_node() { return _cpu_to_node; } static GrowableArray* nindex_to_node() { return _nindex_to_node; } - static size_t find_large_page_size(); + static size_t default_large_page_size(); + static size_t find_default_large_page_size(); + static size_t find_large_page_size(size_t page_size); static size_t setup_large_page_size(); static bool setup_large_page_type(size_t page_size); From ed9cbe252d969236a80393173c7b257b4e022d76 Mon Sep 17 00:00:00 2001 From: Jan Lahoda Date: Wed, 29 Apr 2020 18:35:14 +0200 Subject: [PATCH 094/143] 8241616: Timestamps on ct.sym entries lead to non-reproducible builds Generate ct.sym in a reproducible way Reviewed-by: ihse --- .../tools/symbolgenerator/CreateSymbols.java | 135 +++++++++++++----- .../TransitiveDependencies.java | 6 +- make/modules/jdk.compiler/Gendata.gmk | 32 ++--- .../platform/CanHandleClassFilesTest.java | 8 +- 4 files changed, 121 insertions(+), 60 deletions(-) diff --git a/make/langtools/src/classes/build/tools/symbolgenerator/CreateSymbols.java b/make/langtools/src/classes/build/tools/symbolgenerator/CreateSymbols.java index 9f3c5a3354c..71ef8bde6c1 100644 --- a/make/langtools/src/classes/build/tools/symbolgenerator/CreateSymbols.java +++ b/make/langtools/src/classes/build/tools/symbolgenerator/CreateSymbols.java @@ -33,9 +33,11 @@ import build.tools.symbolgenerator.CreateSymbols .RequiresDescription; import java.io.BufferedInputStream; import java.io.BufferedReader; +import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -53,6 +55,7 @@ import java.util.Arrays; import java.util.Calendar; import java.util.Collection; import java.util.Collections; +import java.util.Comparator; import java.util.EnumSet; import java.util.HashMap; import java.util.HashSet; @@ -65,11 +68,15 @@ import java.util.Map.Entry; import java.util.Objects; import java.util.Set; import java.util.TimeZone; +import java.util.TreeMap; +import java.util.TreeSet; import java.util.function.Function; import java.util.function.Predicate; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; import javax.tools.JavaFileManager; import javax.tools.JavaFileManager.Location; @@ -209,7 +216,8 @@ public class CreateSymbols { * {@code ctDescriptionFile}, using the file as a recipe to create the sigfiles. */ @SuppressWarnings("unchecked") - public void createSymbols(String ctDescriptionFileExtra, String ctDescriptionFile, String ctSymLocation) throws IOException { + public void createSymbols(String ctDescriptionFileExtra, String ctDescriptionFile, String ctSymLocation, + long timestamp, String currentVersion, String systemModules) throws IOException { LoadDescriptions data = load(ctDescriptionFileExtra != null ? Paths.get(ctDescriptionFileExtra) : null, Paths.get(ctDescriptionFile), null); @@ -217,12 +225,13 @@ public class CreateSymbols { splitHeaders(data.classes); Map> package2Version2Module = new HashMap<>(); + Map> directory2FileData = new TreeMap<>(); for (ModuleDescription md : data.modules.values()) { for (ModuleHeaderDescription mhd : md.header) { List versionsList = Collections.singletonList(mhd.versions); - writeModulesForVersions(ctSymLocation, + writeModulesForVersions(directory2FileData, md, mhd, versionsList); @@ -260,10 +269,36 @@ public class CreateSymbols { Set currentVersions = new HashSet<>(jointVersions); limitJointVersion(currentVersions, e.getValue().toString()); currentVersions = currentVersions.stream().filter(vers -> !disjoint(vers, e.getValue().toString())).collect(Collectors.toSet()); - writeClassesForVersions(ctSymLocation, classDescription, header, e.getKey(), currentVersions); + writeClassesForVersions(directory2FileData, classDescription, header, e.getKey(), currentVersions); } } } + + currentVersion = Integer.toString(Integer.parseInt(currentVersion), Character.MAX_RADIX); + currentVersion = currentVersion.toUpperCase(Locale.ROOT); + + openDirectory(directory2FileData, currentVersion + "/") + .add(new FileData(currentVersion + "/system-modules", + Files.readAllBytes(Paths.get(systemModules)))); + + try (OutputStream fos = new FileOutputStream(ctSymLocation); + OutputStream bos = new BufferedOutputStream(fos); + ZipOutputStream jos = new ZipOutputStream(bos)) { + for (Entry> e : directory2FileData.entrySet()) { + jos.putNextEntry(createZipEntry(e.getKey(), timestamp)); + for (FileData fd : e.getValue()) { + jos.putNextEntry(createZipEntry(fd.fileName, timestamp)); + jos.write(fd.fileData); + } + } + } + } + + private ZipEntry createZipEntry(String name, long timestamp) { + ZipEntry ze = new ZipEntry(name); + + ze.setTime(timestamp); + return ze; } public static String EXTENSION = ".sig"; @@ -431,7 +466,9 @@ public class CreateSymbols { moduleList.put(desc.name, desc); } - return new LoadDescriptions(result, moduleList, new ArrayList<>(platforms.values())); + return new LoadDescriptions(result, + moduleList, + new ArrayList<>(platforms.values())); } static final class LoadDescriptions { @@ -664,29 +701,29 @@ public class CreateSymbols { return true; } - void writeClassesForVersions(String ctSymLocation, + void writeClassesForVersions(Map> directory2FileData, ClassDescription classDescription, ClassHeaderDescription header, String module, Iterable versions) throws IOException { for (String ver : versions) { - writeClass(ctSymLocation, classDescription, header, module, ver); + writeClass(directory2FileData, classDescription, header, module, ver); } } - void writeModulesForVersions(String ctSymLocation, + void writeModulesForVersions(Map> directory2FileData, ModuleDescription moduleDescription, ModuleHeaderDescription header, Iterable versions) throws IOException { for (String ver : versions) { - writeModule(ctSymLocation, moduleDescription, header, ver); + writeModule(directory2FileData, moduleDescription, header, ver); } } // - void writeModule(String ctSymLocation, + void writeModule(Map> directory2FileData, ModuleDescription moduleDescription, ModuleHeaderDescription header, String version) throws IOException { @@ -713,21 +750,10 @@ public class CreateSymbols { new Method[0], attributes); - Path outputClassFile = Paths.get(ctSymLocation, - version, - moduleDescription.name, - "module-info" + EXTENSION); - - Files.createDirectories(outputClassFile.getParent()); - - try (OutputStream out = Files.newOutputStream(outputClassFile)) { - ClassWriter w = new ClassWriter(); - - w.write(classFile, out); - } + doWrite(directory2FileData, version, moduleDescription.name, "module-info" + EXTENSION, classFile); } - void writeClass(String ctSymLocation, + void writeClass(Map> directory2FileData, ClassDescription classDescription, ClassHeaderDescription header, String module, @@ -783,23 +809,45 @@ public class CreateSymbols { methods.toArray(new Method[0]), attributes); - Path outputClassFile = Paths.get(ctSymLocation, version); + doWrite(directory2FileData, version, module, classDescription.name + EXTENSION, classFile); + } - if (module != null) { - outputClassFile = outputClassFile.resolve(module); - } - - outputClassFile = outputClassFile.resolve(classDescription.name + EXTENSION); - - Files.createDirectories(outputClassFile.getParent()); - - try (OutputStream out = Files.newOutputStream(outputClassFile)) { + private void doWrite(Map> directory2FileData, + String version, + String moduleName, + String fileName, + ClassFile classFile) throws IOException { + int lastSlash = fileName.lastIndexOf('/'); + String pack = lastSlash != (-1) ? fileName.substring(0, lastSlash + 1) : "/"; + String directory = version + "/" + moduleName + "/" + pack; + String fullFileName = version + "/" + moduleName + "/" + fileName; + try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { ClassWriter w = new ClassWriter(); w.write(classFile, out); + + openDirectory(directory2FileData, directory) + .add(new FileData(fullFileName, out.toByteArray())); } } + private Set openDirectory(Map> directory2FileData, + String directory) { + Comparator fileCompare = (fd1, fd2) -> fd1.fileName.compareTo(fd2.fileName); + return directory2FileData.computeIfAbsent(directory, d -> new TreeSet<>(fileCompare)); + } + + private static class FileData { + public final String fileName; + public final byte[] fileData; + + public FileData(String fileName, byte[] fileData) { + this.fileName = fileName; + this.fileData = fileData; + } + + } + private void addAttributes(ModuleDescription md, ModuleHeaderDescription header, List cp, @@ -3727,23 +3775,40 @@ public class CreateSymbols { String ctDescriptionFileExtra; String ctDescriptionFile; String ctSymLocation; + String timestampSpec; + String currentVersion; + String systemModules; - if (args.length == 3) { + if (args.length == 6) { ctDescriptionFileExtra = null; ctDescriptionFile = args[1]; ctSymLocation = args[2]; - } else if (args.length == 4) { + timestampSpec = args[3]; + currentVersion = args[4]; + systemModules = args[5]; + } else if (args.length == 7) { ctDescriptionFileExtra = args[1]; ctDescriptionFile = args[2]; ctSymLocation = args[3]; + timestampSpec = args[4]; + currentVersion = args[5]; + systemModules = args[6]; } else { help(); return ; } + long timestamp = Long.parseLong(timestampSpec); + + //SOURCE_DATE_EPOCH is in seconds, convert to milliseconds: + timestamp *= 1000; + new CreateSymbols().createSymbols(ctDescriptionFileExtra, ctDescriptionFile, - ctSymLocation); + ctSymLocation, + timestamp, + currentVersion, + systemModules); break; } } diff --git a/make/langtools/src/classes/build/tools/symbolgenerator/TransitiveDependencies.java b/make/langtools/src/classes/build/tools/symbolgenerator/TransitiveDependencies.java index e197bea7fc9..923eb4b44df 100644 --- a/make/langtools/src/classes/build/tools/symbolgenerator/TransitiveDependencies.java +++ b/make/langtools/src/classes/build/tools/symbolgenerator/TransitiveDependencies.java @@ -108,11 +108,7 @@ public class TransitiveDependencies { allModules.add("java.base"); allModules.add("jdk.unsupported"); - String version = - Integer.toString(Integer.parseInt(Source.DEFAULT.name), Character.MAX_RADIX); - version = version.toUpperCase(Locale.ROOT); - - Path targetFile = Paths.get(args[0]).resolve(version).resolve("system-modules"); + Path targetFile = Paths.get(args[0]); Files.createDirectories(targetFile.getParent()); diff --git a/make/modules/jdk.compiler/Gendata.gmk b/make/modules/jdk.compiler/Gendata.gmk index ed98ab4ee23..0da7147609d 100644 --- a/make/modules/jdk.compiler/Gendata.gmk +++ b/make/modules/jdk.compiler/Gendata.gmk @@ -64,7 +64,7 @@ $(eval $(call SetupJavaCompilation, COMPILE_CREATE_SYMBOLS, \ $(COMPILECREATESYMBOLS_ADD_EXPORTS), \ )) -$(SUPPORT_OUTPUTDIR)/symbols/ct.sym-files/_the.symbols: \ +$(SUPPORT_OUTPUTDIR)/symbols/ct.sym: \ $(COMPILE_CREATE_SYMBOLS) \ $(wildcard $(TOPDIR)/make/data/symbols/*) \ $(MODULE_INFOS) @@ -74,34 +74,28 @@ $(SUPPORT_OUTPUTDIR)/symbols/ct.sym-files/_the.symbols: \ $(JAVA_SMALL) $(INTERIM_LANGTOOLS_ARGS) \ $(COMPILECREATESYMBOLS_ADD_EXPORTS) \ -classpath $(BUILDTOOLS_OUTPUTDIR)/create_symbols \ - build.tools.symbolgenerator.CreateSymbols \ - build-ctsym \ - $(CT_DATA_DESCRIPTION) \ - $(@D) + build.tools.symbolgenerator.TransitiveDependencies \ + $(@D)/system-modules \ + $(CT_MODULESOURCEPATH) \ + $(CT_MODULES) $(JAVA_SMALL) $(INTERIM_LANGTOOLS_ARGS) \ $(COMPILECREATESYMBOLS_ADD_EXPORTS) \ -classpath $(BUILDTOOLS_OUTPUTDIR)/create_symbols \ - build.tools.symbolgenerator.TransitiveDependencies \ - $(@D) \ - $(CT_MODULESOURCEPATH) \ - $(CT_MODULES) + build.tools.symbolgenerator.CreateSymbols \ + build-ctsym \ + $(CT_DATA_DESCRIPTION) \ + $(@D)/ct.sym \ + $(SOURCE_DATE_EPOCH) \ + $(JDK_SOURCE_TARGET_VERSION) \ + $(@D)/system-modules $(TOUCH) $@ -# Can't generate ct.sym directly into modules libs as the SetupJarArchive macro -# creates meta data files in the output dir. -$(eval $(call SetupJarArchive, CREATE_CTSYM, \ - DEPENDENCIES := $(SUPPORT_OUTPUTDIR)/symbols/ct.sym-files/_the.symbols, \ - SRCS := $(SUPPORT_OUTPUTDIR)/symbols/ct.sym-files, \ - SUFFIXES := .sig system-modules, \ - JAR := $(SUPPORT_OUTPUTDIR)/symbols/ct.sym, \ -)) - # Copy ct.sym to the modules libs dir $(eval $(call SetupCopyFiles, COPY_TO_LIBS, \ FILES := $(SUPPORT_OUTPUTDIR)/symbols/ct.sym, \ DEST := $(SUPPORT_OUTPUTDIR)/modules_libs/jdk.compiler, \ )) -TARGETS += $(CREATE_CTSYM) $(COPY_TO_LIBS) +TARGETS += $(COPY_TO_LIBS) ################################################################################ diff --git a/test/langtools/tools/javac/platform/CanHandleClassFilesTest.java b/test/langtools/tools/javac/platform/CanHandleClassFilesTest.java index fbbe22c30a6..8afdf54f40d 100644 --- a/test/langtools/tools/javac/platform/CanHandleClassFilesTest.java +++ b/test/langtools/tools/javac/platform/CanHandleClassFilesTest.java @@ -40,6 +40,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.stream.Stream; +import javax.lang.model.SourceVersion; import javax.tools.StandardLocation; @@ -108,8 +109,10 @@ public class CanHandleClassFilesTest { var createSymbolsClass = Class.forName("build.tools.symbolgenerator.CreateSymbols", false, cl); var main = createSymbolsClass.getMethod("main", String[].class); var symbols = targetDir.resolve("symbols"); + var systemModules = targetDir.resolve("system-modules"); try (Writer w = Files.newBufferedWriter(symbols)) {} + try (Writer w = Files.newBufferedWriter(systemModules)) {} main.invoke(null, (Object) new String[] {"build-description-incremental", @@ -120,7 +123,10 @@ public class CanHandleClassFilesTest { (Object) new String[] {"build-ctsym", "does-not-exist", symbols.toAbsolutePath().toString(), - targetDir.resolve("ct.sym").toAbsolutePath().toString()}); + targetDir.resolve("ct.sym").toAbsolutePath().toString(), + Long.toString(System.currentTimeMillis() / 1000), + "" + SourceVersion.latest().ordinal(), + systemModules.toAbsolutePath().toString()}); } } From 6bd9391f0308afe7cd3d14020082bf1591e15118 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Mon, 18 May 2020 12:32:11 +0200 Subject: [PATCH 095/143] 8244433: Remove saving of RSP in Assembler::pusha_uncached() Remove move instruction to save the actual value of RSP in Assembler::pusha_uncached() on x86. Reviewed-by: eosterlund, thartmann, kvn --- src/hotspot/cpu/x86/assembler_x86.cpp | 15 +++++++++------ src/hotspot/cpu/x86/macroAssembler_x86.cpp | 7 ++++--- src/hotspot/cpu/x86/methodHandles_x86.cpp | 10 ++++++++++ 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/hotspot/cpu/x86/assembler_x86.cpp b/src/hotspot/cpu/x86/assembler_x86.cpp index d60fc9dbaef..e8c5f951878 100644 --- a/src/hotspot/cpu/x86/assembler_x86.cpp +++ b/src/hotspot/cpu/x86/assembler_x86.cpp @@ -8789,7 +8789,8 @@ void Assembler::popa_uncached() { // 64bit movq(rdi, Address(rsp, 8 * wordSize)); movq(rsi, Address(rsp, 9 * wordSize)); movq(rbp, Address(rsp, 10 * wordSize)); - // skip rsp + // Skip rsp as it is restored automatically to the value + // before the corresponding pusha when popa is done. movq(rbx, Address(rsp, 12 * wordSize)); movq(rdx, Address(rsp, 13 * wordSize)); movq(rcx, Address(rsp, 14 * wordSize)); @@ -8798,22 +8799,24 @@ void Assembler::popa_uncached() { // 64bit addq(rsp, 16 * wordSize); } +// Does not actually store the value of rsp on the stack. +// The slot for rsp just contains an arbitrary value. void Assembler::pusha() { // 64bit emit_copy(code_section(), pusha_code, pusha_len); } +// Does not actually store the value of rsp on the stack. +// The slot for rsp just contains an arbitrary value. void Assembler::pusha_uncached() { // 64bit - // we have to store original rsp. ABI says that 128 bytes - // below rsp are local scratch. - movq(Address(rsp, -5 * wordSize), rsp); - subq(rsp, 16 * wordSize); movq(Address(rsp, 15 * wordSize), rax); movq(Address(rsp, 14 * wordSize), rcx); movq(Address(rsp, 13 * wordSize), rdx); movq(Address(rsp, 12 * wordSize), rbx); - // skip rsp + // Skip rsp as the value is normally not used. There are a few places where + // the original value of rsp needs to be known but that can be computed + // from the value of rsp immediately after pusha (rsp + 16 * wordSize). movq(Address(rsp, 10 * wordSize), rbp); movq(Address(rsp, 9 * wordSize), rsi); movq(Address(rsp, 8 * wordSize), rdi); diff --git a/src/hotspot/cpu/x86/macroAssembler_x86.cpp b/src/hotspot/cpu/x86/macroAssembler_x86.cpp index 633b317fc77..b5753410fd4 100644 --- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp @@ -898,7 +898,8 @@ void MacroAssembler::print_state64(int64_t pc, int64_t regs[]) { PRINT_REG(rdi, regs[8]); PRINT_REG(rsi, regs[9]); PRINT_REG(rbp, regs[10]); - PRINT_REG(rsp, regs[11]); + // rsp is actually not stored by pusha(), compute the old rsp from regs (rsp after pusha): regs + 16 = old rsp + PRINT_REG(rsp, (intptr_t)(®s[16])); PRINT_REG(r8 , regs[7]); PRINT_REG(r9 , regs[6]); PRINT_REG(r10, regs[5]); @@ -908,8 +909,8 @@ void MacroAssembler::print_state64(int64_t pc, int64_t regs[]) { PRINT_REG(r14, regs[1]); PRINT_REG(r15, regs[0]); #undef PRINT_REG - // Print some words near top of staack. - int64_t* rsp = (int64_t*) regs[11]; + // Print some words near the top of the stack. + int64_t* rsp = ®s[16]; int64_t* dump_sp = rsp; for (int col1 = 0; col1 < 8; col1++) { tty->print("(rsp+0x%03x) 0x%016lx: ", (int)((intptr_t)dump_sp - (intptr_t)rsp), (intptr_t)dump_sp); diff --git a/src/hotspot/cpu/x86/methodHandles_x86.cpp b/src/hotspot/cpu/x86/methodHandles_x86.cpp index fa5b6f8e2bc..912e8411716 100644 --- a/src/hotspot/cpu/x86/methodHandles_x86.cpp +++ b/src/hotspot/cpu/x86/methodHandles_x86.cpp @@ -507,7 +507,17 @@ void trace_method_handle_stub(const char* adaptername, for (int i = 0; i < saved_regs_count; i++) { Register r = as_Register(i); // The registers are stored in reverse order on the stack (by pusha). +#ifdef AMD64 + assert(RegisterImpl::number_of_registers == 16, "sanity"); + if (r == rsp) { + // rsp is actually not stored by pusha(), compute the old rsp from saved_regs (rsp after pusha): saved_regs + 16 = old rsp + tty->print("%3s=" PTR_FORMAT, r->name(), (intptr_t)(&saved_regs[16])); + } else { + tty->print("%3s=" PTR_FORMAT, r->name(), saved_regs[((saved_regs_count - 1) - i)]); + } +#else tty->print("%3s=" PTR_FORMAT, r->name(), saved_regs[((saved_regs_count - 1) - i)]); +#endif if ((i + 1) % 4 == 0) { tty->cr(); } else { From 840c3050e935d4a5f5f6fadc2e6a218cb8cbcfe7 Mon Sep 17 00:00:00 2001 From: Andy Herrick Date: Mon, 18 May 2020 10:11:10 -0400 Subject: [PATCH 096/143] 8237971: Package type for runtime image on macosx Reviewed-by: asemenyuk, almatvee --- .../internal/MacBaseInstallerBundler.java | 24 +++++++------- .../jpackage/internal/MacDmgBundler.java | 32 ++++++++++++++----- .../jpackage/internal/MacPkgBundler.java | 8 ++--- .../jpackage/internal/resources/DMGsetup.scpt | 15 ++++----- 4 files changed, 47 insertions(+), 32 deletions(-) diff --git a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacBaseInstallerBundler.java b/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacBaseInstallerBundler.java index d55c1da9a58..febaa7e0577 100644 --- a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacBaseInstallerBundler.java +++ b/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacBaseInstallerBundler.java @@ -83,17 +83,6 @@ public abstract class MacBaseInstallerBundler extends AbstractBundler { params -> "", null); - public static final BundlerParamInfo MAC_INSTALL_DIR = - new StandardBundlerParam<>( - "mac-install-dir", - String.class, - params -> { - String dir = INSTALL_DIR.fetchFrom(params); - return (dir != null) ? dir : "/Applications"; - }, - (s, p) -> s - ); - public static final BundlerParamInfo INSTALLER_NAME = new StandardBundlerParam<> ( "mac.installerName", @@ -111,6 +100,19 @@ public abstract class MacBaseInstallerBundler extends AbstractBundler { }, (s, p) -> s); + protected static String getInstallDir( + Map params) { + String returnValue = INSTALL_DIR.fetchFrom(params); + if (returnValue == null) { + if (StandardBundlerParam.isRuntimeInstaller(params)) { + returnValue = "/Library/Java/JavaVirtualMachines"; + } else { + returnValue = "/Applications"; + } + } + return returnValue; + } + protected void validateAppImageAndBundeler( Map params) throws ConfigException { if (PREDEFINED_APP_IMAGE.fetchFrom(params) != null) { diff --git a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacDmgBundler.java b/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacDmgBundler.java index 78c0b8ff2da..a66051745c8 100644 --- a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacDmgBundler.java +++ b/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacDmgBundler.java @@ -68,9 +68,9 @@ public class MacDmgBundler extends MacBaseInstallerBundler { File appImageDir = APP_IMAGE_TEMP_ROOT.fetchFrom(params); try { appImageDir.mkdirs(); + File appLocation = prepareAppBundle(params); - if (prepareAppBundle(params) != null && - prepareConfigFiles(params)) { + if (appLocation != null && prepareConfigFiles(params)) { File configScript = getConfig_Script(params); if (configScript.exists()) { Log.verbose(MessageFormat.format( @@ -79,7 +79,7 @@ public class MacDmgBundler extends MacBaseInstallerBundler { IOUtils.run("bash", configScript); } - return buildDMG(params, outdir); + return buildDMG(params, appLocation, outdir); } return null; } catch (IOException ex) { @@ -117,8 +117,7 @@ public class MacDmgBundler extends MacBaseInstallerBundler { data.put("DEPLOY_VOLUME_PATH", volumePath.toString()); data.put("DEPLOY_APPLICATION_NAME", APP_NAME.fetchFrom(params)); - data.put("DEPLOY_INSTALL_LOCATION", MAC_INSTALL_DIR.fetchFrom(params)); - data.put("DEPLOY_INSTALL_NAME", MAC_INSTALL_DIR.fetchFrom(params)); + data.put("DEPLOY_INSTALL_LOCATION", getInstallDir(params)); createResource(DEFAULT_DMG_SETUP_SCRIPT, params) .setCategory(I18N.getString("resource.dmg-setup-script")) @@ -253,9 +252,8 @@ public class MacDmgBundler extends MacBaseInstallerBundler { return null; } - private File buildDMG( - Map params, File outdir) - throws IOException { + private File buildDMG( Map params, + File appLocation, File outdir) throws IOException { File imagesRoot = IMAGES_ROOT.fetchFrom(params); if (!imagesRoot.exists()) imagesRoot.mkdirs(); @@ -269,6 +267,24 @@ public class MacDmgBundler extends MacBaseInstallerBundler { StandardBundlerParam.getPredefinedAppImage(params); if (predefinedImage != null) { srcFolder = predefinedImage; + } else if (StandardBundlerParam.isRuntimeInstaller(params)) { + Path newRoot = Files.createTempDirectory( + TEMP_ROOT.fetchFrom(params).toPath(), "root-"); + + // first, is this already a runtime with + // /Contents/Home - if so we need the Home dir + Path original = appLocation.toPath(); + Path home = original.resolve("Contents/Home"); + Path source = (Files.exists(home)) ? home : original; + + // Then we need to put back the /Content/Home + Path root = newRoot.resolve( + MAC_CF_BUNDLE_IDENTIFIER.fetchFrom(params)); + Path dest = root.resolve("Contents/Home"); + + IOUtils.copyRecursive(source, dest); + + srcFolder = newRoot.toFile(); } Log.verbose(MessageFormat.format(I18N.getString( diff --git a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacPkgBundler.java b/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacPkgBundler.java index dae6c96ef15..894d0ab817d 100644 --- a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacPkgBundler.java +++ b/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacPkgBundler.java @@ -176,10 +176,10 @@ public class MacPkgBundler extends MacBaseInstallerBundler { Map data = new HashMap<>(); - Path appLocation = Path.of(MAC_INSTALL_DIR.fetchFrom(params), + Path appLocation = Path.of(getInstallDir(params), APP_NAME.fetchFrom(params) + ".app", "Contents", "app"); - data.put("INSTALL_LOCATION", MAC_INSTALL_DIR.fetchFrom(params)); + data.put("INSTALL_LOCATION", getInstallDir(params)); data.put("APP_LOCATION", appLocation.toString()); createResource(TEMPLATE_PREINSTALL_SCRIPT, params) @@ -406,7 +406,7 @@ public class MacPkgBundler extends MacBaseInstallerBundler { "--root", root, "--install-location", - MAC_INSTALL_DIR.fetchFrom(params), + getInstallDir(params), "--analyze", cpl.getAbsolutePath()); @@ -421,7 +421,7 @@ public class MacPkgBundler extends MacBaseInstallerBundler { "--root", root, "--install-location", - MAC_INSTALL_DIR.fetchFrom(params), + getInstallDir(params), "--component-plist", cpl.getAbsolutePath(), "--scripts", diff --git a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/DMGsetup.scpt b/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/DMGsetup.scpt index 4f0b23857c2..37ddb68918c 100644 --- a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/DMGsetup.scpt +++ b/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/DMGsetup.scpt @@ -8,8 +8,8 @@ tell application "Finder" set toolbar visible of theWindow to false set statusbar visible of theWindow to false - -- size of window should match size of background - set the bounds of theWindow to {400, 100, 917, 380} + -- size of window should fit the size of background + set the bounds of theWindow to {400, 100, 920, 440} set theViewOptions to a reference to the icon view options of theWindow set arrangement of theViewOptions to not arranged @@ -17,20 +17,17 @@ tell application "Finder" set background picture of theViewOptions to POSIX file "DEPLOY_BG_FILE" -- Create alias for install location - make new alias file at POSIX file "DEPLOY_VOLUME_PATH" to POSIX file "DEPLOY_INSTALL_LOCATION" with properties {name:"DEPLOY_INSTALL_NAME"} + make new alias file at POSIX file "DEPLOY_VOLUME_PATH" to POSIX file "DEPLOY_INSTALL_LOCATION" with properties {name:"DEPLOY_INSTALL_LOCATION"} set allTheFiles to the name of every item of theWindow repeat with theFile in allTheFiles set theFilePath to POSIX path of theFile - if theFilePath is "/DEPLOY_APPLICATION_NAME.app" then - -- Position application location - set position of item theFile of theWindow to {120, 130} - else if theFilePath is "DEPLOY_INSTALL_NAME" then + if theFilePath is "DEPLOY_INSTALL_LOCATION" then -- Position install location set position of item theFile of theWindow to {390, 130} else - -- Move all other files far enough to be not visible if user has "show hidden files" option set - set position of item theFile of theWindow to {1000, 130} + -- Position application or runtime + set position of item theFile of theWindow to {120, 130} end if end repeat From b957788c329f4abcbf14ae09347f76caf28316e5 Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Mon, 18 May 2020 10:47:52 -0400 Subject: [PATCH 097/143] 8245137: aarch64 ICache flush depends on enabling gnu extensions Use __builtin___clear_cache. Reviewed-by: aph, dholmes --- src/hotspot/cpu/aarch64/icache_aarch64.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hotspot/cpu/aarch64/icache_aarch64.hpp b/src/hotspot/cpu/aarch64/icache_aarch64.hpp index 869568baeed..5e689fb988e 100644 --- a/src/hotspot/cpu/aarch64/icache_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/icache_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. * @@ -34,10 +34,10 @@ class ICache : public AbstractICache { public: static void initialize(); static void invalidate_word(address addr) { - __clear_cache((char *)addr, (char *)(addr + 3)); + __builtin___clear_cache((char *)addr, (char *)(addr + 3)); } static void invalidate_range(address start, int nbytes) { - __clear_cache((char *)start, (char *)(start + nbytes)); + __builtin___clear_cache((char *)start, (char *)(start + nbytes)); } }; From 60728a487c13cf4cae0051f824700f73052473e5 Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Mon, 18 May 2020 11:31:16 -0400 Subject: [PATCH 098/143] 8242424: Deprecate InitialBootClassLoaderMetaspaceSize 8243147: Deprecate UseLargePagesInMetaspace Mark these options for deprecation Reviewed-by: stuefe, dcubed --- src/hotspot/share/runtime/arguments.cpp | 2 ++ src/hotspot/share/runtime/globals.hpp | 4 ++-- .../jtreg/runtime/CommandLine/VMDeprecatedOptions.java | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index dbe9e1048d0..bbb845b1fc7 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -533,6 +533,8 @@ static SpecialFlag const special_jvm_flags[] = { { "BiasedLockingDecayTime", JDK_Version::jdk(15), JDK_Version::jdk(16), JDK_Version::jdk(17) }, { "UseOptoBiasInlining", JDK_Version::jdk(15), JDK_Version::jdk(16), JDK_Version::jdk(17) }, { "PrintPreciseBiasedLockingStatistics", JDK_Version::jdk(15), JDK_Version::jdk(16), JDK_Version::jdk(17) }, + { "InitialBootClassLoaderMetaspaceSize", JDK_Version::jdk(15), JDK_Version::jdk(16), JDK_Version::jdk(17) }, + { "UseLargePagesInMetaspace", JDK_Version::jdk(15), JDK_Version::jdk(16), JDK_Version::jdk(17) }, // --- Deprecated alias flags (see also aliased_jvm_flags) - sorted by obsolete_in then expired_in: { "DefaultMaxRAMFraction", JDK_Version::jdk(8), JDK_Version::undefined(), JDK_Version::undefined() }, diff --git a/src/hotspot/share/runtime/globals.hpp b/src/hotspot/share/runtime/globals.hpp index f18d7f3f9d2..e5f4d7811b5 100644 --- a/src/hotspot/share/runtime/globals.hpp +++ b/src/hotspot/share/runtime/globals.hpp @@ -178,7 +178,7 @@ const size_t minimumSymbolTableSize = 1024; "Fail large pages individual allocation") \ \ product(bool, UseLargePagesInMetaspace, false, \ - "Use large page memory in metaspace. " \ + "(Deprecated) Use large page memory in metaspace. " \ "Only used if UseLargePages is enabled.") \ \ product(bool, UseNUMA, false, \ @@ -895,7 +895,7 @@ const size_t minimumSymbolTableSize = 1024; \ product(size_t, InitialBootClassLoaderMetaspaceSize, \ NOT_LP64(2200*K) LP64_ONLY(4*M), \ - "Initial size of the boot class loader data metaspace") \ + "(Deprecated) Initial size of the boot class loader data metaspace") \ range(30*K, max_uintx/BytesPerWord) \ constraint(InitialBootClassLoaderMetaspaceSizeConstraintFunc, AfterErgo)\ \ diff --git a/test/hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java b/test/hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java index 1cba9d545f4..6853905fa21 100644 --- a/test/hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java +++ b/test/hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java @@ -55,6 +55,8 @@ public class VMDeprecatedOptions { {"BiasedLockingBulkRevokeThreshold", "40"}, {"BiasedLockingDecayTime", "25000"}, {"UseOptoBiasInlining", "true"}, + {"InitialBootClassLoaderMetaspaceSize", "2200000"}, + {"UseLargePagesInMetaspace", "true"}, // deprecated alias flags (see also aliased_jvm_flags): {"DefaultMaxRAMFraction", "4"}, From 02293daa6438a07723e63cf23917d5ab1c6bc688 Mon Sep 17 00:00:00 2001 From: Yumin Qi Date: Mon, 18 May 2020 09:28:06 -0700 Subject: [PATCH 099/143] 8245070: 32-bit builds are broken after JDK-8242524 Reviewed-by: erikj, ihse --- make/Images.gmk | 47 +++++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/make/Images.gmk b/make/Images.gmk index 1770c0abe88..7864c0f6774 100644 --- a/make/Images.gmk +++ b/make/Images.gmk @@ -147,31 +147,34 @@ ifeq ($(BUILD_CDS_ARCHIVE), true) JRE_TARGETS += $(gen_cds_archive_jre) - $(eval $(call SetupExecute, gen_cds_nocoops_archive_jdk, \ - WARN := Creating CDS-NOCOOPS archive for jdk image, \ - DEPS := $(jlink_jdk), \ - OUTPUT_FILE := $(JDK_IMAGE_DIR)/$(CDS_NOCOOPS_ARCHIVE), \ - SUPPORT_DIR := $(SUPPORT_OUTPUTDIR)/images/jdk, \ - COMMAND := $(FIXPATH) $(JDK_IMAGE_DIR)/bin/java -Xshare:dump \ - -XX:SharedArchiveFile=$(JDK_IMAGE_DIR)/$(CDS_NOCOOPS_ARCHIVE) \ - -XX:-UseCompressedOops \ - -Xmx128M -Xms128M $(LOG_INFO), \ - )) + ifeq ($(call isTargetCpuBits, 64), true) + $(eval $(call SetupExecute, gen_cds_nocoops_archive_jdk, \ + WARN := Creating CDS-NOCOOPS archive for jdk image, \ + DEPS := $(jlink_jdk), \ + OUTPUT_FILE := $(JDK_IMAGE_DIR)/$(CDS_NOCOOPS_ARCHIVE), \ + SUPPORT_DIR := $(SUPPORT_OUTPUTDIR)/images/jdk, \ + COMMAND := $(FIXPATH) $(JDK_IMAGE_DIR)/bin/java -Xshare:dump \ + -XX:SharedArchiveFile=$(JDK_IMAGE_DIR)/$(CDS_NOCOOPS_ARCHIVE) \ + -XX:-UseCompressedOops \ + -Xmx128M -Xms128M $(LOG_INFO), \ + )) - JDK_TARGETS += $(gen_cds_nocoops_archive_jdk) + JDK_TARGETS += $(gen_cds_nocoops_archive_jdk) - $(eval $(call SetupExecute, gen_cds_nocoops_archive_jre, \ - WARN := Creating CDS-NOCOOPS archive for jre image, \ - DEPS := $(jlink_jre), \ - OUTPUT_FILE := $(JRE_IMAGE_DIR)/$(CDS_NOCOOPS_ARCHIVE), \ - SUPPORT_DIR := $(SUPPORT_OUTPUTDIR)/images/jre, \ - COMMAND := $(FIXPATH) $(JRE_IMAGE_DIR)/bin/java -Xshare:dump \ - -XX:SharedArchiveFile=$(JRE_IMAGE_DIR)/$(CDS_NOCOOPS_ARCHIVE) \ - -XX:-UseCompressedOops \ - -Xmx128M -Xms128M $(LOG_INFO), \ - )) + $(eval $(call SetupExecute, gen_cds_nocoops_archive_jre, \ + WARN := Creating CDS-NOCOOPS archive for jre image, \ + DEPS := $(jlink_jre), \ + OUTPUT_FILE := $(JRE_IMAGE_DIR)/$(CDS_NOCOOPS_ARCHIVE), \ + SUPPORT_DIR := $(SUPPORT_OUTPUTDIR)/images/jre, \ + COMMAND := $(FIXPATH) $(JRE_IMAGE_DIR)/bin/java -Xshare:dump \ + -XX:SharedArchiveFile=$(JRE_IMAGE_DIR)/$(CDS_NOCOOPS_ARCHIVE) \ + -XX:-UseCompressedOops \ + -Xmx128M -Xms128M $(LOG_INFO), \ + )) + + JRE_TARGETS += $(gen_cds_nocoops_archive_jre) + endif - JRE_TARGETS += $(gen_cds_nocoops_archive_jre) endif ################################################################################ From fd28aad72d3a13fbc2eb13293d40564e471414f3 Mon Sep 17 00:00:00 2001 From: Anthony Scarpino Date: Mon, 18 May 2020 09:42:52 -0700 Subject: [PATCH 100/143] 8166597: Crypto support for the EdDSA Signature Algorithm Reviewed-by: weijun, mullan, wetmore --- .../classes/build/tools/intpoly/FieldGen.java | 70 ++- .../java/security/interfaces/EdECKey.java | 47 ++ .../security/interfaces/EdECPrivateKey.java | 55 ++ .../security/interfaces/EdECPublicKey.java | 50 ++ .../security/spec/EdDSAParameterSpec.java | 110 ++++ .../classes/java/security/spec/EdECPoint.java | 86 +++ .../security/spec/EdECPrivateKeySpec.java | 81 +++ .../java/security/spec/EdECPublicKeySpec.java | 78 +++ .../security/spec/NamedParameterSpec.java | 18 +- src/java.base/share/classes/module-info.java | 1 + .../classes/sun/security/pkcs/PKCS7.java | 6 +- .../classes/sun/security/provider/SHA3.java | 22 +- .../sun/security/provider/SHAKE256.java | 45 ++ .../sun/security/tools/keytool/Main.java | 6 + .../classes/sun/security/util/KeyUtil.java | 17 +- .../util/SecurityProviderConstants.java | 7 +- .../util/math/intpoly/IntegerPolynomial.java | 34 +- .../math/intpoly/IntegerPolynomial1305.java | 11 +- .../math/intpoly/IntegerPolynomial25519.java | 21 +- .../math/intpoly/IntegerPolynomial448.java | 11 +- .../intpoly/IntegerPolynomialModBinP.java | 228 +++++++ .../sun/security/x509/AlgorithmId.java | 30 +- .../sun/security/ec/ParametersMap.java | 156 +++++ .../share/classes/sun/security/ec/SunEC.java | 65 +- .../sun/security/ec/XECParameters.java | 95 +-- .../sun/security/ec/ed/Ed25519Operations.java | 214 +++++++ .../sun/security/ec/ed/Ed448Operations.java | 201 ++++++ .../ec/ed/EdDSAAlgorithmParameters.java | 107 ++++ .../sun/security/ec/ed/EdDSAKeyFactory.java | 236 +++++++ .../security/ec/ed/EdDSAKeyPairGenerator.java | 139 +++++ .../sun/security/ec/ed/EdDSAOperations.java | 279 +++++++++ .../sun/security/ec/ed/EdDSAParameters.java | 332 ++++++++++ .../security/ec/ed/EdDSAPrivateKeyImpl.java | 116 ++++ .../security/ec/ed/EdDSAPublicKeyImpl.java | 130 ++++ .../sun/security/ec/ed/EdDSASignature.java | 314 ++++++++++ .../sun/security/ec/ed/EdECOperations.java | 103 ++++ .../ec/point/ExtendedHomogeneousPoint.java | 194 ++++++ .../classes/sun/security/ec/point/Point.java | 3 +- .../security/ec/point/ProjectivePoint.java | 32 +- .../jdk/sun/security/ec/ed/EdECKeyFormat.java | 144 +++++ test/jdk/sun/security/ec/ed/TestEdDSA.java | 581 ++++++++++++++++++ test/jdk/sun/security/ec/ed/TestEdOps.java | 291 +++++++++ test/jdk/sun/security/ec/xec/TestXECOps.java | 12 +- .../jdk/sun/security/ec/xec/XECIterative.java | 7 +- .../util/math/TestIntegerModuloP.java | 12 +- test/lib/jdk/test/lib/Convert.java | 37 +- .../javax/crypto/full/SignatureBench.java | 18 +- 47 files changed, 4697 insertions(+), 155 deletions(-) create mode 100644 src/java.base/share/classes/java/security/interfaces/EdECKey.java create mode 100644 src/java.base/share/classes/java/security/interfaces/EdECPrivateKey.java create mode 100644 src/java.base/share/classes/java/security/interfaces/EdECPublicKey.java create mode 100644 src/java.base/share/classes/java/security/spec/EdDSAParameterSpec.java create mode 100644 src/java.base/share/classes/java/security/spec/EdECPoint.java create mode 100644 src/java.base/share/classes/java/security/spec/EdECPrivateKeySpec.java create mode 100644 src/java.base/share/classes/java/security/spec/EdECPublicKeySpec.java create mode 100644 src/java.base/share/classes/sun/security/provider/SHAKE256.java create mode 100644 src/java.base/share/classes/sun/security/util/math/intpoly/IntegerPolynomialModBinP.java create mode 100644 src/jdk.crypto.ec/share/classes/sun/security/ec/ParametersMap.java create mode 100644 src/jdk.crypto.ec/share/classes/sun/security/ec/ed/Ed25519Operations.java create mode 100644 src/jdk.crypto.ec/share/classes/sun/security/ec/ed/Ed448Operations.java create mode 100644 src/jdk.crypto.ec/share/classes/sun/security/ec/ed/EdDSAAlgorithmParameters.java create mode 100644 src/jdk.crypto.ec/share/classes/sun/security/ec/ed/EdDSAKeyFactory.java create mode 100644 src/jdk.crypto.ec/share/classes/sun/security/ec/ed/EdDSAKeyPairGenerator.java create mode 100644 src/jdk.crypto.ec/share/classes/sun/security/ec/ed/EdDSAOperations.java create mode 100644 src/jdk.crypto.ec/share/classes/sun/security/ec/ed/EdDSAParameters.java create mode 100644 src/jdk.crypto.ec/share/classes/sun/security/ec/ed/EdDSAPrivateKeyImpl.java create mode 100644 src/jdk.crypto.ec/share/classes/sun/security/ec/ed/EdDSAPublicKeyImpl.java create mode 100644 src/jdk.crypto.ec/share/classes/sun/security/ec/ed/EdDSASignature.java create mode 100644 src/jdk.crypto.ec/share/classes/sun/security/ec/ed/EdECOperations.java create mode 100644 src/jdk.crypto.ec/share/classes/sun/security/ec/point/ExtendedHomogeneousPoint.java create mode 100644 test/jdk/sun/security/ec/ed/EdECKeyFormat.java create mode 100644 test/jdk/sun/security/ec/ed/TestEdDSA.java create mode 100644 test/jdk/sun/security/ec/ed/TestEdOps.java diff --git a/make/jdk/src/classes/build/tools/intpoly/FieldGen.java b/make/jdk/src/classes/build/tools/intpoly/FieldGen.java index dfde325b613..0d30436058c 100644 --- a/make/jdk/src/classes/build/tools/intpoly/FieldGen.java +++ b/make/jdk/src/classes/build/tools/intpoly/FieldGen.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 @@ -21,7 +21,6 @@ * questions. */ - /* * This file is used to generated optimized finite field implementations. */ @@ -170,6 +169,19 @@ public class FieldGen { o521crSequence(19), orderFieldSmallCrSequence(19) ); + static FieldParams O25519 = new FieldParams( + "Curve25519OrderField", 26, 10, 1, 252, + "1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed", + orderFieldCrSequence(10), orderFieldSmallCrSequence(10) + ); + + static FieldParams O448 = new FieldParams( + "Curve448OrderField", 28, 16, 1, 446, + "3fffffffffffffffffffffffffffffffffffffffffffffffffffffff7cca23e9c44edb49aed63690216cc2728dc58f552378c292ab5844f3", + //"ffffffffffffffffffffffffffffffffffffffffffffffffffffffff7cca23e9c44edb49aed63690216cc2728dc58f552378c292ab5844f3", + orderFieldCrSequence(16), orderFieldSmallCrSequence(16) + ); + private static List o521crSequence(int numLimbs) { // split the full reduce in half, with a carry in between @@ -212,7 +224,8 @@ public class FieldGen { } static final FieldParams[] ALL_FIELDS = { - P256, P384, P521, O256, O384, O521, + Curve25519, Curve448, + P256, P384, P521, O256, O384, O521, O25519, O448 }; public static class Term { @@ -322,6 +335,11 @@ public class FieldGen { private Iterable buildTerms(BigInteger sub) { // split a large subtrahend into smaller terms // that are aligned with limbs + boolean negate = false; + if (sub.compareTo(BigInteger.ZERO) < 0) { + negate = true; + sub = sub.negate(); + } List result = new ArrayList(); BigInteger mod = BigInteger.valueOf(1 << bitsPerLimb); int termIndex = 0; @@ -332,6 +350,9 @@ public class FieldGen { coef = coef - (1 << bitsPerLimb); plusOne = true; } + if (negate) { + coef = 0 - coef; + } if (coef != 0) { int pow = termIndex * bitsPerLimb; result.add(new Term(pow, -coef)); @@ -619,6 +640,14 @@ public class FieldGen { result.appendLine(); result.appendLine("}"); + StringBuilder coqTerms = new StringBuilder("//"); + for (Term t : params.getTerms()) { + coqTerms.append("(" + t.getPower() + "%nat,"); + coqTerms.append(t.getCoefficient() + ")::"); + } + coqTerms.append("nil."); + result.appendLine(coqTerms.toString()); + result.appendLine("private static BigInteger evaluateModulus() {"); result.incrIndent(); result.appendLine("BigInteger result = BigInteger.valueOf(2).pow(" @@ -650,6 +679,41 @@ public class FieldGen { result.decrIndent(); result.appendLine("}"); + result.appendLine("@Override"); + result.appendLine("protected void reduceIn(long[] limbs, long v, int i) {"); + result.incrIndent(); + String c = "v"; + for (Term t : params.getTerms()) { + int reduceBits = params.getPower() - t.getPower(); + int coefficient = -1 * t.getCoefficient(); + + String x = coefficient + " * " + c; + String accOp = "+="; + String temp = null; + if (coefficient == 1) { + x = c; + } else if (coefficient == -1) { + x = c; + accOp = "-="; + } else { + temp = result.getTemporary("long", x); + x = temp; + } + + if (reduceBits % params.getBitsPerLimb() == 0) { + int pos = reduceBits / params.getBitsPerLimb(); + result.appendLine("limbs[i - " + pos + "] " + accOp + " " + x + ";"); + } else { + int secondPos = reduceBits / params.getBitsPerLimb(); + int bitOffset = (secondPos + 1) * params.getBitsPerLimb() - reduceBits; + int rightBitOffset = params.getBitsPerLimb() - bitOffset; + result.appendLine("limbs[i - " + (secondPos + 1) + "] " + accOp + " (" + x + " << " + bitOffset + ") & LIMB_MASK;"); + result.appendLine("limbs[i - " + secondPos + "] " + accOp + " " + x + " >> " + rightBitOffset + ";"); + } + } + result.decrIndent(); + result.appendLine("}"); + result.appendLine("@Override"); result.appendLine("protected void finalCarryReduceLast(long[] limbs) {"); result.incrIndent(); diff --git a/src/java.base/share/classes/java/security/interfaces/EdECKey.java b/src/java.base/share/classes/java/security/interfaces/EdECKey.java new file mode 100644 index 00000000000..bec29eeed8e --- /dev/null +++ b/src/java.base/share/classes/java/security/interfaces/EdECKey.java @@ -0,0 +1,47 @@ +/* + * 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 java.security.interfaces; + +import java.security.spec.NamedParameterSpec; + +/** + * An interface for an elliptic curve public/private key as defined by + * RFC 8032: Edwards-Curve + * Digital Signature Algorithm (EdDSA). These keys are distinct from the + * keys represented by {@code ECKey}, and they are intended for use with + * algorithms based on RFC 8032 such as the EdDSA {@code Signature} algorithm. + * This interface allows access to the algorithm parameters associated with + * the key. + * + * @since 15 + */ +public interface EdECKey { + /** + * Returns the algorithm parameters associated with the key. + * + * @return the associated algorithm parameters. + */ + NamedParameterSpec getParams(); +} diff --git a/src/java.base/share/classes/java/security/interfaces/EdECPrivateKey.java b/src/java.base/share/classes/java/security/interfaces/EdECPrivateKey.java new file mode 100644 index 00000000000..826b52650ea --- /dev/null +++ b/src/java.base/share/classes/java/security/interfaces/EdECPrivateKey.java @@ -0,0 +1,55 @@ +/* + * 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 java.security.interfaces; + +import java.security.PrivateKey; +import java.util.Optional; + +/** + * An interface for an elliptic curve private key as defined by + * RFC 8032: Edwards-Curve + * Digital Signature Algorithm (EdDSA). These keys are distinct from the + * keys represented by {@code ECPrivateKey}, and they are intended for use + * with algorithms based on RFC 8032 such as the EdDSA {@code Signature} + * algorithm. + *

+ * An Edwards-Curve private key is a bit string. This interface only supports bit + * string lengths that are a multiple of 8, and the key is represented using + * a byte array. + * + * @since 15 + */ +public interface EdECPrivateKey extends EdECKey, PrivateKey { + + /** + * Get a copy of the byte array representing the private key. This method + * may return an empty {@code Optional} if the implementation is not + * willing to produce the private key value. + * + * @return an {@code Optional} containing the private key byte array. + * If the key is not available, then an empty {@code Optional}. + */ + Optional getBytes(); +} diff --git a/src/java.base/share/classes/java/security/interfaces/EdECPublicKey.java b/src/java.base/share/classes/java/security/interfaces/EdECPublicKey.java new file mode 100644 index 00000000000..d2e26411651 --- /dev/null +++ b/src/java.base/share/classes/java/security/interfaces/EdECPublicKey.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. 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 java.security.interfaces; + +import java.security.PublicKey; +import java.security.spec.EdECPoint; + +/** + * An interface for an elliptic curve public key as defined by + * RFC 8032: Edwards-Curve + * Digital Signature Algorithm (EdDSA). These keys are distinct from the + * keys represented by {@code ECPublicKey}, and they are intended for use with + * algorithms based on RFC 8032 such as the EdDSA {@code Signature} algorithm. + *

+ * An Edwards-Curve public key is a point on the curve, which is represented using an + * EdECPoint. + * + * @since 15 + */ +public interface EdECPublicKey extends EdECKey, PublicKey { + + /** + * Get the point representing the public key. + * + * @return the {@code EdECPoint} representing the public key. + */ + EdECPoint getPoint(); +} diff --git a/src/java.base/share/classes/java/security/spec/EdDSAParameterSpec.java b/src/java.base/share/classes/java/security/spec/EdDSAParameterSpec.java new file mode 100644 index 00000000000..d66689b6336 --- /dev/null +++ b/src/java.base/share/classes/java/security/spec/EdDSAParameterSpec.java @@ -0,0 +1,110 @@ +/* + * 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 java.security.spec; + +import java.security.InvalidParameterException; +import java.util.Objects; +import java.util.Optional; + +/** + * A class used to specify EdDSA signature and verification parameters. All + * algorithm modes in RFC 8032: + * Edwards-Curve Digital Signature Algorithm (EdDSA) can be specified using + * combinations of the settings in this class. + * + *

    + *
  • If prehash is true, then the mode is Ed25519ph or Ed448ph
  • + *
  • Otherwise, if a context is present, the mode is Ed25519ctx or Ed448
  • + *
  • Otherwise, the mode is Ed25519 or Ed448
  • + *
+ * + * @since 15 + */ + +public class EdDSAParameterSpec implements AlgorithmParameterSpec { + + private final boolean prehash; + private final byte[] context; + + /** + * Construct an {@code EdDSAParameterSpec} by specifying whether the prehash mode + * is used. No context is provided so this constructor specifies a mode + * in which the context is null. Note that this mode may be different + * than the mode in which an empty array is used as the context. + * + * @param prehash whether the prehash mode is specified. + */ + public EdDSAParameterSpec(boolean prehash) { + this.prehash = prehash; + this.context = null; + } + + /** + * Construct an {@code EdDSAParameterSpec} by specifying a context and whether the + * prehash mode is used. The context may not be null, but it may be an + * empty array. The mode used when the context is an empty array may not be + * the same as the mode used when the context is absent. + * + * @param prehash whether the prehash mode is specified. + * @param context the context is copied and bound to the signature. + * @throws NullPointerException if context is null. + * @throws InvalidParameterException if context length is greater than 255. + */ + public EdDSAParameterSpec(boolean prehash, byte[] context) { + + Objects.requireNonNull(context, "context may not be null"); + if (context.length > 255) { + throw new InvalidParameterException("context length cannot be " + + "greater than 255"); + } + + this.prehash = prehash; + this.context = context.clone(); + } + + /** + * Get whether the prehash mode is specified. + * + * @return whether the prehash mode is specified. + */ + public boolean isPrehash() { + return prehash; + } + + /** + * Get the context that the signature will use. + * + * @return {@code Optional} contains a copy of the context or empty + * if context is null. + */ + public Optional getContext() { + if (context == null) { + return Optional.empty(); + } else { + return Optional.of(context.clone()); + } + } +} diff --git a/src/java.base/share/classes/java/security/spec/EdECPoint.java b/src/java.base/share/classes/java/security/spec/EdECPoint.java new file mode 100644 index 00000000000..cb080f8557d --- /dev/null +++ b/src/java.base/share/classes/java/security/spec/EdECPoint.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. 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 java.security.spec; + +import java.math.BigInteger; +import java.util.Objects; + +/** + * An elliptic curve point used to specify keys as defined by + * RFC 8032: Edwards-Curve + * Digital Signature Algorithm (EdDSA). These points are distinct from the + * points represented by {@code ECPoint}, and they are intended for use with + * algorithms based on RFC 8032 such as the EdDSA {@code Signature} algorithm. + *

+ * An EdEC point is specified by its y-coordinate value and a boolean that + * indicates whether the x-coordinate is odd. The y-coordinate is an + * element of the field of integers modulo some value p that is determined by + * the algorithm parameters. This field element is represented by a + * {@code BigInteger}, and implementations that consume objects of this class + * may reject integer values which are not in the range [0, p). + * + * @since 15 + */ + +public final class EdECPoint { + + private final boolean xOdd; + private final BigInteger y; + + /** + * Construct an EdECPoint. + * + * @param xOdd whether the x-coordinate is odd. + * @param y the y-coordinate, represented using a {@code BigInteger}. + * + * @throws NullPointerException if {@code y} is null. + */ + public EdECPoint(boolean xOdd, BigInteger y) { + + Objects.requireNonNull(y, "y must not be null"); + + this.xOdd = xOdd; + this.y = y; + } + + /** + * Get whether the x-coordinate of the point is odd. + * + * @return a boolean indicating whether the x-coordinate is odd. + */ + public boolean isXOdd() { + return xOdd; + } + + /** + * Get the y-coordinate of the point. + * + * @return the y-coordinate, represented using a {@code BigInteger}. + */ + public BigInteger getY() { + return y; + } +} diff --git a/src/java.base/share/classes/java/security/spec/EdECPrivateKeySpec.java b/src/java.base/share/classes/java/security/spec/EdECPrivateKeySpec.java new file mode 100644 index 00000000000..370dfc92e59 --- /dev/null +++ b/src/java.base/share/classes/java/security/spec/EdECPrivateKeySpec.java @@ -0,0 +1,81 @@ +/* + * 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 java.security.spec; + +import java.util.Objects; + +/** + * A class representing elliptic curve private keys as defined in + * RFC 8032: Edwards-Curve + * Digital Signature Algorithm (EdDSA), including the curve and other + * algorithm parameters. The private key is a bit string represented using + * a byte array. This class only supports bit string lengths that are a + * multiple of 8. + * + * @since 15 + */ +public final class EdECPrivateKeySpec implements KeySpec { + + private final NamedParameterSpec params; + private final byte[] bytes; + + /** + * Construct a private key spec using the supplied parameters and + * bit string. + * + * @param params the algorithm parameters. + * @param bytes the key as a byte array. This array is copied + * to protect against subsequent modification. + * + * @throws NullPointerException if {@code params} or {@code bytes} + * is null. + */ + public EdECPrivateKeySpec(NamedParameterSpec params, byte[] bytes) { + Objects.requireNonNull(params, "params must not be null"); + Objects.requireNonNull(bytes, "bytes must not be null"); + + this.params = params; + this.bytes = bytes.clone(); + } + + /** + * Get the algorithm parameters that define the curve and other settings. + * + * @return the algorithm parameters. + */ + public NamedParameterSpec getParams() { + return params; + } + + /** + * Get the byte array representing the private key. A new copy of the array + * is returned each time this method is called. + * + * @return the private key as a byte array. + */ + public byte[] getBytes() { + return bytes.clone(); + } +} diff --git a/src/java.base/share/classes/java/security/spec/EdECPublicKeySpec.java b/src/java.base/share/classes/java/security/spec/EdECPublicKeySpec.java new file mode 100644 index 00000000000..fc52b3b7968 --- /dev/null +++ b/src/java.base/share/classes/java/security/spec/EdECPublicKeySpec.java @@ -0,0 +1,78 @@ +/* + * 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 java.security.spec; + +import java.util.Objects; + +/** + * A class representing elliptic curve public keys as defined in + * RFC 8032: Edwards-Curve + * Digital Signature Algorithm (EdDSA), including the curve and other + * algorithm parameters. The public key is a point on the curve, which is + * represented using an {@code EdECPoint}. + * + * @since 15 + */ +public final class EdECPublicKeySpec implements KeySpec { + + private final NamedParameterSpec params; + private final EdECPoint point; + + /** + * Construct a public key spec using the supplied parameters and + * point. + * + * @param params the algorithm parameters. + * @param point the point representing the public key. + * + * @throws NullPointerException if {@code params} or {@code point} + * is null. + */ + public EdECPublicKeySpec(NamedParameterSpec params, EdECPoint point) { + Objects.requireNonNull(params, "params must not be null"); + Objects.requireNonNull(point, "point must not be null"); + + this.params = params; + this.point = point; + } + + /** + * Get the algorithm parameters that define the curve and other settings. + * + * @return the parameters. + */ + public NamedParameterSpec getParams() { + return params; + } + + /** + * Get the point representing the public key. + * + * @return the {@code EdECPoint} representing the public key. + */ + public EdECPoint getPoint() { + return point; + } +} diff --git a/src/java.base/share/classes/java/security/spec/NamedParameterSpec.java b/src/java.base/share/classes/java/security/spec/NamedParameterSpec.java index 6fecdc96640..9090567aca7 100644 --- a/src/java.base/share/classes/java/security/spec/NamedParameterSpec.java +++ b/src/java.base/share/classes/java/security/spec/NamedParameterSpec.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 @@ -52,6 +52,22 @@ public class NamedParameterSpec implements AlgorithmParameterSpec { public static final NamedParameterSpec X448 = new NamedParameterSpec("X448"); + /** + * The Ed25519 parameters + * + * @since 15 + */ + public static final NamedParameterSpec ED25519 + = new NamedParameterSpec("Ed25519"); + + /** + * The Ed448 parameters + * + * @since 15 + */ + public static final NamedParameterSpec ED448 + = new NamedParameterSpec("Ed448"); + private String name; /** diff --git a/src/java.base/share/classes/module-info.java b/src/java.base/share/classes/module-info.java index 55253635512..23b069edba7 100644 --- a/src/java.base/share/classes/module-info.java +++ b/src/java.base/share/classes/module-info.java @@ -294,6 +294,7 @@ module java.base { java.rmi, java.security.jgss, jdk.crypto.cryptoki, + jdk.crypto.ec, jdk.security.auth; exports sun.security.provider.certpath to java.naming; diff --git a/src/java.base/share/classes/sun/security/pkcs/PKCS7.java b/src/java.base/share/classes/sun/security/pkcs/PKCS7.java index 9de6a9f7059..2a217d4b4ee 100644 --- a/src/java.base/share/classes/sun/security/pkcs/PKCS7.java +++ b/src/java.base/share/classes/sun/security/pkcs/PKCS7.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -829,6 +829,10 @@ public class PKCS7 { BigInteger serialNumber = signerChain[0].getSerialNumber(); String encAlg = AlgorithmId.getEncAlgFromSigAlg(signatureAlgorithm); String digAlg = AlgorithmId.getDigAlgFromSigAlg(signatureAlgorithm); + if (digAlg == null) { + throw new UnsupportedOperationException("Unable to determine " + + "the digest algorithm from the signature algorithm."); + } SignerInfo signerInfo = new SignerInfo(issuerName, serialNumber, AlgorithmId.get(digAlg), null, AlgorithmId.get(encAlg), diff --git a/src/java.base/share/classes/sun/security/provider/SHA3.java b/src/java.base/share/classes/sun/security/provider/SHA3.java index fab2aea2ef2..100e0f7017e 100644 --- a/src/java.base/share/classes/sun/security/provider/SHA3.java +++ b/src/java.base/share/classes/sun/security/provider/SHA3.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 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 @@ -61,14 +61,16 @@ abstract class SHA3 extends DigestBase { 0x8000000000008080L, 0x80000001L, 0x8000000080008008L, }; + private final byte suffix; private byte[] state = new byte[WIDTH]; private long[] lanes = new long[DM*DM]; /** * Creates a new SHA-3 object. */ - SHA3(String name, int digestLength) { - super(name, digestLength, (WIDTH - (2 * digestLength))); + SHA3(String name, int digestLength, byte suffix, int c) { + super(name, digestLength, (WIDTH - c)); + this.suffix = suffix; } /** @@ -88,7 +90,7 @@ abstract class SHA3 extends DigestBase { */ void implDigest(byte[] out, int ofs) { int numOfPadding = - setPaddingBytes(buffer, (int)(bytesProcessed % buffer.length)); + setPaddingBytes(suffix, buffer, (int)(bytesProcessed % buffer.length)); if (numOfPadding < 1) { throw new ProviderException("Incorrect pad size: " + numOfPadding); } @@ -112,13 +114,13 @@ abstract class SHA3 extends DigestBase { * pad10*1 algorithm (section 5.1) and the 2-bit suffix "01" required * for SHA-3 hash (section 6.1). */ - private static int setPaddingBytes(byte[] in, int len) { + private static int setPaddingBytes(byte suffix, byte[] in, int len) { if (len != in.length) { // erase leftover values Arrays.fill(in, len, in.length, (byte)0); // directly store the padding bytes into the input // as the specified buffer is allocated w/ size = rateR - in[len] |= (byte) 0x06; + in[len] |= suffix; in[in.length - 1] |= (byte) 0x80; } return (in.length - len); @@ -268,7 +270,7 @@ abstract class SHA3 extends DigestBase { */ public static final class SHA224 extends SHA3 { public SHA224() { - super("SHA3-224", 28); + super("SHA3-224", 28, (byte)0x06, 56); } } @@ -277,7 +279,7 @@ abstract class SHA3 extends DigestBase { */ public static final class SHA256 extends SHA3 { public SHA256() { - super("SHA3-256", 32); + super("SHA3-256", 32, (byte)0x06, 64); } } @@ -286,7 +288,7 @@ abstract class SHA3 extends DigestBase { */ public static final class SHA384 extends SHA3 { public SHA384() { - super("SHA3-384", 48); + super("SHA3-384", 48, (byte)0x06, 96); } } @@ -295,7 +297,7 @@ abstract class SHA3 extends DigestBase { */ public static final class SHA512 extends SHA3 { public SHA512() { - super("SHA3-512", 64); + super("SHA3-512", 64, (byte)0x06, 128); } } } diff --git a/src/java.base/share/classes/sun/security/provider/SHAKE256.java b/src/java.base/share/classes/sun/security/provider/SHAKE256.java new file mode 100644 index 00000000000..1df97621364 --- /dev/null +++ b/src/java.base/share/classes/sun/security/provider/SHAKE256.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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package sun.security.provider; + +/* + * The SHAKE256 extendable output function. + */ +public final class SHAKE256 extends SHA3 { + public SHAKE256(int d) { + super("SHAKE256", d, (byte) 0x1F, 64); + } + + public void update(byte in) { + engineUpdate(in); + } + public void update(byte[] in, int off, int len) { + engineUpdate(in, off, len); + } + + public byte[] digest() { + return engineDigest(); + } +} diff --git a/src/java.base/share/classes/sun/security/tools/keytool/Main.java b/src/java.base/share/classes/sun/security/tools/keytool/Main.java index 616bc3dc2e7..47f4646ba9a 100644 --- a/src/java.base/share/classes/sun/security/tools/keytool/Main.java +++ b/src/java.base/share/classes/sun/security/tools/keytool/Main.java @@ -1870,6 +1870,12 @@ public final class Main { keysize = SecurityProviderConstants.DEF_RSA_KEY_SIZE; } else if ("DSA".equalsIgnoreCase(keyAlgName)) { keysize = SecurityProviderConstants.DEF_DSA_KEY_SIZE; + } else if ("EdDSA".equalsIgnoreCase(keyAlgName)) { + keysize = SecurityProviderConstants.DEF_ED_KEY_SIZE; + } else if ("Ed25519".equalsIgnoreCase(keyAlgName)) { + keysize = 255; + } else if ("Ed448".equalsIgnoreCase(keyAlgName)) { + keysize = 448; } } else { if ("EC".equalsIgnoreCase(keyAlgName)) { diff --git a/src/java.base/share/classes/sun/security/util/KeyUtil.java b/src/java.base/share/classes/sun/security/util/KeyUtil.java index e477b9f8db3..03be866bdd9 100644 --- a/src/java.base/share/classes/sun/security/util/KeyUtil.java +++ b/src/java.base/share/classes/sun/security/util/KeyUtil.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2016, 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 @@ -27,10 +27,10 @@ package sun.security.util; import java.security.AlgorithmParameters; import java.security.Key; -import java.security.PrivilegedAction; -import java.security.AccessController; import java.security.InvalidKeyException; import java.security.interfaces.ECKey; +import java.security.interfaces.EdECKey; +import java.security.interfaces.EdECPublicKey; import java.security.interfaces.RSAKey; import java.security.interfaces.DSAKey; import java.security.interfaces.DSAParams; @@ -44,6 +44,7 @@ import javax.crypto.interfaces.DHPublicKey; import javax.crypto.spec.DHParameterSpec; import javax.crypto.spec.DHPublicKeySpec; import java.math.BigInteger; +import java.security.spec.NamedParameterSpec; import sun.security.jca.JCAUtil; @@ -96,6 +97,16 @@ public final class KeyUtil { } else if (key instanceof DHKey) { DHKey pubk = (DHKey)key; size = pubk.getParams().getP().bitLength(); + } else if (key instanceof EdECKey) { + String nc = ((EdECKey) key).getParams().getName(); + if (nc.equalsIgnoreCase(NamedParameterSpec.ED25519.getName())) { + size = 255; + } else if (nc.equalsIgnoreCase( + NamedParameterSpec.ED448.getName())) { + size = 448; + } else { + size = -1; + } } // Otherwise, it may be a unextractable key of PKCS#11, or // a key we are not able to handle. diff --git a/src/java.base/share/classes/sun/security/util/SecurityProviderConstants.java b/src/java.base/share/classes/sun/security/util/SecurityProviderConstants.java index f798229072c..2d16d2ed625 100644 --- a/src/java.base/share/classes/sun/security/util/SecurityProviderConstants.java +++ b/src/java.base/share/classes/sun/security/util/SecurityProviderConstants.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, 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 @@ -59,6 +59,7 @@ public final class SecurityProviderConstants { public static final int DEF_RSASSA_PSS_KEY_SIZE; public static final int DEF_DH_KEY_SIZE; public static final int DEF_EC_KEY_SIZE; + public static final int DEF_ED_KEY_SIZE; private static final String KEY_LENGTH_PROP = "jdk.security.defaultKeySize"; @@ -70,6 +71,7 @@ public final class SecurityProviderConstants { int rsaSsaPssKeySize = rsaKeySize; // default to same value as RSA int dhKeySize = 2048; int ecKeySize = 256; + int edKeySize = 255; if (keyLengthStr != null) { try { @@ -106,6 +108,8 @@ public final class SecurityProviderConstants { dhKeySize = value; } else if (algoName.equals("EC")) { ecKeySize = value; + } else if (algoName.equalsIgnoreCase("EdDSA")) { + edKeySize = value; } else { if (debug != null) { debug.println("Ignoring unsupported algo in " + @@ -132,5 +136,6 @@ public final class SecurityProviderConstants { DEF_RSASSA_PSS_KEY_SIZE = rsaSsaPssKeySize; DEF_DH_KEY_SIZE = dhKeySize; DEF_EC_KEY_SIZE = ecKeySize; + DEF_ED_KEY_SIZE = edKeySize; } } diff --git a/src/java.base/share/classes/sun/security/util/math/intpoly/IntegerPolynomial.java b/src/java.base/share/classes/sun/security/util/math/intpoly/IntegerPolynomial.java index 543ceeaebcf..123141d7ee1 100644 --- a/src/java.base/share/classes/sun/security/util/math/intpoly/IntegerPolynomial.java +++ b/src/java.base/share/classes/sun/security/util/math/intpoly/IntegerPolynomial.java @@ -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 @@ -157,12 +157,34 @@ public abstract class IntegerPolynomial implements IntegerFieldModuloP { public SmallValue getSmallValue(int value) { int maxMag = 1 << (bitsPerLimb - 1); if (Math.abs(value) >= maxMag) { - throw new IllegalArgumentException( - "max magnitude is " + maxMag); + throw new IllegalArgumentException("max magnitude is " + maxMag); } return new Limb(value); } + protected abstract void reduceIn(long[] c, long v, int i); + + private void reduceHigh(long[] limbs) { + + // conservatively calculate how many reduce operations can be done + // before a carry is needed + int extraBits = 63 - 2 * bitsPerLimb; + int allowedAdds = 1 << extraBits; + int carryPeriod = allowedAdds / numLimbs; + int reduceCount = 0; + for (int i = limbs.length - 1; i >= numLimbs; i--) { + reduceIn(limbs, limbs[i], i); + limbs[i] = 0; + + reduceCount++; + if (reduceCount % carryPeriod == 0) { + carry(limbs, 0, i); + reduceIn(limbs, limbs[i], i); + limbs[i] = 0; + } + } + } + /** * This version of encode takes a ByteBuffer that is properly ordered, and * may extract larger values (e.g. long) from the ByteBuffer for better @@ -179,10 +201,12 @@ public abstract class IntegerPolynomial implements IntegerFieldModuloP { if (requiredLimbs > numLimbs) { long[] temp = new long[requiredLimbs]; encodeSmall(buf, length, highByte, temp); - // encode does a full carry/reduce + reduceHigh(temp); System.arraycopy(temp, 0, result, 0, result.length); + reduce(result); } else { encodeSmall(buf, length, highByte, result); + postEncodeCarry(result); } } @@ -226,8 +250,6 @@ public abstract class IntegerPolynomial implements IntegerFieldModuloP { result[limbIndex++] = curLimbValue; } Arrays.fill(result, limbIndex, result.length, 0); - - postEncodeCarry(result); } protected void encode(byte[] v, int offset, int length, byte highByte, diff --git a/src/java.base/share/classes/sun/security/util/math/intpoly/IntegerPolynomial1305.java b/src/java.base/share/classes/sun/security/util/math/intpoly/IntegerPolynomial1305.java index 27610b56245..acbc28bfdc0 100644 --- a/src/java.base/share/classes/sun/security/util/math/intpoly/IntegerPolynomial1305.java +++ b/src/java.base/share/classes/sun/security/util/math/intpoly/IntegerPolynomial1305.java @@ -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 @@ -156,7 +156,8 @@ public class IntegerPolynomial1305 extends IntegerPolynomial { } } - private void modReduceIn(long[] limbs, int index, long x) { + @Override + protected void reduceIn(long[] limbs, long x, int index) { // this only works when BITS_PER_LIMB * NUM_LIMBS = POWER exactly long reducedValue = (x * SUBTRAHEND); limbs[index - NUM_LIMBS] += reducedValue; @@ -166,13 +167,13 @@ public class IntegerPolynomial1305 extends IntegerPolynomial { protected void finalCarryReduceLast(long[] limbs) { long carry = limbs[numLimbs - 1] >> bitsPerLimb; limbs[numLimbs - 1] -= carry << bitsPerLimb; - modReduceIn(limbs, numLimbs, carry); + reduceIn(limbs, carry, numLimbs); } protected final void modReduce(long[] limbs, int start, int end) { for (int i = start; i < end; i++) { - modReduceIn(limbs, i, limbs[i]); + reduceIn(limbs, limbs[i], i); limbs[i] = 0; } } @@ -203,7 +204,7 @@ public class IntegerPolynomial1305 extends IntegerPolynomial { long carry4 = carryValue(new4); limbs[4] = new4 - (carry4 << BITS_PER_LIMB); - modReduceIn(limbs, 5, carry4); + reduceIn(limbs, carry4, 5); carry(limbs); } diff --git a/src/java.base/share/classes/sun/security/util/math/intpoly/IntegerPolynomial25519.java b/src/java.base/share/classes/sun/security/util/math/intpoly/IntegerPolynomial25519.java index 31188603904..bad4b72b741 100644 --- a/src/java.base/share/classes/sun/security/util/math/intpoly/IntegerPolynomial25519.java +++ b/src/java.base/share/classes/sun/security/util/math/intpoly/IntegerPolynomial25519.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 @@ -51,6 +51,13 @@ public class IntegerPolynomial25519 extends IntegerPolynomial { super(BITS_PER_LIMB, NUM_LIMBS, 1, MODULUS); } + @Override + protected void reduceIn(long[] limbs, long v, int i) { + long t0 = 19 * v; + limbs[i - 10] += (t0 << 5) & LIMB_MASK; + limbs[i - 9] += t0 >> 21; + } + @Override protected void finalCarryReduceLast(long[] limbs) { @@ -81,17 +88,6 @@ public class IntegerPolynomial25519 extends IntegerPolynomial { @Override protected void mult(long[] a, long[] b, long[] r) { - - // Use grade-school multiplication into primitives to avoid the - // temporary array allocation. This is equivalent to the following - // code: - // long[] c = new long[2 * NUM_LIMBS - 1]; - // for(int i = 0; i < NUM_LIMBS; i++) { - // for(int j - 0; j < NUM_LIMBS; j++) { - // c[i + j] += a[i] * b[j] - // } - // } - long c0 = (a[0] * b[0]); long c1 = (a[0] * b[1]) + (a[1] * b[0]); long c2 = (a[0] * b[2]) + (a[1] * b[1]) + (a[2] * b[0]); @@ -172,7 +168,6 @@ public class IntegerPolynomial25519 extends IntegerPolynomial { // carry(0,9) carry(r, 0, 9); } - @Override protected void square(long[] a, long[] r) { diff --git a/src/java.base/share/classes/sun/security/util/math/intpoly/IntegerPolynomial448.java b/src/java.base/share/classes/sun/security/util/math/intpoly/IntegerPolynomial448.java index 70c4f009526..716cb3c1775 100644 --- a/src/java.base/share/classes/sun/security/util/math/intpoly/IntegerPolynomial448.java +++ b/src/java.base/share/classes/sun/security/util/math/intpoly/IntegerPolynomial448.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 @@ -45,16 +45,17 @@ public class IntegerPolynomial448 extends IntegerPolynomial { super(BITS_PER_LIMB, NUM_LIMBS, 1, MODULUS); } - private void modReduceIn(long[] limbs, int index, long x) { - limbs[index - NUM_LIMBS] += x; - limbs[index - NUM_LIMBS / 2] += x; + @Override + protected void reduceIn(long[] limbs, long v, int i) { + limbs[i - 8] += v; + limbs[i - 16] += v; } @Override protected void finalCarryReduceLast(long[] limbs) { long carry = limbs[numLimbs - 1] >> bitsPerLimb; limbs[numLimbs - 1] -= carry << bitsPerLimb; - modReduceIn(limbs, numLimbs, carry); + reduceIn(limbs, carry, numLimbs); } @Override diff --git a/src/java.base/share/classes/sun/security/util/math/intpoly/IntegerPolynomialModBinP.java b/src/java.base/share/classes/sun/security/util/math/intpoly/IntegerPolynomialModBinP.java new file mode 100644 index 00000000000..a0e173b0a63 --- /dev/null +++ b/src/java.base/share/classes/sun/security/util/math/intpoly/IntegerPolynomialModBinP.java @@ -0,0 +1,228 @@ +/* + * 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 sun.security.util.math.intpoly; + +import java.math.BigInteger; +import java.nio.ByteBuffer; + +/** + * The field of integers modulo a binomial prime. This is a general-purpose + * field implementation, that is much slower than more specialized classes + * like IntegerPolynomial25519. It is suitable when only a small number of + * arithmetic operations are required in some field. For example, this class + * can be used for operations on scalars/exponents in signature operations. + * + * This class may only be used for primes of the form 2^a + b. + */ + +public class IntegerPolynomialModBinP extends IntegerPolynomial { + + private final long[] reduceLimbs; + private final int bitOffset; + private final int limbMask; + private final int rightBitOffset; + private final int power; + + public IntegerPolynomialModBinP(int bitsPerLimb, + int numLimbs, + int power, + BigInteger subtrahend) { + super(bitsPerLimb, numLimbs, 1, + BigInteger.valueOf(2).pow(power).subtract(subtrahend)); + + boolean negate = false; + if (subtrahend.compareTo(BigInteger.ZERO) < 0) { + negate = true; + subtrahend = subtrahend.negate(); + } + int reduceLimbsLength = subtrahend.bitLength() / bitsPerLimb + 1; + reduceLimbs = new long[reduceLimbsLength]; + ImmutableElement reduceElem = getElement(subtrahend); + if (negate) { + reduceElem = reduceElem.additiveInverse(); + } + System.arraycopy(reduceElem.limbs, 0, reduceLimbs, 0, + reduceLimbs.length); + + // begin test code + System.out.println("reduce limbs:"); + for (int i = 0; i < reduceLimbs.length; i++) { + System.out.println(i + ":" + reduceLimbs[i]); + } + // end test code + + this.power = power; + this.bitOffset = numLimbs * bitsPerLimb - power; + this.limbMask = -1 >>> (64 - bitsPerLimb); + this.rightBitOffset = bitsPerLimb - bitOffset; + } + + @Override + protected void finalCarryReduceLast(long[] limbs) { + + int extraBits = bitsPerLimb * numLimbs - power; + int highBits = bitsPerLimb - extraBits; + long c = limbs[numLimbs - 1] >> highBits; + limbs[numLimbs - 1] -= c << highBits; + for (int j = 0; j < reduceLimbs.length; j++) { + int reduceBits = power + extraBits - j * bitsPerLimb; + modReduceInBits(limbs, numLimbs, reduceBits, c * reduceLimbs[j]); + } + } + + + /** + * Allow more general (and slower) input conversion that takes a large + * value and reduces it. + */ + @Override + public ImmutableElement getElement(byte[] v, int offset, int length, + byte highByte) { + + long[] result = new long[numLimbs]; + int numHighBits = 32 - Integer.numberOfLeadingZeros(highByte); + int numBits = 8 * length + numHighBits; + int requiredLimbs = (numBits + bitsPerLimb - 1) / bitsPerLimb; + if (requiredLimbs > numLimbs) { + long[] temp = new long[requiredLimbs]; + encode(v, offset, length, highByte, temp); + // encode does a full carry/reduce + System.arraycopy(temp, 0, result, 0, result.length); + } else { + encode(v, offset, length, highByte, result); + } + + return new ImmutableElement(result, 0); + } + + /** + * Multiply a and b, and store the result in c. Requires that + * a.length == b.length == numLimbs and c.length >= 2 * numLimbs - 1. + * It is allowed for a and b to be the same array. + */ + private void multOnly(long[] a, long[] b, long[] c) { + for (int i = 0; i < numLimbs; i++) { + for (int j = 0; j < numLimbs; j++) { + c[i + j] += a[i] * b[j]; + } + } + } + + @Override + protected void mult(long[] a, long[] b, long[] r) { + + long[] c = new long[2 * numLimbs]; + multOnly(a, b, c); + carryReduce(c, r); + } + + private void modReduceInBits(long[] limbs, int index, int bits, long x) { + + if (bits % bitsPerLimb == 0) { + int pos = bits / bitsPerLimb; + limbs[index - pos] += x; + } + else { + int secondPos = bits / (bitsPerLimb); + int bitOffset = (secondPos + 1) * bitsPerLimb - bits; + int rightBitOffset = bitsPerLimb - bitOffset; + limbs[index - (secondPos + 1)] += (x << bitOffset) & limbMask; + limbs[index - secondPos] += x >> rightBitOffset; + } + } + + protected void reduceIn(long[] c, long v, int i) { + + for (int j = 0; j < reduceLimbs.length; j++) { + modReduceInBits(c, i, power - bitsPerLimb * j, reduceLimbs[j] * v); + } + } + + private void carryReduce(long[] c, long[] r) { + + // full carry to prevent overflow during reduce + carry(c); + // Reduce in from all high positions + for (int i = c.length - 1; i >= numLimbs; i--) { + reduceIn(c, c[i], i); + c[i] = 0; + } + // carry on lower positions that possibly carries out one position + carry(c, 0, numLimbs); + // reduce in a single position + reduceIn(c, c[numLimbs], numLimbs); + c[numLimbs] = 0; + // final carry + carry(c, 0, numLimbs - 1); + System.arraycopy(c, 0, r, 0, r.length); + } + + @Override + protected void reduce(long[] a) { + // TODO: optimize this + long[] c = new long[a.length + 2]; + System.arraycopy(a, 0, c, 0, a.length); + carryReduce(c, a); + } + + @Override + protected void square(long[] a, long[] r) { + + long[] c = new long[2 * numLimbs]; + for (int i = 0; i < numLimbs; i++) { + c[2 * i] += a[i] * a[i]; + for (int j = i + 1; j < numLimbs; j++) { + c[i + j] += 2 * a[i] * a[j]; + } + } + + carryReduce(c, r); + + } + + /** + * The field of integers modulo the order of the Curve25519 subgroup + */ + public static class Curve25519OrderField extends IntegerPolynomialModBinP { + + public Curve25519OrderField() { + super(26, 10, 252, + new BigInteger("-27742317777372353535851937790883648493")); + } + } + + /** + * The field of integers modulo the order of the Curve448 subgroup + */ + public static class Curve448OrderField extends IntegerPolynomialModBinP { + + public Curve448OrderField() { + super(28, 16, 446, + new BigInteger("138180668098951153520073867485154268803366" + + "92474882178609894547503885")); + } + } +} diff --git a/src/java.base/share/classes/sun/security/x509/AlgorithmId.java b/src/java.base/share/classes/sun/security/x509/AlgorithmId.java index d2dc54ac4d6..48e4cc19b04 100644 --- a/src/java.base/share/classes/sun/security/x509/AlgorithmId.java +++ b/src/java.base/share/classes/sun/security/x509/AlgorithmId.java @@ -28,11 +28,13 @@ package sun.security.x509; import java.io.*; import java.security.interfaces.RSAKey; import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.EdDSAParameterSpec; import java.security.spec.InvalidParameterSpecException; import java.security.spec.MGF1ParameterSpec; import java.security.spec.PSSParameterSpec; import java.util.*; import java.security.*; +import java.security.interfaces.*; import sun.security.rsa.PSSParameters; import sun.security.util.*; @@ -199,7 +201,8 @@ public class AlgorithmId implements Serializable, DerEncoder { } else { bytes.putNull(); }*/ - if (algid.equals(RSASSA_PSS_oid)) { + if (algid.equals(RSASSA_PSS_oid) || algid.equals(ed448_oid) + || algid.equals(ed25519_oid)) { // RFC 4055 3.3: when an RSASSA-PSS key does not require // parameter validation, field is absent. } else { @@ -588,6 +591,12 @@ public class AlgorithmId implements Serializable, DerEncoder { if (name.equalsIgnoreCase("SHA512withECDSA")) { return AlgorithmId.sha512WithECDSA_oid; } + if (name.equalsIgnoreCase("ED25519")) { + return AlgorithmId.ed25519_oid; + } + if (name.equalsIgnoreCase("ED448")) { + return AlgorithmId.ed448_oid; + } return oidTable().get(name.toUpperCase(Locale.ENGLISH)); } @@ -902,6 +911,11 @@ public class AlgorithmId implements Serializable, DerEncoder { public static final ObjectIdentifier pbeWithSHA1AndRC2_40_oid = ObjectIdentifier.of("1.2.840.113549.1.12.1.6"); + public static final ObjectIdentifier ed25519_oid = + ObjectIdentifier.of("1.3.101.112"); + public static final ObjectIdentifier ed448_oid = + ObjectIdentifier.of("1.3.101.113"); + static { nameTable = new HashMap<>(); nameTable.put(MD5_oid, "MD5"); @@ -921,6 +935,8 @@ public class AlgorithmId implements Serializable, DerEncoder { nameTable.put(DSA_OIW_oid, "DSA"); nameTable.put(EC_oid, "EC"); nameTable.put(ECDH_oid, "ECDH"); + nameTable.put(ed25519_oid, "ED25519"); + nameTable.put(ed448_oid, "ED448"); nameTable.put(AES_oid, "AES"); @@ -1044,6 +1060,8 @@ public class AlgorithmId implements Serializable, DerEncoder { + "withRSA"; case "RSASSA-PSS": return "RSASSA-PSS"; + case "EDDSA": + return edAlgFromKey(k); default: return null; } @@ -1094,6 +1112,8 @@ public class AlgorithmId implements Serializable, DerEncoder { return PSSParamsHolder.PSS_384_ID; } else if (spec == PSSParamsHolder.PSS_512_SPEC) { return PSSParamsHolder.PSS_512_ID; + } else if (spec instanceof EdDSAParameterSpec) { + return AlgorithmId.get(algName); } else { try { AlgorithmParameters result = @@ -1130,6 +1150,14 @@ public class AlgorithmId implements Serializable, DerEncoder { } } + private static String edAlgFromKey(PrivateKey k) { + if (k instanceof EdECPrivateKey) { + EdECPrivateKey edKey = (EdECPrivateKey) k; + return edKey.getParams().getName(); + } + return "EdDSA"; + } + // Values from SP800-57 part 1 rev 4 tables 2 and 3 private static String ecStrength (int bitLength) { if (bitLength >= 512) { // 256 bits of strength diff --git a/src/jdk.crypto.ec/share/classes/sun/security/ec/ParametersMap.java b/src/jdk.crypto.ec/share/classes/sun/security/ec/ParametersMap.java new file mode 100644 index 00000000000..c5af8fe3234 --- /dev/null +++ b/src/jdk.crypto.ec/share/classes/sun/security/ec/ParametersMap.java @@ -0,0 +1,156 @@ +/* + * 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 sun.security.ec; + +import sun.security.util.ObjectIdentifier; +import sun.security.x509.AlgorithmId; + +import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.NamedParameterSpec; +import java.util.Collections; +import java.util.Map; +import java.util.HashMap; +import java.util.Optional; +import java.util.function.Function; +import java.util.function.Supplier; + +public class ParametersMap { + + private Map sizeMap = new HashMap(); + private Map oidMap = + new HashMap(); + private Map nameMap = new HashMap(); + + + public void fix() { + + sizeMap = Collections.unmodifiableMap(sizeMap); + oidMap = Collections.unmodifiableMap(oidMap); + nameMap = Collections.unmodifiableMap(nameMap); + } + + public void put(String name, ObjectIdentifier oid, int size, T params) { + nameMap.put(name.toLowerCase(), params); + oidMap.put(oid, params); + sizeMap.put(size, params); + } + + public Optional getByOid(ObjectIdentifier id) { + return Optional.ofNullable(oidMap.get(id)); + } + public Optional getBySize(int size) { + return Optional.ofNullable(sizeMap.get(size)); + } + public Optional getByName(String name) { + return Optional.ofNullable(nameMap.get(name.toLowerCase())); + } + + // Utility method that is used by the methods below to handle exception + // suppliers + private static + Supplier apply(final Function func, final A a) { + return new Supplier() { + @Override + public B get() { + return func.apply(a); + } + }; + } + + /** + * Get parameters by key size, or throw an exception if no parameters are + * defined for the specified key size. This method is used in several + * contexts that should throw different exceptions when the parameters + * are not found. The first argument is a function that produces the + * desired exception. + * + * @param exception a function that produces an exception from a string + * @param size the desired key size + * @param the type of exception that is thrown + * @return the parameters for the specified key size + * @throws T when suitable parameters do not exist + */ + public + + T getBySize(Function exception, + int size) throws E { + + Optional paramsOpt = getBySize(size); + return paramsOpt.orElseThrow( + apply(exception, "Unsupported size: " + size)); + } + + /** + * Get parameters by algorithm ID, or throw an exception if no + * parameters are defined for the specified ID. This method is used in + * several contexts that should throw different exceptions when the + * parameters are not found. The first argument is a function that produces + * the desired exception. + * + * @param exception a function that produces an exception from a string + * @param algId the algorithm ID + * @param the type of exception that is thrown + * @return the parameters for the specified algorithm ID + * @throws E when suitable parameters do not exist + */ + public + + T get(Function exception, + AlgorithmId algId) throws E { + + Optional paramsOpt = getByOid(algId.getOID()); + return paramsOpt.orElseThrow( + apply(exception, "Unsupported OID: " + algId.getOID())); + } + + /** + * Get parameters by algorithm parameter spec, or throw an exception if no + * parameters are defined for the spec. This method is used in + * several contexts that should throw different exceptions when the + * parameters are not found. The first argument is a function that produces + * the desired exception. + * + * @param exception a function that produces an exception from a string + * @param params the algorithm parameters spec + * @param the type of exception that is thrown + * @return the parameters for the spec + * @throws E when suitable parameters do not exist + */ + public + + T get(Function exception, + AlgorithmParameterSpec params) throws E { + + if (params instanceof NamedParameterSpec) { + NamedParameterSpec namedParams = (NamedParameterSpec) params; + Optional paramsOpt = getByName(namedParams.getName()); + return paramsOpt.orElseThrow( + apply(exception, "Unsupported name: " + namedParams.getName())); + } else { + throw exception.apply("Only NamedParameterSpec is supported."); + } + } +} diff --git a/src/jdk.crypto.ec/share/classes/sun/security/ec/SunEC.java b/src/jdk.crypto.ec/share/classes/sun/security/ec/SunEC.java index 39dfeaa5cf5..e34517c9c2a 100644 --- a/src/jdk.crypto.ec/share/classes/sun/security/ec/SunEC.java +++ b/src/jdk.crypto.ec/share/classes/sun/security/ec/SunEC.java @@ -37,6 +37,11 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.regex.Pattern; + +import sun.security.ec.ed.EdDSAAlgorithmParameters; +import sun.security.ec.ed.EdDSAKeyFactory; +import sun.security.ec.ed.EdDSAKeyPairGenerator; +import sun.security.ec.ed.EdDSASignature; import sun.security.util.CurveDB; import sun.security.util.NamedCurve; @@ -116,6 +121,15 @@ public final class SunEC extends Provider { String algo = getAlgorithm(); try { if (type.equals("Signature")) { + + if (algo.equalsIgnoreCase("EdDSA")) { + return new EdDSASignature(); + } else if (algo.equalsIgnoreCase("Ed25519")) { + return new EdDSASignature.Ed25519(); + } else if (algo.equalsIgnoreCase("Ed448")) { + return new EdDSASignature.Ed448(); + } + boolean inP1363 = algo.endsWith("inP1363Format"); if (inP1363) { algo = algo.substring(0, algo.length() - 13); @@ -148,6 +162,12 @@ public final class SunEC extends Provider { return new XDHKeyFactory.X25519(); } else if (algo.equals("X448")) { return new XDHKeyFactory.X448(); + } else if (algo.equalsIgnoreCase("EdDSA")) { + return new EdDSAKeyFactory(); + } else if (algo.equalsIgnoreCase("Ed25519")) { + return new EdDSAKeyFactory.Ed25519(); + } else if (algo.equalsIgnoreCase("Ed448")) { + return new EdDSAKeyFactory.Ed448(); } } else if (type.equals("AlgorithmParameters")) { if (algo.equals("EC")) { @@ -162,6 +182,12 @@ public final class SunEC extends Provider { return new XDHKeyPairGenerator.X25519(); } else if (algo.equals("X448")) { return new XDHKeyPairGenerator.X448(); + } else if (algo.equalsIgnoreCase("EdDSA")) { + return new EdDSAKeyPairGenerator(); + } else if (algo.equalsIgnoreCase("Ed25519")) { + return new EdDSAKeyPairGenerator.Ed25519(); + } else if (algo.equalsIgnoreCase("Ed448")) { + return new EdDSAKeyPairGenerator.Ed448(); } } else if (type.equals("KeyAgreement")) { if (algo.equals("ECDH")) { @@ -184,8 +210,7 @@ public final class SunEC extends Provider { } public SunEC() { - super("SunEC", PROVIDER_VER, - "Sun Elliptic Curve provider (EC, ECDSA, ECDH)"); + super("SunEC", PROVIDER_VER, "Sun Elliptic Curve provider"); AccessController.doPrivileged(new PrivilegedAction() { public Void run() { putEntries(); @@ -255,6 +280,7 @@ public final class SunEC extends Provider { apAttrs)); putXDHEntries(); + putEdDSAEntries(); /* * Signature engines @@ -350,4 +376,39 @@ public final class SunEC extends Provider { new String[]{"1.3.101.111", "OID.1.3.101.111"}, ATTRS)); } + + private void putEdDSAEntries() { + + HashMap ATTRS = new HashMap<>(1); + ATTRS.put("ImplementedIn", "Software"); + + /* EdDSA does not require native implementation */ + putService(new ProviderService(this, "KeyFactory", + "EdDSA", "sun.security.ec.ed.EdDSAKeyFactory", null, ATTRS)); + putService(new ProviderService(this, "KeyFactory", + "Ed25519", "sun.security.ec.ed.EdDSAKeyFactory.Ed25519", + new String[]{"1.3.101.112", "OID.1.3.101.112"}, ATTRS)); + putService(new ProviderService(this, "KeyFactory", + "Ed448", "sun.security.ec.ed.EdDSAKeyFactory.Ed448", + new String[]{"1.3.101.113", "OID.1.3.101.113"}, ATTRS)); + + putService(new ProviderService(this, "KeyPairGenerator", + "EdDSA", "sun.security.ec.ed.EdDSAKeyPairGenerator", null, ATTRS)); + putService(new ProviderService(this, "KeyPairGenerator", + "Ed25519", "sun.security.ec.ed.EdDSAKeyPairGenerator.Ed25519", + new String[]{"1.3.101.112", "OID.1.3.101.112"}, ATTRS)); + putService(new ProviderService(this, "KeyPairGenerator", + "Ed448", "sun.security.ec.ed.EdDSAKeyPairGenerator.Ed448", + new String[]{"1.3.101.113", "OID.1.3.101.113"}, ATTRS)); + + putService(new ProviderService(this, "Signature", + "EdDSA", "sun.security.ec.ed.EdDSASignature", null, ATTRS)); + putService(new ProviderService(this, "Signature", + "Ed25519", "sun.security.ec.ed.EdDSASignature.Ed25519", + new String[]{"1.3.101.112", "OID.1.3.101.112"}, ATTRS)); + putService(new ProviderService(this, "Signature", + "Ed448", "sun.security.ec.ed.EdDSASignature.Ed448", + new String[]{"1.3.101.113", "OID.1.3.101.113"}, ATTRS)); + + } } diff --git a/src/jdk.crypto.ec/share/classes/sun/security/ec/XECParameters.java b/src/jdk.crypto.ec/share/classes/sun/security/ec/XECParameters.java index 728ceef5e8e..b926aaa0064 100644 --- a/src/jdk.crypto.ec/share/classes/sun/security/ec/XECParameters.java +++ b/src/jdk.crypto.ec/share/classes/sun/security/ec/XECParameters.java @@ -29,18 +29,17 @@ import java.io.IOException; import java.math.BigInteger; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.NamedParameterSpec; -import java.util.Collections; import java.util.Map; import java.util.HashMap; -import java.util.Optional; import java.util.function.Function; -import java.util.function.Supplier; import sun.security.util.ObjectIdentifier; import sun.security.x509.AlgorithmId; public class XECParameters { + static ParametersMap namedParams = new ParametersMap<>(); + // Naming/identification parameters private final ObjectIdentifier oid; private final String name; @@ -106,10 +105,6 @@ public class XECParameters { return name; } - private static final Map SIZE_MAP; - private static final Map OID_MAP; - private static final Map NAME_MAP; - static { final BigInteger TWO = BigInteger.valueOf(2); @@ -140,9 +135,7 @@ public class XECParameters { // Unable to set X448 parameters---it will be disabled } - SIZE_MAP = Collections.unmodifiableMap(bySize); - OID_MAP = Collections.unmodifiableMap(byOid); - NAME_MAP = Collections.unmodifiableMap(byName); + namedParams.fix(); } private static void addParameters(int bits, BigInteger p, int a24, @@ -154,110 +147,36 @@ public class XECParameters { ObjectIdentifier oid = new ObjectIdentifier(objectId); XECParameters params = new XECParameters(bits, p, a24, basePoint, logCofactor, oid, name); - bySize.put(bits, params); - byOid.put(oid, params); - byName.put(name.toLowerCase(), params); - } - - public static Optional getByOid(ObjectIdentifier id) { - return Optional.ofNullable(OID_MAP.get(id)); - } - public static Optional getBySize(int size) { - return Optional.ofNullable(SIZE_MAP.get(size)); - } - public static Optional getByName(String name) { - return Optional.ofNullable(NAME_MAP.get(name.toLowerCase())); + namedParams.put(name.toLowerCase(), oid, bits, params); } boolean oidEquals(XECParameters other) { return oid.equals(other.getOid()); } - // Utility method that is used by the methods below to handle exception - // suppliers - private static - Supplier apply(final Function func, final A a) { - return new Supplier() { - @Override - public B get() { - return func.apply(a); - } - }; - } - /** - * Get parameters by key size, or throw an exception if no parameters are - * defined for the specified key size. This method is used in several - * contexts that should throw different exceptions when the parameters - * are not found. The first argument is a function that produces the - * desired exception. - * - * @param exception a function that produces an exception from a string - * @param size the desired key size - * @param the type of exception that is thrown - * @return the parameters for the specified key size - * @throws T when suitable parameters do not exist - */ public static XECParameters getBySize(Function exception, int size) throws T { - Optional xecParams = getBySize(size); - return xecParams.orElseThrow( - apply(exception, "Unsupported size: " + size)); + return namedParams.getBySize(exception, size); } - /** - * Get parameters by algorithm ID, or throw an exception if no - * parameters are defined for the specified ID. This method is used in - * several contexts that should throw different exceptions when the - * parameters are not found. The first argument is a function that produces - * the desired exception. - * - * @param exception a function that produces an exception from a string - * @param algId the algorithm ID - * @param the type of exception that is thrown - * @return the parameters for the specified algorithm ID - * @throws T when suitable parameters do not exist - */ public static XECParameters get(Function exception, AlgorithmId algId) throws T { - Optional xecParams = getByOid(algId.getOID()); - return xecParams.orElseThrow( - apply(exception, "Unsupported OID: " + algId.getOID())); + return namedParams.get(exception, algId); } - /** - * Get parameters by algorithm parameter spec, or throw an exception if no - * parameters are defined for the spec. This method is used in - * several contexts that should throw different exceptions when the - * parameters are not found. The first argument is a function that produces - * the desired exception. - * - * @param exception a function that produces an exception from a string - * @param params the algorithm parameters spec - * @param the type of exception that is thrown - * @return the parameters for the spec - * @throws T when suitable parameters do not exist - */ public static XECParameters get(Function exception, AlgorithmParameterSpec params) throws T { - if (params instanceof NamedParameterSpec) { - NamedParameterSpec namedParams = (NamedParameterSpec) params; - Optional xecParams = - getByName(namedParams.getName()); - return xecParams.orElseThrow( - apply(exception, "Unsupported name: " + namedParams.getName())); - } else { - throw exception.apply("Only NamedParameterSpec is supported."); - } + return namedParams.get(exception, params); } } diff --git a/src/jdk.crypto.ec/share/classes/sun/security/ec/ed/Ed25519Operations.java b/src/jdk.crypto.ec/share/classes/sun/security/ec/ed/Ed25519Operations.java new file mode 100644 index 00000000000..48ff4f644cf --- /dev/null +++ b/src/jdk.crypto.ec/share/classes/sun/security/ec/ed/Ed25519Operations.java @@ -0,0 +1,214 @@ +/* + * 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 sun.security.ec.ed; + +import sun.security.ec.point.*; +import sun.security.util.math.*; + +import java.math.BigInteger; +import java.util.function.Function; + +/* + * Elliptic curve point arithmetic, decoding, and other operations for the + * family of curves including edwards25519 and its related group. Though the + * operations in this class are optimized for edwards25519, they are correct + * for any twisted Edwards curve ax^2 + y^2 = 1 + dx^2y^2 (mod p) with the + * following properties: + * 1) a = -1 (mod p) + * 2) a is square (mod p) + * 3) d is not square (mod p) + */ +public class Ed25519Operations extends EdECOperations { + + private final SmallValue two; + private final ImmutableIntegerModuloP d; + private final ExtendedHomogeneousPoint.Immutable basePoint; + + private static final BigInteger TWO = BigInteger.valueOf(2); + private static final BigInteger SEVEN = BigInteger.valueOf(7); + private final BigInteger sizeMinus5; + + public Ed25519Operations(ImmutableIntegerModuloP d, BigInteger baseX, + BigInteger baseY) { + + this.two = d.getField().getSmallValue(2); + this.d = d; + this.basePoint = of(new AffinePoint( + d.getField().getElement(baseX), d.getField().getElement(baseY) + )); + this.sizeMinus5 = + d.getField().getSize().subtract(BigInteger.valueOf(5)); + } + + @Override + public Point basePointMultiply(byte[] scalar) { + return setProduct(basePoint.mutable(), scalar); + } + + @Override + protected ExtendedHomogeneousPoint.Immutable getNeutral() { + IntegerFieldModuloP field = d.getField(); + return new ExtendedHomogeneousPoint.Immutable(field.get0(), + field.get1(), field.get0(), field.get1()); + } + + @Override + protected MutablePoint setSum(MutablePoint p1, MutablePoint p2, + MutableIntegerModuloP t1, + MutableIntegerModuloP t2, + MutableIntegerModuloP t3) { + + ExtendedHomogeneousPoint.Mutable ehp1 = + (ExtendedHomogeneousPoint.Mutable) p1; + ExtendedHomogeneousPoint.Mutable ehp2 = + (ExtendedHomogeneousPoint.Mutable) p2; + return setSum(ehp1, ehp2, t1, t2, t3); + } + + @Override + protected MutablePoint setDouble(MutablePoint p, MutableIntegerModuloP t1, + MutableIntegerModuloP t2) { + + ExtendedHomogeneousPoint.Mutable ehp = + (ExtendedHomogeneousPoint.Mutable) p; + return setDouble(ehp, t1, t2); + } + + @Override + public ExtendedHomogeneousPoint.Immutable of(AffinePoint p) { + return new ExtendedHomogeneousPoint.Immutable(p.getX(), p.getY(), + p.getX().multiply(p.getY()), p.getX().getField().get1()); + } + + @Override + public + AffinePoint decodeAffinePoint(Function exception, + int xLSB, IntegerModuloP y) throws T { + + IntegerFieldModuloP field = d.getField(); + BigInteger p = field.getSize(); + ImmutableIntegerModuloP y2 = y.square(); + ImmutableIntegerModuloP u = y2.subtract(field.get1()); + MutableIntegerModuloP v = d.mutable().setProduct(y2) + .setSum(field.get1()); + + MutableIntegerModuloP x = + u.mutable().setProduct(v.pow(BigInteger.valueOf(3))); + ImmutableIntegerModuloP uv7pow = + u.multiply(v.pow(SEVEN)).pow(sizeMinus5.shiftRight(3)); + x.setProduct(uv7pow); + + v.setProduct(x).setProduct(x); + // v now holds vx^2 + BigInteger bigVX2 = v.asBigInteger(); + if (bigVX2.equals(u.asBigInteger())) { + // do nothing---x is correct + } else if (bigVX2.equals(u.additiveInverse().asBigInteger())) { + BigInteger exp = p.subtract(BigInteger.ONE).shiftRight(2); + IntegerModuloP twoPow = field.getElement(TWO.modPow(exp, p)); + x.setProduct(twoPow); + } else { + throw exception.apply("Invalid point"); + } + + if (x.asBigInteger().equals(BigInteger.ZERO) && xLSB == 1) { + throw exception.apply("Invalid point"); + } + + if (xLSB != x.asBigInteger().mod(BigInteger.valueOf(2)).intValue()) { + x.setAdditiveInverse(); + } + + return new AffinePoint(x.fixed(), y.fixed()); + } + + ExtendedHomogeneousPoint.Mutable setSum( + ExtendedHomogeneousPoint.Mutable p1, + ExtendedHomogeneousPoint.Mutable p2, + MutableIntegerModuloP t1, + MutableIntegerModuloP t2, + MutableIntegerModuloP t3) { + + t1.setValue(p2.getY()).setDifference(p2.getX()); + // t1 holds y2 - x2 + t2.setValue(p1.getY()).setDifference(p1.getX()).setProduct(t1); + // t2 holds A = (y1 - x1) * (y2 - x2) + t1.setValue(p2.getY()).setSum(p2.getX()); + // t1 holds y2 + x2 + t3.setValue(p1.getY()).setSum(p1.getX()).setProduct(t1); + // t3 holds B = (y1 + x1) * (y2 + x2) + p1.getX().setValue(t3).setDifference(t2); + // x holds E = B - A + t3.setSum(t2); + // t3 holds H = B + A, t2 is unused + t2.setValue(d).setSum(d).setProduct(p1.getT()).setProduct(p2.getT()); + // t2 holds C + t1.setValue(p1.getZ()).setProduct(p2.getZ()).setProduct(two); + // t1 holds D + p1.getY().setValue(t1).setSum(t2); + // y holds G + p1.getZ().setValue(t1).setDifference(t2); + // z holds F + + p1.getT().setValue(p1.getX()).setProduct(t3); + p1.getX().setProduct(p1.getZ()); + p1.getZ().setProduct(p1.getY()); + p1.getY().setProduct(t3); + + return p1; + + } + + protected ExtendedHomogeneousPoint.Mutable setDouble( + ExtendedHomogeneousPoint.Mutable p, + MutableIntegerModuloP t1, MutableIntegerModuloP t2) { + + t1.setValue(p.getX()).setSum(p.getY()).setSquare(); + // t1 holds (x + y)^2 + p.getX().setSquare(); + // x = A = x^2 + p.getY().setSquare(); + // y = B = y^2 + t2.setValue(p.getX()).setSum(p.getY()).setReduced(); + // t2 holds H + p.getZ().setSquare().setProduct(two); + // z holds C + + p.getT().setValue(t2).setDifference(t1); + // t holds E + t1.setValue(p.getX()).setDifference(p.getY()).setReduced(); + // t1 holds G + + p.getZ().setSum(t1); + // z holds F + + p.getX().setValue(p.getT()).setProduct(p.getZ()); + p.getY().setValue(t1).setProduct(t2); + p.getT().setProduct(t2); + p.getZ().setProduct(t1); + + return p; + } +} diff --git a/src/jdk.crypto.ec/share/classes/sun/security/ec/ed/Ed448Operations.java b/src/jdk.crypto.ec/share/classes/sun/security/ec/ed/Ed448Operations.java new file mode 100644 index 00000000000..5bf8c372885 --- /dev/null +++ b/src/jdk.crypto.ec/share/classes/sun/security/ec/ed/Ed448Operations.java @@ -0,0 +1,201 @@ +/* + * 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 sun.security.ec.ed; + +import sun.security.ec.point.*; +import sun.security.util.math.*; + +import java.math.BigInteger; +import java.util.function.Function; + +// Arithmetic works for a=1 and non-square d +/* + * Elliptic curve point arithmetic, decoding, and other operations for the + * family of curves including edwards448 and its related group. Though the + * operations in this class are optimized for edwards448, they are correct + * for any untwisted Edwards curve x^2 + y^2 = 1 + dx^2y^2 (mod p) where + * d is not square (mod p). + */ +public class Ed448Operations extends EdECOperations { + + private final SmallValue two; + private final ImmutableIntegerModuloP d; + private final ProjectivePoint.Immutable basePoint; + + private static final BigInteger TWO = BigInteger.valueOf(2); + private static final BigInteger THREE = BigInteger.valueOf(3); + private static final BigInteger FIVE = BigInteger.valueOf(5); + private final BigInteger sizeMinus3; + + public Ed448Operations(ImmutableIntegerModuloP d, BigInteger baseX, + BigInteger baseY) { + + this.two = d.getField().getSmallValue(2); + this.d = d; + this.basePoint = of(new AffinePoint( + d.getField().getElement(baseX), + d.getField().getElement(baseY) + )); + + this.sizeMinus3 = d.getField().getSize().subtract(THREE); + } + + @Override + public Point basePointMultiply(byte[] scalar) { + return setProduct(basePoint.mutable(), scalar); + } + + @Override + protected ProjectivePoint.Immutable getNeutral() { + IntegerFieldModuloP field = d.getField(); + return new ProjectivePoint.Immutable(field.get0(), field.get1(), + field.get1()); + } + + @Override + protected MutablePoint setSum(MutablePoint p1, MutablePoint p2, + MutableIntegerModuloP t1, + MutableIntegerModuloP t2, + MutableIntegerModuloP t3) { + + ProjectivePoint.Mutable ehp1 = (ProjectivePoint.Mutable) p1; + ProjectivePoint.Mutable ehp2 = (ProjectivePoint.Mutable) p2; + return setSum(ehp1, ehp2, t1, t2, t3); + } + + @Override + protected MutablePoint setDouble(MutablePoint p, MutableIntegerModuloP t1, + MutableIntegerModuloP t2) { + + ProjectivePoint.Mutable ehp = (ProjectivePoint.Mutable) p; + return setDouble(ehp, t1, t2); + } + + @Override + public ProjectivePoint.Immutable of(AffinePoint p) { + return new ProjectivePoint.Immutable(p.getX(), p.getY(), + p.getX().getField().get1()); + } + + @Override + public + AffinePoint decodeAffinePoint(Function exception, int xLSB, + IntegerModuloP y) throws T { + + ImmutableIntegerModuloP y2 = y.square(); + ImmutableIntegerModuloP u = y2.subtract(d.getField().get1()); + MutableIntegerModuloP v = d.mutable().setProduct(y2) + .setDifference(d.getField().get1()); + + IntegerModuloP u5v3pow = u.pow(FIVE).multiply(v.pow(THREE)) + .pow(sizeMinus3.shiftRight(2)); + + MutableIntegerModuloP x = v.mutable().setProduct(u.pow(THREE)) + .setProduct(u5v3pow); + + v.setProduct(x).setProduct(x); + // v now holds vx^2 + if (v.asBigInteger().equals(u.asBigInteger())) { + // x is correct + } else { + throw exception.apply("Invalid point"); + } + + if (x.asBigInteger().equals(BigInteger.ZERO) && xLSB == 1) { + throw exception.apply("Invalid point"); + } + + if (xLSB != x.asBigInteger().mod(TWO).intValue()) { + x.setAdditiveInverse(); + } + + return new AffinePoint(x.fixed(), y.fixed()); + } + + ProjectivePoint.Mutable setSum( + ProjectivePoint.Mutable p1, + ProjectivePoint.Mutable p2, + MutableIntegerModuloP t1, + MutableIntegerModuloP t2, + MutableIntegerModuloP t3) { + + t1.setValue(p1.getX()).setProduct(p2.getX()); + // t1 holds C + t2.setValue(p2.getX()).setSum(p2.getY()); + p1.getX().setSum(p1.getY()).setProduct(t2); + // x holds H + p1.getZ().setProduct(p2.getZ()); + // z holds A + p1.getY().setProduct(p2.getY()); + // y holds D + + t3.setValue(d).setProduct(t1).setProduct(p1.getY()); + // t3 holds E + // do part of the final calculation of x and y to free up t1 + p1.getX().setDifference(t1).setReduced().setDifference(p1.getY()); + p1.getY().setDifference(t1); + t1.setValue(p1.getZ()).setSquare(); + // t2 holds B + + t2.setValue(t1).setDifference(t3); + // t2 holds F + t1.setSum(t3); + // t1 holds G + + p1.getX().setProduct(t2).setProduct(p1.getZ()); + p1.getY().setProduct(t1).setProduct(p1.getZ()); + p1.getZ().setValue(t2.multiply(t1)); + + return p1; + + } + + protected ProjectivePoint.Mutable setDouble(ProjectivePoint.Mutable p, + MutableIntegerModuloP t1, + MutableIntegerModuloP t2) { + + t2.setValue(p.getX()).setSquare(); + // t2 holds C + p.getX().setSum(p.getY()).setSquare(); + // x holds B + p.getY().setSquare(); + // y holds D + p.getZ().setSquare(); + // z holds H + + t1.setValue(t2).setSum(p.getY()).setReduced(); + // t1 holds E + t2.setDifference(p.getY()); + p.getY().setValue(t1).setProduct(t2); + + p.getZ().setProduct(two); + p.getZ().setAdditiveInverse().setSum(t1); + // z holds J + p.getX().setDifference(t1).setProduct(p.getZ()); + p.getZ().setProduct(t1); + + return p; + } +} diff --git a/src/jdk.crypto.ec/share/classes/sun/security/ec/ed/EdDSAAlgorithmParameters.java b/src/jdk.crypto.ec/share/classes/sun/security/ec/ed/EdDSAAlgorithmParameters.java new file mode 100644 index 00000000000..e8a9e22240c --- /dev/null +++ b/src/jdk.crypto.ec/share/classes/sun/security/ec/ed/EdDSAAlgorithmParameters.java @@ -0,0 +1,107 @@ +/* + * 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 sun.security.ec.ed; + +import java.io.IOException; +import java.security.AlgorithmParametersSpi; +import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.ECParameterSpec; +import java.security.spec.EdDSAParameterSpec; +import java.security.spec.InvalidParameterSpecException; + +/** + * This AlgorithmParametersSpi only supports NamedParameterSpec. + * EdDSAParameterSpec is not support because there is not ASN.1 format + */ + +public class EdDSAAlgorithmParameters extends AlgorithmParametersSpi { + + EdDSAParameterSpec edspec; + + // If no curve is provide, wait engineInit() to provide one. + public EdDSAAlgorithmParameters() { + } + + /** + * NamedParameterSpec can only be used if curve was not specified + * as part of getInstance(EdDSA). If the curve was used, engineInit will + * throws an exception for being already initialized. + * EdDSAParameterSpec is not support because there is not ASN.1 format + * + * @param paramSpec NamedParameterSpec curve. + * + * @throws InvalidParameterSpecException + */ + @Override + protected void engineInit(AlgorithmParameterSpec paramSpec) + throws InvalidParameterSpecException { + if (paramSpec instanceof EdDSAParameterSpec) { + edspec = (EdDSAParameterSpec)paramSpec; + return; + } + throw new InvalidParameterSpecException( + "Unknown AlgorithmParameterSpec"); + } + + @Override + protected void engineInit(byte[] params) throws IOException { + throw new IOException( + "EdDSA does not support parameters as a byte array."); + } + + @Override + protected void engineInit(byte[] params, String format) throws IOException { + engineInit(params); + } + + @Override + protected T engineGetParameterSpec( + Class paramSpec) throws InvalidParameterSpecException { + + if (paramSpec.isAssignableFrom(ECParameterSpec.class)) { + return paramSpec.cast(edspec); + } + throw new InvalidParameterSpecException( + "Only EDDSAParameterSpec supported."); + } + + @Override + protected byte[] engineGetEncoded() throws IOException { + throw new IOException( + "EdDSA does not support parameters as a byte array."); + } + + @Override + protected byte[] engineGetEncoded(String format) throws IOException { + throw new IOException( + "EdDSA does not support parameters as a byte array."); + } + + @Override + protected String engineToString() { + return edspec.toString(); + } +} diff --git a/src/jdk.crypto.ec/share/classes/sun/security/ec/ed/EdDSAKeyFactory.java b/src/jdk.crypto.ec/share/classes/sun/security/ec/ed/EdDSAKeyFactory.java new file mode 100644 index 00000000000..6b9d26f242b --- /dev/null +++ b/src/jdk.crypto.ec/share/classes/sun/security/ec/ed/EdDSAKeyFactory.java @@ -0,0 +1,236 @@ +/* + * 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 sun.security.ec.ed; + +import java.security.KeyFactorySpi; +import java.security.Key; +import java.security.PublicKey; +import java.security.PrivateKey; +import java.security.InvalidKeyException; +import java.security.ProviderException; +import java.security.interfaces.*; +import java.security.spec.*; +import java.util.function.Function; + +public class EdDSAKeyFactory extends KeyFactorySpi { + + private EdDSAParameters lockedParams = null; + + public EdDSAKeyFactory() { + // do nothing + } + + protected EdDSAKeyFactory(NamedParameterSpec paramSpec) { + lockedParams = EdDSAParameters.get(ProviderException::new, paramSpec); + } + + @Override + protected Key engineTranslateKey(Key key) throws InvalidKeyException { + + if (key == null) { + throw new InvalidKeyException("Key must not be null"); + } + + if (key instanceof EdECKey) { + EdECKey edKey = (EdECKey) key; + EdDSAParameters params = EdDSAParameters.get( + InvalidKeyException::new, edKey.getParams()); + checkLockedParams(InvalidKeyException::new, params); + + if (edKey instanceof EdECPublicKey) { + EdECPublicKey publicKey = (EdECPublicKey) edKey; + return new EdDSAPublicKeyImpl(params, publicKey.getPoint()); + } else if (edKey instanceof EdECPrivateKey) { + EdECPrivateKey privateKey = (EdECPrivateKey) edKey; + byte[] privateKeyBytes = privateKey.getBytes().orElseThrow( + () -> new InvalidKeyException("No private key data")); + return new EdDSAPrivateKeyImpl(params, privateKeyBytes); + } else { + throw new InvalidKeyException("Unsupported EdECKey subclass"); + } + } else if (key instanceof PublicKey && + key.getFormat().equals("X.509")) { + EdDSAPublicKeyImpl result = + new EdDSAPublicKeyImpl(key.getEncoded()); + checkLockedParams(InvalidKeyException::new, result.getParams()); + return result; + } else if (key instanceof PrivateKey && + key.getFormat().equals("PKCS#8")) { + EdDSAPrivateKeyImpl result = + new EdDSAPrivateKeyImpl(key.getEncoded()); + checkLockedParams(InvalidKeyException::new, result.getParams()); + return result; + } else { + throw new InvalidKeyException("Unsupported key type or format"); + } + } + + private + + void checkLockedParams(Function exception, + NamedParameterSpec spec) throws T { + + EdDSAParameters params = EdDSAParameters.get(exception, spec); + checkLockedParams(exception, params); + } + + private + + void checkLockedParams(Function exception, + EdDSAParameters params) throws T { + + if (lockedParams != null && lockedParams != params) { + throw exception.apply("Parameters must be " + + lockedParams.getName()); + } + } + + @Override + protected PublicKey engineGeneratePublic(KeySpec keySpec) + throws InvalidKeySpecException { + + try { + return generatePublicImpl(keySpec); + } catch (InvalidKeyException ex) { + throw new InvalidKeySpecException(ex); + } + } + + @Override + protected PrivateKey engineGeneratePrivate(KeySpec keySpec) + throws InvalidKeySpecException { + + try { + return generatePrivateImpl(keySpec); + } catch (InvalidKeyException ex) { + throw new InvalidKeySpecException(ex); + } + } + + + private PublicKey generatePublicImpl(KeySpec keySpec) + throws InvalidKeyException, InvalidKeySpecException { + + if (keySpec instanceof X509EncodedKeySpec) { + X509EncodedKeySpec x509Spec = (X509EncodedKeySpec) keySpec; + EdDSAPublicKeyImpl result = + new EdDSAPublicKeyImpl(x509Spec.getEncoded()); + checkLockedParams(InvalidKeySpecException::new, + result.getParams()); + return result; + } else if (keySpec instanceof EdECPublicKeySpec) { + EdECPublicKeySpec publicKeySpec = (EdECPublicKeySpec) keySpec; + EdDSAParameters params = EdDSAParameters.get( + InvalidKeySpecException::new, publicKeySpec.getParams()); + checkLockedParams(InvalidKeySpecException::new, params); + return new EdDSAPublicKeyImpl(params, publicKeySpec.getPoint()); + } else { + throw new InvalidKeySpecException( + "Only X509EncodedKeySpec and EdECPublicKeySpec are supported"); + } + } + + private PrivateKey generatePrivateImpl(KeySpec keySpec) + throws InvalidKeyException, InvalidKeySpecException { + + if (keySpec instanceof PKCS8EncodedKeySpec) { + PKCS8EncodedKeySpec pkcsSpec = (PKCS8EncodedKeySpec) keySpec; + EdDSAPrivateKeyImpl result = + new EdDSAPrivateKeyImpl(pkcsSpec.getEncoded()); + checkLockedParams(InvalidKeySpecException::new, + result.getParams()); + return result; + } else if (keySpec instanceof EdECPrivateKeySpec) { + EdECPrivateKeySpec privateKeySpec = (EdECPrivateKeySpec) keySpec; + EdDSAParameters params = EdDSAParameters.get( + InvalidKeySpecException::new, privateKeySpec.getParams()); + checkLockedParams(InvalidKeySpecException::new, params); + return new EdDSAPrivateKeyImpl(params, privateKeySpec.getBytes()); + } else { + throw new InvalidKeySpecException( + "Only PKCS8EncodedKeySpec and EdECPrivateKeySpec supported"); + } + } + + protected T engineGetKeySpec(Key key, Class keySpec) + throws InvalidKeySpecException { + + if (key instanceof EdECPublicKey) { + checkLockedParams(InvalidKeySpecException::new, + ((EdECPublicKey) key).getParams()); + + if (X509EncodedKeySpec.class.isAssignableFrom(keySpec)) { + if (!key.getFormat().equals("X.509")) { + throw new InvalidKeySpecException("Format is not X.509"); + } + return keySpec.cast(new X509EncodedKeySpec(key.getEncoded())); + } else if (EdECPublicKeySpec.class.isAssignableFrom(keySpec)) { + EdECPublicKey edKey = (EdECPublicKey) key; + return keySpec.cast( + new EdECPublicKeySpec(edKey.getParams(), edKey.getPoint())); + } else { + throw new InvalidKeySpecException( + "KeySpec must be X509EncodedKeySpec or EdECPublicKeySpec"); + } + } else if (key instanceof EdECPrivateKey) { + checkLockedParams(InvalidKeySpecException::new, + ((EdECPrivateKey) key).getParams()); + + if (PKCS8EncodedKeySpec.class.isAssignableFrom(keySpec)) { + if (!key.getFormat().equals("PKCS#8")) { + throw new InvalidKeySpecException("Format is not PKCS#8"); + } + return keySpec.cast(new PKCS8EncodedKeySpec(key.getEncoded())); + } else if (EdECPrivateKeySpec.class.isAssignableFrom(keySpec)) { + EdECPrivateKey edKey = (EdECPrivateKey) key; + byte[] scalar = edKey.getBytes().orElseThrow( + () -> new InvalidKeySpecException("No private key value") + ); + return keySpec.cast( + new EdECPrivateKeySpec(edKey.getParams(), scalar)); + } else { + throw new InvalidKeySpecException + ("KeySpec must be PKCS8EncodedKeySpec or EdECPrivateKeySpec"); + } + } else { + throw new InvalidKeySpecException("Unsupported key type"); + } + } + + public static class Ed25519 extends EdDSAKeyFactory { + + public Ed25519() { + super(NamedParameterSpec.ED25519); + } + } + + public static class Ed448 extends EdDSAKeyFactory { + + public Ed448() { + super(NamedParameterSpec.ED448); + } + } +} diff --git a/src/jdk.crypto.ec/share/classes/sun/security/ec/ed/EdDSAKeyPairGenerator.java b/src/jdk.crypto.ec/share/classes/sun/security/ec/ed/EdDSAKeyPairGenerator.java new file mode 100644 index 00000000000..040f9531afb --- /dev/null +++ b/src/jdk.crypto.ec/share/classes/sun/security/ec/ed/EdDSAKeyPairGenerator.java @@ -0,0 +1,139 @@ +/* + * 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 sun.security.ec.ed; + +//import java.security.*; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.InvalidParameterException; +import java.security.KeyPair; +import java.security.KeyPairGeneratorSpi; +import java.security.NoSuchAlgorithmException; +import java.security.ProviderException; +import java.security.SecureRandom; +import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.EdECPoint; +import java.security.spec.NamedParameterSpec; + +import sun.security.jca.JCAUtil; +import sun.security.util.SecurityProviderConstants; + +/** + * Key pair generator for the EdDSA signature algorithm. + */ +public class EdDSAKeyPairGenerator extends KeyPairGeneratorSpi { + + private SecureRandom random = null; + private EdDSAOperations ops = null; + private EdDSAParameters lockedParams = null; + + public EdDSAKeyPairGenerator() { + initialize(SecurityProviderConstants.DEF_ED_KEY_SIZE, null); + } + + private EdDSAKeyPairGenerator(NamedParameterSpec paramSpec) { + tryInitialize(paramSpec); + lockedParams = ops.getParameters(); + } + + private void tryInitialize(NamedParameterSpec paramSpec) { + try { + initialize(paramSpec, null); + } catch (InvalidAlgorithmParameterException ex) { + String name = paramSpec.getName(); + throw new ProviderException(name + " not supported"); + } + } + + @Override + public void initialize(int keySize, SecureRandom random) { + + EdDSAParameters params = EdDSAParameters.getBySize( + InvalidParameterException::new, keySize); + + initializeImpl(params, random); + } + + @Override + public void initialize(AlgorithmParameterSpec params, SecureRandom random) + throws InvalidAlgorithmParameterException { + + EdDSAParameters edParams = EdDSAParameters.get( + InvalidAlgorithmParameterException::new, params); + + try { + initializeImpl(edParams, random); + } catch (InvalidParameterException e) { + throw new InvalidAlgorithmParameterException(e); + } + } + + private void initializeImpl(EdDSAParameters params, SecureRandom random) { + + if (lockedParams != null && lockedParams != params) { + throw new InvalidParameterException("Parameters must be " + + lockedParams.getName()); + } + + try { + this.ops = new EdDSAOperations(params); + } catch (NoSuchAlgorithmException ex) { + throw new ProviderException(ex); + } + this.random = random == null ? JCAUtil.getSecureRandom() : random; + } + + + @Override + public KeyPair generateKeyPair() { + + byte[] privateKey = ops.generatePrivate(random); + EdECPoint publicKey = ops.computePublic(privateKey); + + try { + return new KeyPair( + new EdDSAPublicKeyImpl(ops.getParameters(), publicKey), + new EdDSAPrivateKeyImpl(ops.getParameters(), privateKey) + ); + } catch (InvalidKeyException ex) { + throw new ProviderException(ex); + } + } + + public static class Ed25519 extends EdDSAKeyPairGenerator { + + public Ed25519() { + super(NamedParameterSpec.ED25519); + } + } + + public static class Ed448 extends EdDSAKeyPairGenerator { + + public Ed448() { + super(NamedParameterSpec.ED448); + } + } +} diff --git a/src/jdk.crypto.ec/share/classes/sun/security/ec/ed/EdDSAOperations.java b/src/jdk.crypto.ec/share/classes/sun/security/ec/ed/EdDSAOperations.java new file mode 100644 index 00000000000..c102453aac9 --- /dev/null +++ b/src/jdk.crypto.ec/share/classes/sun/security/ec/ed/EdDSAOperations.java @@ -0,0 +1,279 @@ +/* + * 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 sun.security.ec.ed; + +import sun.security.ec.point.AffinePoint; +import sun.security.ec.point.Point; +import sun.security.util.ArrayUtil; +import sun.security.util.math.IntegerFieldModuloP; +import sun.security.util.math.IntegerModuloP; +import sun.security.util.math.MutableIntegerModuloP; + +import java.math.BigInteger; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.SignatureException; +import java.security.spec.EdDSAParameterSpec; +import java.security.spec.EdECPoint; +import java.util.Arrays; +import java.util.function.Function; + +/* + * A class containing the operations of the EdDSA signature scheme. The + * parameters include an object that performs the elliptic curve point + * arithmetic, and EdDSAOperations uses this object to construct the signing + * and verification operations. + */ +public class EdDSAOperations { + + private final EdDSAParameters params; + + public EdDSAOperations(EdDSAParameters params) + throws NoSuchAlgorithmException { + + this.params = params; + } + + public EdDSAParameters getParameters() { + return params; + } + + public byte[] generatePrivate(SecureRandom random) { + byte[] result = new byte[params.getKeyLength()]; + random.nextBytes(result); + return result; + } + + public EdECPoint computePublic(byte[] privateKey) { + byte[] privateKeyHash = params.digest(privateKey); + int byteLength = privateKeyHash.length / 2; + byte[] s = Arrays.copyOf(privateKeyHash, byteLength); + prune(s); + IntegerModuloP fieldS = params.getOrderField().getElement(s); + fieldS.asByteArray(s); + Point A = params.getEdOperations().basePointMultiply(s); + return asEdECPoint(A.asAffine()); + } + + private static EdECPoint asEdECPoint(AffinePoint p) { + return new EdECPoint(p.getX().asBigInteger().testBit(0), + p.getY().asBigInteger()); + } + + public byte[] sign(EdDSAParameterSpec sigParams, byte[] privateKey, + byte[] message) { + + byte[] privateKeyHash = params.digest(privateKey); + + int byteLength = privateKeyHash.length / 2; + byte[] s = Arrays.copyOf(privateKeyHash, byteLength); + prune(s); + IntegerModuloP sElem = params.getOrderField().getElement(s); + sElem.asByteArray(s); + Point A = params.getEdOperations().basePointMultiply(s); + byte[] prefix = Arrays.copyOfRange(privateKeyHash, + privateKeyHash.length / 2, privateKeyHash.length); + byte[] dom = params.dom(sigParams); + byte[] r = params.digest(dom, prefix, message); + + // reduce r modulo the order + IntegerModuloP fieldR = params.getOrderField().getElement(r); + r = new byte[params.getKeyLength()]; + fieldR.asByteArray(r); + + Point R = params.getEdOperations().basePointMultiply(r); + + byte[] encodedR = encode(byteLength, R); + byte[] encodedA = encode(byteLength, A); + byte[] k = params.digest(dom, encodedR, encodedA, message); + + // S computation is in group-order field + IntegerFieldModuloP subField = params.getOrderField(); + IntegerModuloP kElem = subField.getElement(k); + IntegerModuloP rElem = subField.getElement(r); + MutableIntegerModuloP S = kElem.mutable().setProduct(sElem); + S.setSum(rElem); + // need to be reduced before output conversion + S.setReduced(); + byte[] sArr = S.asByteArray(byteLength); + byte[] rArr = encode(byteLength, R); + + byte[] result = new byte[byteLength * 2]; + System.arraycopy(rArr, 0, result, 0, byteLength); + System.arraycopy(sArr, 0, result, byteLength, byteLength); + return result; + } + + public boolean verify(EdDSAParameterSpec sigParams, AffinePoint affineA, + byte[] publicKey, byte[] message, byte[] signature) + throws SignatureException { + + if (signature == null) { + throw new SignatureException("signature was null"); + } + byte[] encR = Arrays.copyOf(signature, signature.length / 2); + byte[] encS = Arrays.copyOfRange(signature, signature.length / 2, + signature.length); + + // reject s if it is too large + ArrayUtil.reverse(encS); + BigInteger bigS = new BigInteger(1, encS); + if (bigS.compareTo(params.getOrderField().getSize()) >= 0) { + throw new SignatureException("s is too large"); + } + ArrayUtil.reverse(encS); + + byte[] dom = params.dom(sigParams); + AffinePoint affineR = decodeAffinePoint(SignatureException::new, encR); + byte[] k = params.digest(dom, encR, publicKey, message); + // reduce k to improve performance of multiply + IntegerFieldModuloP subField = params.getOrderField(); + IntegerModuloP kElem = subField.getElement(k); + k = kElem.asByteArray(k.length / 2); + + Point pointR = params.getEdOperations().of(affineR); + Point pointA = params.getEdOperations().of(affineA); + + EdECOperations edOps = params.getEdOperations(); + Point lhs = edOps.basePointMultiply(encS); + Point rhs = edOps.setSum(edOps.setProduct(pointA.mutable(), k), + pointR.mutable()); + + return lhs.affineEquals(rhs); + } + + public boolean verify(EdDSAParameterSpec sigParams, byte[] publicKey, + byte[] message, byte[] signature) + throws InvalidKeyException, SignatureException { + + AffinePoint affineA = decodeAffinePoint(InvalidKeyException::new, + publicKey); + return verify(sigParams, affineA, publicKey, message, signature); + } + + public + + AffinePoint decodeAffinePoint(Function exception, byte[] arr) + throws T { + + if (arr.length != params.getKeyLength()) { + throw exception.apply("incorrect length"); + } + + arr = arr.clone(); + int xLSB = (0xFF & arr[arr.length - 1]) >>> 7; + arr[arr.length - 1] &= 0x7F; + int yLength = (params.getBits() + 7) >> 3; + IntegerModuloP y = + params.getField().getElement(arr, 0, yLength, (byte) 0); + // reject non-canonical y values + ArrayUtil.reverse(arr); + BigInteger bigY = new BigInteger(1, arr); + if (bigY.compareTo(params.getField().getSize()) >= 0) { + throw exception.apply("y value is too large"); + } + return params.getEdOperations().decodeAffinePoint(exception, xLSB, y); + } + + public + + AffinePoint decodeAffinePoint(Function exception, + EdECPoint point) + throws T { + + // reject non-canonical y values + if (point.getY().compareTo(params.getField().getSize()) >= 0) { + throw exception.apply("y value is too large"); + } + + int xLSB = point.isXOdd() ? 1 : 0; + IntegerModuloP y = params.getField().getElement(point.getY()); + return params.getEdOperations().decodeAffinePoint(exception, xLSB, y); + } + + /** + * Mask off the high order bits of an encoded integer in an array. The + * array is modified in place. + * + * @param arr an array containing an encoded integer + * @param bits the number of bits to keep + * @return the number, in range [0,8], of bits kept in the highest byte + */ + private static int maskHighOrder(byte[] arr, int bits) { + + int lastByteIndex = arr.length - 1; + int bitsDiff = arr.length * 8 - bits; + int highBits = 8 - bitsDiff; + byte msbMaskOff = (byte) ((1 << highBits) - 1); + arr[lastByteIndex] &= msbMaskOff; + + return highBits; + } + + /** + * Prune an encoded scalar value by modifying it in place. The extra + * high-order bits are masked off, the highest valid bit it set, and the + * number is rounded down to a multiple of the co-factor. + * + * @param k an encoded scalar value + * @param bits the number of bits in the scalar + * @param logCofactor the base-2 logarithm of the co-factor + */ + private static void prune(byte[] k, int bits, int logCofactor) { + + int lastByteIndex = k.length - 1; + + // mask off unused high-order bits + int highBits = maskHighOrder(k, bits); + + // set the highest bit + if (highBits == 0) { + k[lastByteIndex - 1] |= 0x80; + } else { + byte msbMaskOn = (byte) (1 << (highBits - 1)); + k[lastByteIndex] |= msbMaskOn; + } + + // round down to a multiple of the co-factor + byte lsbMaskOff = (byte) (0xFF << logCofactor); + k[0] &= lsbMaskOff; + } + + void prune(byte[] arr) { + prune(arr, params.getBits(), params.getLogCofactor()); + } + + private static byte[] encode(int length, Point p) { + return encode(length, p.asAffine()); + } + + private static byte[] encode(int length, AffinePoint p) { + byte[] result = p.getY().asByteArray(length); + int xLSB = p.getX().asByteArray(1)[0] & 0x01; + result[result.length - 1] |= (xLSB << 7); + return result; + } +} diff --git a/src/jdk.crypto.ec/share/classes/sun/security/ec/ed/EdDSAParameters.java b/src/jdk.crypto.ec/share/classes/sun/security/ec/ed/EdDSAParameters.java new file mode 100644 index 00000000000..a1c5733af75 --- /dev/null +++ b/src/jdk.crypto.ec/share/classes/sun/security/ec/ed/EdDSAParameters.java @@ -0,0 +1,332 @@ +/* + * 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 sun.security.ec.ed; + +import sun.security.ec.ParametersMap; +import sun.security.provider.SHAKE256; +import sun.security.util.ObjectIdentifier; +import sun.security.util.math.*; +import sun.security.util.math.intpoly.*; +import sun.security.x509.AlgorithmId; + +import java.io.IOException; +import java.math.BigInteger; +import java.nio.charset.StandardCharsets; +import java.security.*; +import java.security.spec.*; +import java.util.function.Function; + +/* + * The set of parameters that defines an instance of the EdDSA signature + * scheme. + */ +public class EdDSAParameters { + + public interface DigesterFactory { + // Default digest creator + Digester createDigester(); + + // Override this method if multiple key lengths are needed + default Digester createDigester(int len) { + return createDigester(); + } + + // Return a digest over all the provided byte arrays + default byte[] digest(byte[]... data) { + Digester d = createDigester(); + for (byte[] curData : data) { + d.update(curData, 0, curData.length); + } + return d.digest(); + } + } + + // Hash for Ed25519 + private static class SHA512DigesterFactory implements DigesterFactory { + @Override + public Digester createDigester() { + try { + MessageDigest md = MessageDigest.getInstance("SHA-512"); + return new MessageDigester(md); + } catch (NoSuchAlgorithmException ex) { + throw new ProviderException(ex); + } + } + } + + // Hash for Ed448 + private static class SHAKE256DigesterFactory implements DigesterFactory { + @Override + // Most usage for Ed448 is 114bytes long + public Digester createDigester() { + return new SHAKE256Digester(114); + } + + // Ed448 uses 64bytes long hasg for the signature message + @Override + public Digester createDigester(int len) { + return new SHAKE256Digester(len); + } + } + + public interface Digester { + void update(byte data); + void update(byte[] data, int off, int len); + byte[] digest(); + } + + private static class MessageDigester implements Digester { + private final MessageDigest md; + + private MessageDigester(MessageDigest md) { + this.md = md; + } + + @Override + public void update(byte data) { + md.update(data); + } + @Override + public void update(byte[] data, int off, int len) { + md.update(data, off, len); + } + @Override + public byte[] digest() { + return md.digest(); + } + } + + private static class SHAKE256Digester implements Digester { + SHAKE256 md; + + SHAKE256Digester(int len) { + md = new SHAKE256(len); + } + @Override + public void update(byte data) { + md.update(data); + } + @Override + public void update(byte[] data, int off, int len) { + md.update(data, off, len); + } + @Override + public byte[] digest() { + return md.digest(); + } + } + + static ParametersMap namedParams = new ParametersMap<>(); + + private final String name; + private final ObjectIdentifier oid; + private final IntegerFieldModuloP field; + private final IntegerFieldModuloP orderField; + private final ImmutableIntegerModuloP d; + private final EdECOperations edOperations; + private final DigesterFactory digester; + private final int keyLength; + private final int bits; + private final int logCofactor; + private final Function dom; + + public EdDSAParameters(String name, ObjectIdentifier oid, + IntegerFieldModuloP field, + IntegerFieldModuloP orderField, + ImmutableIntegerModuloP d, + EdECOperations edOps, + DigesterFactory digester, + Function dom, + int keyLength, int bits, int logCofactor) { + this.oid = oid; + this.name = name; + this.field = field; + this.orderField = orderField; + this.d = d; + this.edOperations = edOps; + this.digester = digester; + this.keyLength = keyLength; + this.bits = bits; + this.logCofactor = logCofactor; + this.dom = dom; + } + + public String getName() { + return name; + } + public ObjectIdentifier getOid() { + return oid; + } + public IntegerFieldModuloP getField() { + return field; + } + public IntegerFieldModuloP getOrderField() { + return orderField; + } + public ImmutableIntegerModuloP getD() { + return d; + } + public EdECOperations getEdOperations() { + return edOperations; + } + public int getKeyLength() { + return keyLength; + } + public int getBits() { + return bits; + } + public int getLogCofactor() { + return logCofactor; + } + + public Digester createDigester() { + return digester.createDigester(); + } + + public Digester createDigester(int len) { + return digester.createDigester(len); + } + + public byte[] digest(byte[]... data) { + return digester.digest(data); + } + + public byte[] dom(EdDSAParameterSpec sigParams) { + return dom.apply(sigParams); + } + + private final static String prefixStr25519 = + "SigEd25519 no Ed25519 collisions"; + private final static String prefixStr448 = "SigEd448"; + + // Used for Ed25519 + static byte[] dom2(EdDSAParameterSpec sigParams) { + if (!sigParams.isPrehash() && !sigParams.getContext().isPresent()) { + return new byte[0]; + } + return domImpl(prefixStr25519, sigParams); + } + + // Used for Ed488 + static byte[] dom4(EdDSAParameterSpec sigParams) { + return domImpl(prefixStr448, sigParams); + } + + static byte[] domImpl(String prefixStr, EdDSAParameterSpec sigParams) { + byte[] prefix = prefixStr.getBytes(StandardCharsets.US_ASCII); + byte[] context = sigParams.getContext().orElse(new byte[0]); + int length = prefix.length + 2 + context.length; + byte[] result = new byte[length]; + System.arraycopy(prefix, 0, result, 0, prefix.length); + byte x = (byte) (sigParams.isPrehash() ? 1 : 0); + result[prefix.length] = x; + result[prefix.length + 1] = (byte) context.length; + System.arraycopy(context, 0, result, prefix.length + 2, + context.length); + return result; + } + + static { + // set up Ed25519 + try { + IntegerFieldModuloP ed25519Field = new IntegerPolynomial25519(); + IntegerFieldModuloP ed25519OrderField = new Curve25519OrderField(); + BigInteger biD = new BigInteger("3709570593466943934313808350875" + + "4565189542113879843219016388785533085940283555"); + ImmutableIntegerModuloP d = ed25519Field.getElement(biD); + BigInteger baseX = new BigInteger("15112221349535400772501151409" + + "588531511454012693041857206046113283949847762202"); + BigInteger baseY = new BigInteger("46316835694926478169428394003" + + "475163141307993866256225615783033603165251855960"); + EdECOperations edOps = new Ed25519Operations(d, baseX, baseY); + String name = NamedParameterSpec.ED25519.getName(); + ObjectIdentifier oid = new ObjectIdentifier("1.3.101.112"); + int bits = 255; + DigesterFactory digester = new SHA512DigesterFactory(); + EdDSAParameters params = new EdDSAParameters(name, oid, + ed25519Field, ed25519OrderField, d, edOps, + digester, EdDSAParameters::dom2, 32, bits, 3); + + namedParams.put(name, oid, bits, params); + + } catch (IOException ex) { + // Unable to set Ed25519 parameters---it will be disabled + } + + // set up Ed448 + try { + IntegerFieldModuloP ed448Field = new IntegerPolynomial448(); + IntegerFieldModuloP ed448OrderField = new Curve448OrderField(); + BigInteger biD = ed448Field.getSize().subtract( + new BigInteger("39081")); + ImmutableIntegerModuloP d = ed448Field.getElement(biD); + BigInteger baseX = new BigInteger("224580040295924300187604334" + + "099896036246789641632564134246125461686950415467406032909" + + "029192869357953282578032075146446173674602635247710"); + BigInteger baseY = new BigInteger("298819210078481492676017930" + + "443930673437544040154080242095928241372331506189835876003" + + "536878655418784733982303233503462500531545062832660"); + EdECOperations edOps = new Ed448Operations(d, baseX, baseY); + String name = NamedParameterSpec.ED448.getName(); + ObjectIdentifier oid = new ObjectIdentifier("1.3.101.113"); + int bits = 448; + DigesterFactory digester = new SHAKE256DigesterFactory(); + EdDSAParameters params = new EdDSAParameters(name, oid, + ed448Field, ed448OrderField, d, edOps, + digester, EdDSAParameters::dom4, 57, bits, 2); + + namedParams.put(name, oid, bits, params); + + } catch (IOException ex) { + // Unable to set Ed448 parameters---it will be disabled + } + + namedParams.fix(); + } + + public static + + EdDSAParameters getBySize(Function exception, + int size) throws T { + + return namedParams.getBySize(exception, size); + } + + public static + + EdDSAParameters get(Function exception, + AlgorithmId algId) throws T { + + return namedParams.get(exception, algId); + } + + public static + + EdDSAParameters get(Function exception, + AlgorithmParameterSpec params) throws T { + + return namedParams.get(exception, params); + } +} diff --git a/src/jdk.crypto.ec/share/classes/sun/security/ec/ed/EdDSAPrivateKeyImpl.java b/src/jdk.crypto.ec/share/classes/sun/security/ec/ed/EdDSAPrivateKeyImpl.java new file mode 100644 index 00000000000..aeacb680f28 --- /dev/null +++ b/src/jdk.crypto.ec/share/classes/sun/security/ec/ed/EdDSAPrivateKeyImpl.java @@ -0,0 +1,116 @@ +/* + * 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 sun.security.ec.ed; + +import java.io.IOException; +import java.security.InvalidKeyException; +import java.security.ProviderException; +import java.security.interfaces.EdECPrivateKey; +import java.util.Optional; +import java.security.spec.NamedParameterSpec; + +import sun.security.pkcs.PKCS8Key; +import sun.security.x509.AlgorithmId; +import sun.security.util.*; + +public final class EdDSAPrivateKeyImpl + extends PKCS8Key implements EdECPrivateKey { + + private static final long serialVersionUID = 1L; + + private final NamedParameterSpec paramSpec; + private byte[] h; + + EdDSAPrivateKeyImpl(EdDSAParameters params, byte[] h) + throws InvalidKeyException { + + this.paramSpec = new NamedParameterSpec(params.getName()); + this.algid = new AlgorithmId(params.getOid()); + this.h = h.clone(); + + encodeKey(); + + checkLength(params); + } + + EdDSAPrivateKeyImpl(byte[] encoded) throws InvalidKeyException { + + decode(encoded); + EdDSAParameters params = EdDSAParameters.get( + InvalidKeyException::new, algid); + paramSpec = new NamedParameterSpec(params.getName()); + + decodeKey(); + + checkLength(params); + } + + private void decodeKey() throws InvalidKeyException { + try { + DerInputStream derStream = new DerInputStream(key); + h = derStream.getOctetString(); + } catch (IOException ex) { + throw new InvalidKeyException(ex); + } + } + + private void encodeKey() { + DerOutputStream derKey = new DerOutputStream(); + try { + derKey.putOctetString(h); + this.key = derKey.toByteArray(); + } catch (IOException ex) { + throw new ProviderException(ex); + } + } + + void checkLength(EdDSAParameters params) throws InvalidKeyException { + + if (params.getKeyLength() != this.h.length) { + throw new InvalidKeyException("key length is " + this.h.length + + ", key length must be " + params.getKeyLength()); + } + } + + public byte[] getKey() { + return h.clone(); + } + + @Override + public String getAlgorithm() { + return "EdDSA"; + } + + @Override + public NamedParameterSpec getParams() { + return paramSpec; + } + + @Override + public Optional getBytes() { + return Optional.of(getKey()); + } +} diff --git a/src/jdk.crypto.ec/share/classes/sun/security/ec/ed/EdDSAPublicKeyImpl.java b/src/jdk.crypto.ec/share/classes/sun/security/ec/ed/EdDSAPublicKeyImpl.java new file mode 100644 index 00000000000..ebc51e9a821 --- /dev/null +++ b/src/jdk.crypto.ec/share/classes/sun/security/ec/ed/EdDSAPublicKeyImpl.java @@ -0,0 +1,130 @@ +/* + * 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 sun.security.ec.ed; + +import java.math.BigInteger; +import java.security.InvalidKeyException; +import java.security.KeyRep; +import java.security.interfaces.EdECPublicKey; +import java.security.spec.EdECPoint; +import java.security.spec.NamedParameterSpec; +import java.util.Arrays; + +import sun.security.util.BitArray; +import sun.security.x509.AlgorithmId; +import sun.security.x509.X509Key; + +public final class EdDSAPublicKeyImpl extends X509Key implements EdECPublicKey { + + private static final long serialVersionUID = 1L; + + private final EdECPoint point; + private final NamedParameterSpec paramSpec; + + public EdDSAPublicKeyImpl(EdDSAParameters params, EdECPoint point) + throws InvalidKeyException { + this.paramSpec = new NamedParameterSpec(params.getName()); + this.algid = new AlgorithmId(params.getOid()); + this.point = point; + + byte[] encodedPoint = point.getY().toByteArray(); + reverse(encodedPoint); + // array may be too large or too small, depending on the value + encodedPoint = Arrays.copyOf(encodedPoint, params.getKeyLength()); + // set the high-order bit of the encoded point + byte msb = (byte) (point.isXOdd() ? 0x80 : 0); + encodedPoint[encodedPoint.length - 1] |= msb; + setKey(new BitArray(encodedPoint.length * 8, encodedPoint)); + + checkLength(params); + } + + public EdDSAPublicKeyImpl(byte[] encoded) throws InvalidKeyException { + decode(encoded); + + EdDSAParameters params = + EdDSAParameters.get(InvalidKeyException::new, algid); + this.paramSpec = new NamedParameterSpec(params.getName()); + // construct the EdECPoint representation + byte[] encodedPoint = getKey().toByteArray(); + byte msb = encodedPoint[encodedPoint.length - 1]; + encodedPoint[encodedPoint.length - 1] &= (byte) 0x7F; + boolean xOdd = (msb & 0x80) != 0; + reverse(encodedPoint); + BigInteger y = new BigInteger(1, encodedPoint); + this.point = new EdECPoint(xOdd, y); + + checkLength(params); + } + + void checkLength(EdDSAParameters params) throws InvalidKeyException { + if (params.getKeyLength() * 8 != getKey().length()) { + throw new InvalidKeyException( + "key length must be " + params.getKeyLength()); + } + } + + public byte[] getEncodedPoint() { + return getKey().toByteArray(); + } + + @Override + public EdECPoint getPoint() { + return point; + } + + @Override + public NamedParameterSpec getParams() { + return paramSpec; + } + + @Override + public String getAlgorithm() { + return "EdDSA"; + } + + protected Object writeReplace() throws java.io.ObjectStreamException { + return new KeyRep(KeyRep.Type.PUBLIC, getAlgorithm(), getFormat(), + getEncoded()); + } + + private static void swap(byte[] arr, int i, int j) { + byte tmp = arr[i]; + arr[i] = arr[j]; + arr[j] = tmp; + } + + private static void reverse(byte [] arr) { + int i = 0; + int j = arr.length - 1; + + while (i < j) { + swap(arr, i, j); + i++; + j--; + } + } +} diff --git a/src/jdk.crypto.ec/share/classes/sun/security/ec/ed/EdDSASignature.java b/src/jdk.crypto.ec/share/classes/sun/security/ec/ed/EdDSASignature.java new file mode 100644 index 00000000000..5fecd943c1a --- /dev/null +++ b/src/jdk.crypto.ec/share/classes/sun/security/ec/ed/EdDSASignature.java @@ -0,0 +1,314 @@ +/* + * 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 sun.security.ec.ed; + +import sun.security.ec.point.AffinePoint; + +import java.io.ByteArrayOutputStream; +import java.security.AlgorithmParameters; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.InvalidParameterException; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.ProviderException; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.SignatureException; +import java.security.SignatureSpi; +import java.security.interfaces.EdECPrivateKey; +import java.security.interfaces.EdECPublicKey; +import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.EdDSAParameterSpec; +import java.security.spec.NamedParameterSpec; +import java.util.function.Function; + +public class EdDSASignature extends SignatureSpi { + + private interface MessageAccumulator { + void add(byte b); + void add(byte[] data, int off, int len); + byte[] getMessage(); + } + + private static class DigestAccumulator implements MessageAccumulator { + private final EdDSAParameters.Digester digester; + + DigestAccumulator(EdDSAParameters.Digester digester) { + this.digester = digester; + } + + @Override + public void add(byte b) { + digester.update(b); + } + @Override + public void add(byte[] data, int off, int len) { + digester.update(data, off, len); + } + @Override + public byte[] getMessage() { + return digester.digest(); + } + } + + private static class MemoryAccumulator implements MessageAccumulator { + ByteArrayOutputStream message = new ByteArrayOutputStream(); + + @Override + public void add(byte b) { + message.write(b); + } + @Override + public void add(byte[] data, int off, int len) { + message.write(data, off, len); + } + @Override + public byte[] getMessage() { + return message.toByteArray(); + } + } + + private byte[] privateKey; + private AffinePoint publicKeyPoint; + private byte[] publicKeyBytes; + private EdDSAOperations ops; + private EdDSAParameters lockedParams = null; + private MessageAccumulator message = null; + private EdDSAParameterSpec sigParams = new EdDSAParameterSpec(false); + + public EdDSASignature() { + // do nothing + } + + EdDSASignature(NamedParameterSpec paramSpec) { + lockedParams = EdDSAParameters.get(ProviderException::new, paramSpec); + } + + @Override + protected void engineInitVerify(PublicKey publicKey) + throws InvalidKeyException { + + if (!(publicKey instanceof EdECPublicKey)) { + throw new InvalidKeyException("Unsupported key type"); + } + EdECPublicKey edKey = (EdECPublicKey) publicKey; + EdDSAParameters params = EdDSAParameters.get( + InvalidKeyException::new, edKey.getParams()); + + initImpl(params); + this.privateKey = null; + this.publicKeyPoint = ops.decodeAffinePoint(InvalidKeyException::new, + edKey.getPoint()); + EdDSAPublicKeyImpl pubKeyImpl = new EdDSAPublicKeyImpl(params, + edKey.getPoint()); + this.publicKeyBytes = pubKeyImpl.getEncodedPoint(); + } + + @Override + protected void engineInitSign(PrivateKey privateKey) + throws InvalidKeyException { + engineInitSign(privateKey, null); + } + + @Override + protected void engineInitSign(PrivateKey privateKey, SecureRandom random) + throws InvalidKeyException { + + if (!(privateKey instanceof EdECPrivateKey)) { + throw new InvalidKeyException("Unsupported key type"); + } + EdECPrivateKey edKey = (EdECPrivateKey) privateKey; + + initImpl(edKey.getParams()); + this.privateKey = edKey.getBytes().orElseThrow( + () -> new InvalidKeyException("No private key value")); + this.publicKeyPoint = null; + this.publicKeyBytes = null; + } + + private + + void checkLockedParams(Function exception, + EdDSAParameters params) throws T { + if (lockedParams != null && lockedParams != params) { + throw exception.apply("Parameters must be " + + lockedParams.getName()); + } + } + + private void ensureMessageInit() throws SignatureException { + if (message == null) { + initMessage(); + } + } + + private void initMessage() throws SignatureException { + if (this.ops == null) { + throw new SignatureException("not initialized"); + } + EdDSAParameters params = ops.getParameters(); + + if (sigParams.isPrehash()) { + this.message = new DigestAccumulator(params.createDigester(64)); + } else { + this.message = new MemoryAccumulator(); + } + } + + @Override + protected void engineUpdate(byte b) throws SignatureException { + ensureMessageInit(); + this.message.add(b); + } + + @Override + protected void engineUpdate(byte[] b, int off, int len) + throws SignatureException { + + ensureMessageInit(); + this.message.add(b, off, len); + } + + @Override + protected byte[] engineSign() throws SignatureException { + if (privateKey == null) { + throw new SignatureException("Missing private key"); + } + ensureMessageInit(); + byte[] result = ops.sign(this.sigParams, this.privateKey, + message.getMessage()); + message = null; + return result; + } + + @Override + protected boolean engineVerify(byte[] sigBytes) throws SignatureException { + if (publicKeyBytes == null) { + throw new SignatureException("Missing publicKey"); + } + if (message == null) { + return false; + } + boolean result = ops.verify(this.sigParams, this.publicKeyPoint, + this.publicKeyBytes, message.getMessage(), sigBytes); + message = null; + return result; + } + + private void initImpl(EdDSAParameters params) throws InvalidKeyException { + checkLockedParams(InvalidKeyException::new, params); + + try { + this.ops = new EdDSAOperations(params); + } catch (NoSuchAlgorithmException ex) { + throw new ProviderException(ex); + } + // message is (re)set to null + // it will be initialized on first update + this.message = null; + } + + private void initImpl(NamedParameterSpec paramSpec) + throws InvalidKeyException { + + EdDSAParameters params = EdDSAParameters.get( + InvalidKeyException::new, paramSpec); + initImpl(params); + } + + @Deprecated + @Override + protected Object engineGetParameter(String param) + throws InvalidParameterException { + throw new UnsupportedOperationException("getParameter() not supported"); + } + + @Deprecated + @Override + protected void engineSetParameter(String param, Object value) + throws InvalidParameterException { + + throw new UnsupportedOperationException("setParameter() not supported"); + } + + @Override + protected void engineSetParameter(AlgorithmParameterSpec params) + throws InvalidAlgorithmParameterException { + + // by convention, ignore null parameters + if (params == null) { + return; + } + + if (params instanceof EdDSAParameterSpec) { + if (message != null) { + // sign/verify in progress + throw new InvalidParameterException("Cannot change signature " + + "parameters during operation"); + } + EdDSAParameterSpec edDsaParams = (EdDSAParameterSpec) params; + checkContextLength(edDsaParams); + + this.sigParams = edDsaParams; + } else { + throw new InvalidAlgorithmParameterException( + "Only EdDSAParameterSpec supported"); + } + } + + private static void checkContextLength(EdDSAParameterSpec edDsaParams) + throws InvalidAlgorithmParameterException { + + if (edDsaParams.getContext().isPresent()) { + byte[] context = edDsaParams.getContext().get(); + if (context.length > 255) { + throw new InvalidAlgorithmParameterException( + "Context is longer than 255 bytes"); + } + } + } + + // There is no RFC-defined ASN.1 for prehash and context (RFC 8410) + @Override + protected AlgorithmParameters engineGetParameters() { + return null; + } + + public static class Ed25519 extends EdDSASignature { + + public Ed25519() { + super(NamedParameterSpec.ED25519); + } + } + + public static class Ed448 extends EdDSASignature { + + public Ed448() { + super(NamedParameterSpec.ED448); + } + } +} diff --git a/src/jdk.crypto.ec/share/classes/sun/security/ec/ed/EdECOperations.java b/src/jdk.crypto.ec/share/classes/sun/security/ec/ed/EdECOperations.java new file mode 100644 index 00000000000..d18c113787e --- /dev/null +++ b/src/jdk.crypto.ec/share/classes/sun/security/ec/ed/EdECOperations.java @@ -0,0 +1,103 @@ +/* + * 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 sun.security.ec.ed; + +import sun.security.ec.point.*; +import sun.security.util.math.IntegerModuloP; +import sun.security.util.math.MutableIntegerModuloP; + +import java.util.function.Function; + +/* + * Base class for Edwards curve ECC implementations. + */ +public abstract class EdECOperations { + + // Curve-specific base point multiplication. + public abstract Point basePointMultiply(byte[] s); + + // Decode curve-specifics to the affinePoint + public abstract + AffinePoint decodeAffinePoint(Function exception, + int xLSB, IntegerModuloP y) throws T; + + // Curve specific point from an X,Y point + public abstract ImmutablePoint of(AffinePoint p); + + /* + * Generic method for taking two classes implementing MutablePoint to be + * called by the curve-specific setSum() + */ + public MutablePoint setSum(MutablePoint p1, MutablePoint p2) { + MutableIntegerModuloP t1 = p2.getField().get1().mutable(); + MutableIntegerModuloP t2 = p2.getField().get1().mutable(); + MutableIntegerModuloP t3 = p2.getField().get1().mutable(); + return setSum(p1, p2, t1, t2, t3); + } + + /* + * Generic method for taking a class implementing MutablePoint with a + * scalar to returning the point product using curve-specific methods. + */ + public MutablePoint setProduct(MutablePoint p1, byte[] s) { + MutablePoint p = p1.mutable(); + p1.setValue(getNeutral()); + MutablePoint addResult = getNeutral().mutable(); + MutableIntegerModuloP t1 = p.getField().get0().mutable(); + MutableIntegerModuloP t2 = p.getField().get0().mutable(); + MutableIntegerModuloP t3 = p.getField().get0().mutable(); + + for (int i = 0; i < s.length * 8; i++) { + addResult.setValue(p1); + setSum(addResult, p, t1, t2, t3); + int swap = bitAt(s, i); + p1.conditionalSet(addResult, swap); + setDouble(p, t1, t2); + } + + return p1; + } + + // Abstract method for constructing the neutral point on the curve + protected abstract ImmutablePoint getNeutral(); + + + // Abstract method for Curve-specific point addition + protected abstract MutablePoint setSum(MutablePoint p1, MutablePoint p2, + MutableIntegerModuloP t1, + MutableIntegerModuloP t2, + MutableIntegerModuloP t3); + // Abstract method for Curve-specific point doubling + protected abstract MutablePoint setDouble(MutablePoint p, + MutableIntegerModuloP t1, + MutableIntegerModuloP t2); + + private static int bitAt(byte[] arr, int index) { + int byteIndex = index / 8; + int bitIndex = index % 8; + return (arr[byteIndex] & (1 << bitIndex)) >> bitIndex; + } +} diff --git a/src/jdk.crypto.ec/share/classes/sun/security/ec/point/ExtendedHomogeneousPoint.java b/src/jdk.crypto.ec/share/classes/sun/security/ec/point/ExtendedHomogeneousPoint.java new file mode 100644 index 00000000000..140d91b01c7 --- /dev/null +++ b/src/jdk.crypto.ec/share/classes/sun/security/ec/point/ExtendedHomogeneousPoint.java @@ -0,0 +1,194 @@ +/* + * 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 sun.security.ec.point; + +import sun.security.util.math.*; + +import java.math.BigInteger; + +/** + * Elliptic curve point in extended homogeneous coordinates (X, Y, T, Z) where + * an affine point (x, y) is represented using any (X, Y, T, Z) s.t. + * x = X/Z, y = Y/Z, and x*y = T/Z. + */ +public abstract class ExtendedHomogeneousPoint + implements Point { + + protected final T x; + protected final T y; + protected final T t; + protected final T z; + + protected ExtendedHomogeneousPoint(T x, T y, T t, T z) { + + this.x = x; + this.y = y; + this.t = t; + this.z = z; + } + + @Override + public IntegerFieldModuloP getField() { + return this.x.getField(); + } + @Override + public Immutable fixed() { + return new Immutable(x.fixed(), y.fixed(), t.fixed(), z.fixed()); + } + + @Override + public Mutable mutable() { + return new Mutable(x.mutable(), y.mutable(), t.mutable(), z.mutable()); + } + + public T getX() { + return x; + } + + public T getY() { + return y; + } + + public T getT() { + return t; + } + + public T getZ() { + return z; + } + + public AffinePoint asAffine() { + IntegerModuloP zInv = z.multiplicativeInverse(); + return new AffinePoint(x.multiply(zInv), y.multiply(zInv)); + } + + private static + + boolean affineEquals(ExtendedHomogeneousPoint p1, + ExtendedHomogeneousPoint p2) { + MutableIntegerModuloP x1 = p1.getX().mutable().setProduct(p2.getZ()); + MutableIntegerModuloP x2 = p2.getX().mutable().setProduct(p1.getZ()); + if (!x1.asBigInteger().equals(x2.asBigInteger())) { + return false; + } + + MutableIntegerModuloP y1 = p1.getY().mutable().setProduct(p2.getZ()); + MutableIntegerModuloP y2 = p2.getY().mutable().setProduct(p1.getZ()); + if (!y1.asBigInteger().equals(y2.asBigInteger())) { + return false; + } + + return true; + } + + public boolean affineEquals(Point p) { + if (p instanceof ExtendedHomogeneousPoint) { + @SuppressWarnings("unchecked") + ExtendedHomogeneousPoint ehp = + (ExtendedHomogeneousPoint) p; + return affineEquals(this, ehp); + } + + return asAffine().equals(p.asAffine()); + } + + public static class Immutable + extends ExtendedHomogeneousPoint + implements ImmutablePoint { + + public Immutable(ImmutableIntegerModuloP x, + ImmutableIntegerModuloP y, + ImmutableIntegerModuloP t, + ImmutableIntegerModuloP z) { + super(x, y, t, z); + } + } + + public static class Mutable + extends ExtendedHomogeneousPoint + implements MutablePoint { + + public Mutable(MutableIntegerModuloP x, + MutableIntegerModuloP y, + MutableIntegerModuloP t, + MutableIntegerModuloP z) { + super(x, y, t, z); + } + + @Override + public Mutable conditionalSet(Point p, int set) { + if (!(p instanceof ExtendedHomogeneousPoint)) { + throw new RuntimeException("Incompatible point"); + } + @SuppressWarnings("unchecked") + ExtendedHomogeneousPoint ehp = + (ExtendedHomogeneousPoint) p; + return conditionalSet(ehp, set); + } + + private + Mutable conditionalSet(ExtendedHomogeneousPoint ehp, int set) { + + x.conditionalSet(ehp.x, set); + y.conditionalSet(ehp.y, set); + t.conditionalSet(ehp.t, set); + z.conditionalSet(ehp.z, set); + + return this; + } + + @Override + public Mutable setValue(AffinePoint p) { + x.setValue(p.getX()); + y.setValue(p.getY()); + t.setValue(p.getX()).setProduct(p.getY()); + z.setValue(p.getX().getField().get1()); + + return this; + } + + @Override + public Mutable setValue(Point p) { + + @SuppressWarnings("unchecked") + ExtendedHomogeneousPoint ehp = + (ExtendedHomogeneousPoint) p; + + return setValue(ehp); + } + + private + Mutable setValue(ExtendedHomogeneousPoint ehp) { + + x.setValue(ehp.x); + y.setValue(ehp.y); + t.setValue(ehp.t); + z.setValue(ehp.z); + + return this; + } + } + +} diff --git a/src/jdk.crypto.ec/share/classes/sun/security/ec/point/Point.java b/src/jdk.crypto.ec/share/classes/sun/security/ec/point/Point.java index b28bd9df73d..0eab1df9272 100644 --- a/src/jdk.crypto.ec/share/classes/sun/security/ec/point/Point.java +++ b/src/jdk.crypto.ec/share/classes/sun/security/ec/point/Point.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 @@ -38,6 +38,7 @@ public interface Point { IntegerFieldModuloP getField(); AffinePoint asAffine(); + boolean affineEquals(Point p); ImmutablePoint fixed(); MutablePoint mutable(); diff --git a/src/jdk.crypto.ec/share/classes/sun/security/ec/point/ProjectivePoint.java b/src/jdk.crypto.ec/share/classes/sun/security/ec/point/ProjectivePoint.java index 587f1c72b35..a3ebc532d46 100644 --- a/src/jdk.crypto.ec/share/classes/sun/security/ec/point/ProjectivePoint.java +++ b/src/jdk.crypto.ec/share/classes/sun/security/ec/point/ProjectivePoint.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 @@ -77,6 +77,36 @@ public abstract class ProjectivePoint return new AffinePoint(x.multiply(zInv), y.multiply(zInv)); } + private static + + boolean affineEquals(ProjectivePoint p1, + ProjectivePoint p2) { + MutableIntegerModuloP x1 = p1.getX().mutable().setProduct(p2.getZ()); + MutableIntegerModuloP x2 = p2.getX().mutable().setProduct(p1.getZ()); + if (!x1.asBigInteger().equals(x2.asBigInteger())) { + return false; + } + + MutableIntegerModuloP y1 = p1.getY().mutable().setProduct(p2.getZ()); + MutableIntegerModuloP y2 = p2.getY().mutable().setProduct(p1.getZ()); + if (!y1.asBigInteger().equals(y2.asBigInteger())) { + return false; + } + + return true; + } + + public boolean affineEquals(Point p) { + if (p instanceof ProjectivePoint) { + @SuppressWarnings("unchecked") + ProjectivePoint pp = + (ProjectivePoint) p; + return affineEquals(this, pp); + } + + return asAffine().equals(p.asAffine()); + } + public static class Immutable extends ProjectivePoint implements ImmutablePoint { diff --git a/test/jdk/sun/security/ec/ed/EdECKeyFormat.java b/test/jdk/sun/security/ec/ed/EdECKeyFormat.java new file mode 100644 index 00000000000..81c1fbef14d --- /dev/null +++ b/test/jdk/sun/security/ec/ed/EdECKeyFormat.java @@ -0,0 +1,144 @@ +/* + * 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 8166597 + * @summary Check for correct formatting of EdDSA keys + * @library /test/lib + * @build jdk.test.lib.Convert + * @modules java.base/sun.security.util + * @run main EdECKeyFormat + */ + +import java.security.*; +import java.security.spec.*; +import java.security.interfaces.*; +import java.io.*; +import java.nio.file.*; +import java.math.*; +import java.util.*; + +import jdk.test.lib.Convert; + +import sun.security.util.*; + +public class EdECKeyFormat { + + private interface Test { + public void runTest(Provider p) throws Exception; + } + + private static void forEachProvider(Test t, String algName) + throws Exception { + + int tested = 0; + for (Provider p : Security.getProviders()) { + Provider.Service s = p.getService("KeyPairGenerator", algName); + if (s != null) { + t.runTest(p); + tested++; + } + } + if (tested == 0) { + throw new RuntimeException("no service found for " + algName); + } + } + + private static Map privKeys = Map.of( + "Ed25519", + "302e020100300506032b657004220420d4ee72dbf913584ad5b6d8f1f769f8ad3afe" + + "7c28cbf1d4fbe097a88f44755842", + "Ed448", + "3047020100300506032b6571043b043980998f387e05852d217c1d715b177c24aa7b" + + "f3f4c3a72223f4983597b9ab2ed4793c30d871c24388b380d80bb36d963f5c276219" + + "b0677fed00" + ); + + private static List pubKeys = List.of( + "302a300506032b657003210019bf44096984cdfe8541bac167dc3b96c85086aa30b6" + + "b6cb0c5c38ad703166e1" + ); + + public static void main(String[] args) throws Exception { + privKeyTest("Ed25519"); + privKeyTest("Ed448"); + pubKeyTest(); + } + + private static void pubKeyTest() throws Exception { + forEachProvider(EdECKeyFormat::pubKeyTest, "EdDSA"); + } + + private static void pubKeyTest(Provider p) throws Exception { + for (String s : pubKeys) { + pubKeyTest(p, s); + } + } + + private static void pubKeyTest(Provider p, String key) throws Exception { + // ensure that a properly-formatted key can be read + byte[] encodedKey = Convert.hexStringToByteArray(key); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encodedKey); + KeyFactory kf = KeyFactory.getInstance("EdDSA", p); + kf.generatePublic(keySpec); + } + + private static void privKeyTest(String algName) throws Exception { + + forEachProvider(p -> privKeyTest(algName, p), algName); + } + + private static void privKeyTest(String algName, Provider p) + throws Exception { + + System.out.println("Testing " + algName + " in " + p.getName()); + + // ensure format produced is correct + KeyPairGenerator kpg = KeyPairGenerator.getInstance(algName, p); + KeyPair kp = kpg.generateKeyPair(); + PrivateKey priv = kp.getPrivate(); + checkPrivKeyFormat(priv.getEncoded()); + KeyFactory kf = KeyFactory.getInstance(algName, p); + PKCS8EncodedKeySpec keySpec = + kf.getKeySpec(priv, PKCS8EncodedKeySpec.class); + checkPrivKeyFormat(keySpec.getEncoded()); + + // ensure that a properly-formatted key can be read + byte[] encodedKey = Convert.hexStringToByteArray(privKeys.get(algName)); + keySpec = new PKCS8EncodedKeySpec(encodedKey); + kf.generatePrivate(keySpec); + } + + private static void checkPrivKeyFormat(byte[] key) throws IOException { + // key value should be nested octet strings + DerValue val = new DerValue(new ByteArrayInputStream(key)); + BigInteger version = val.data.getBigInteger(); + DerValue algId = val.data.getDerValue(); + byte[] keyValue = val.data.getOctetString(); + val = new DerValue(new ByteArrayInputStream(keyValue)); + if (val.tag != DerValue.tag_OctetString) { + throw new RuntimeException("incorrect format"); + } + } +} diff --git a/test/jdk/sun/security/ec/ed/TestEdDSA.java b/test/jdk/sun/security/ec/ed/TestEdDSA.java new file mode 100644 index 00000000000..7c7e536757c --- /dev/null +++ b/test/jdk/sun/security/ec/ed/TestEdDSA.java @@ -0,0 +1,581 @@ +/* + * 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 8166597 + * @summary EdDSA Signature Known Answer Tests (KAT) from RFC 8032 + * @library /test/lib + * @build jdk.test.lib.Convert + * @run main TestEdDSA + */ + +import java.security.*; +import java.security.spec.*; +import java.util.*; +import jdk.test.lib.Convert; + +public class TestEdDSA { + + private static SecureRandom random = new SecureRandom(); + + public static void main(String[] args) throws Exception { + runBasicTests(); + runKAT(); + runCurveMixTest(); + } + + private static void runKAT() throws Exception { + + // "pure" Ed25519 + runSignTest("Ed25519", null, + "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60", + "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a", + "", + "e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e06522490155" + + "5fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b"); + + runSignTest("Ed25519", null, + "4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb", + "3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c", + "72", + "92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da" + + "085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00"); + + runSignTest("Ed25519", null, + "c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7", + "fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025", + "af82", + "6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac" + + "18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a"); + + runSignTest("Ed25519", null, + "f5e5767cf153319517630f226876b86c8160cc583bc013744c6bf255f5cc0ee5", + "278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e", + "08b8b2b733424243760fe426a4b54908632110a66c2f6591eabd3345e3e4eb98" + + "fa6e264bf09efe12ee50f8f54e9f77b1e355f6c50544e23fb1433ddf73be84d8" + + "79de7c0046dc4996d9e773f4bc9efe5738829adb26c81b37c93a1b270b20329d" + + "658675fc6ea534e0810a4432826bf58c941efb65d57a338bbd2e26640f89ffbc" + + "1a858efcb8550ee3a5e1998bd177e93a7363c344fe6b199ee5d02e82d522c4fe" + + "ba15452f80288a821a579116ec6dad2b3b310da903401aa62100ab5d1a36553e" + + "06203b33890cc9b832f79ef80560ccb9a39ce767967ed628c6ad573cb116dbef" + + "efd75499da96bd68a8a97b928a8bbc103b6621fcde2beca1231d206be6cd9ec7" + + "aff6f6c94fcd7204ed3455c68c83f4a41da4af2b74ef5c53f1d8ac70bdcb7ed1" + + "85ce81bd84359d44254d95629e9855a94a7c1958d1f8ada5d0532ed8a5aa3fb2" + + "d17ba70eb6248e594e1a2297acbbb39d502f1a8c6eb6f1ce22b3de1a1f40cc24" + + "554119a831a9aad6079cad88425de6bde1a9187ebb6092cf67bf2b13fd65f270" + + "88d78b7e883c8759d2c4f5c65adb7553878ad575f9fad878e80a0c9ba63bcbcc" + + "2732e69485bbc9c90bfbd62481d9089beccf80cfe2df16a2cf65bd92dd597b07" + + "07e0917af48bbb75fed413d238f5555a7a569d80c3414a8d0859dc65a46128ba" + + "b27af87a71314f318c782b23ebfe808b82b0ce26401d2e22f04d83d1255dc51a" + + "ddd3b75a2b1ae0784504df543af8969be3ea7082ff7fc9888c144da2af58429e" + + "c96031dbcad3dad9af0dcbaaaf268cb8fcffead94f3c7ca495e056a9b47acdb7" + + "51fb73e666c6c655ade8297297d07ad1ba5e43f1bca32301651339e22904cc8c" + + "42f58c30c04aafdb038dda0847dd988dcda6f3bfd15c4b4c4525004aa06eeff8" + + "ca61783aacec57fb3d1f92b0fe2fd1a85f6724517b65e614ad6808d6f6ee34df" + + "f7310fdc82aebfd904b01e1dc54b2927094b2db68d6f903b68401adebf5a7e08" + + "d78ff4ef5d63653a65040cf9bfd4aca7984a74d37145986780fc0b16ac451649" + + "de6188a7dbdf191f64b5fc5e2ab47b57f7f7276cd419c17a3ca8e1b939ae49e4" + + "88acba6b965610b5480109c8b17b80e1b7b750dfc7598d5d5011fd2dcc5600a3" + + "2ef5b52a1ecc820e308aa342721aac0943bf6686b64b2579376504ccc493d97e" + + "6aed3fb0f9cd71a43dd497f01f17c0e2cb3797aa2a2f256656168e6c496afc5f" + + "b93246f6b1116398a346f1a641f3b041e989f7914f90cc2c7fff357876e506b5" + + "0d334ba77c225bc307ba537152f3f1610e4eafe595f6d9d90d11faa933a15ef1" + + "369546868a7f3a45a96768d40fd9d03412c091c6315cf4fde7cb68606937380d" + + "b2eaaa707b4c4185c32eddcdd306705e4dc1ffc872eeee475a64dfac86aba41c" + + "0618983f8741c5ef68d3a101e8a3b8cac60c905c15fc910840b94c00a0b9d0", + "0aab4c900501b3e24d7cdf4663326a3a87df5e4843b2cbdb67cbf6e460fec350" + + "aa5371b1508f9f4528ecea23c436d94b5e8fcd4f681e30a6ac00a9704a188a03"); + + runSignTest("Ed25519", null, + "833fe62409237b9d62ec77587520911e9a759cec1d19755b7da901b96dca3d42", + "ec172b93ad5e563bf4932c70e1245034c35467ef2efd4d64ebf819683467e2bf", + "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a" + + "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f", + "dc2a4459e7369633a52b1bf277839a00201009a3efbf3ecb69bea2186c26b589" + + "09351fc9ac90b3ecfdfbc7c66431e0303dca179c138ac17ad9bef1177331a704"); + + // Ed25519ctx + byte[] context = Convert.hexStringToByteArray("666f6f"); + runSignTest("Ed25519", new EdDSAParameterSpec(false, context), + "0305334e381af78f141cb666f6199f57bc3495335a256a95bd2a55bf546663f6", + "dfc9425e4f968f7f0c29f0259cf5f9aed6851c2bb4ad8bfb860cfee0ab248292", + "f726936d19c800494e3fdaff20b276a8", + "55a4cc2f70a54e04288c5f4cd1e45a7bb520b36292911876cada7323198dd87a" + + "8b36950b95130022907a7fb7c4e9b2d5f6cca685a587b4b21f4b888e4e7edb0d"); + + context = Convert.hexStringToByteArray("626172"); + runSignTest("Ed25519", new EdDSAParameterSpec(false, context), + "0305334e381af78f141cb666f6199f57bc3495335a256a95bd2a55bf546663f6", + "dfc9425e4f968f7f0c29f0259cf5f9aed6851c2bb4ad8bfb860cfee0ab248292", + "f726936d19c800494e3fdaff20b276a8", + "fc60d5872fc46b3aa69f8b5b4351d5808f92bcc044606db097abab6dbcb1aee3" + + "216c48e8b3b66431b5b186d1d28f8ee15a5ca2df6668346291c2043d4eb3e90d"); + + context = Convert.hexStringToByteArray("666f6f"); + runSignTest("Ed25519", new EdDSAParameterSpec(false, context), + "0305334e381af78f141cb666f6199f57bc3495335a256a95bd2a55bf546663f6", + "dfc9425e4f968f7f0c29f0259cf5f9aed6851c2bb4ad8bfb860cfee0ab248292", + "508e9e6882b979fea900f62adceaca35", + "8b70c1cc8310e1de20ac53ce28ae6e7207f33c3295e03bb5c0732a1d20dc6490" + + "8922a8b052cf99b7c4fe107a5abb5b2c4085ae75890d02df26269d8945f84b0b"); + + context = Convert.hexStringToByteArray("666f6f"); + runSignTest("Ed25519", new EdDSAParameterSpec(false, context), + "ab9c2853ce297ddab85c993b3ae14bcad39b2c682beabc27d6d4eb20711d6560", + "0f1d1274943b91415889152e893d80e93275a1fc0b65fd71b4b0dda10ad7d772", + "f726936d19c800494e3fdaff20b276a8", + "21655b5f1aa965996b3f97b3c849eafba922a0a62992f73b3d1b73106a84ad85" + + "e9b86a7b6005ea868337ff2d20a7f5fbd4cd10b0be49a68da2b2e0dc0ad8960f"); + + // Ed25519ph + runSignTest("Ed25519", new EdDSAParameterSpec(true), + "833fe62409237b9d62ec77587520911e9a759cec1d19755b7da901b96dca3d42", + "ec172b93ad5e563bf4932c70e1245034c35467ef2efd4d64ebf819683467e2bf", + "616263", + "98a70222f0b8121aa9d30f813d683f809e462b469c7ff87639499bb94e6dae41" + + "31f85042463c2a355a2003d062adf5aaa10b8c61e636062aaad11c2a26083406"); + + // Ed448 + runSignTest("Ed448", null, + "6c82a562cb808d10d632be89c8513ebf6c929f34ddfa8c9f63c9960ef6e348a3" + + "528c8a3fcc2f044e39a3fc5b94492f8f032e7549a20098f95b", + "5fd7449b59b461fd2ce787ec616ad46a1da1342485a70e1f8a0ea75d80e96778" + + "edf124769b46c7061bd6783df1e50f6cd1fa1abeafe8256180", + "", + "533a37f6bbe457251f023c0d88f976ae2dfb504a843e34d2074fd823d41a591f" + + "2b233f034f628281f2fd7a22ddd47d7828c59bd0a21bfd3980ff0d2028d4b18a" + + "9df63e006c5d1c2d345b925d8dc00b4104852db99ac5c7cdda8530a113a0f4db" + + "b61149f05a7363268c71d95808ff2e652600"); + + runSignTest("Ed448", null, + "c4eab05d357007c632f3dbb48489924d552b08fe0c353a0d4a1f00acda2c463a" + + "fbea67c5e8d2877c5e3bc397a659949ef8021e954e0a12274e", + "43ba28f430cdff456ae531545f7ecd0ac834a55d9358c0372bfa0c6c6798c086" + + "6aea01eb00742802b8438ea4cb82169c235160627b4c3a9480", + "03", + "26b8f91727bd62897af15e41eb43c377efb9c610d48f2335cb0bd0087810f435" + + "2541b143c4b981b7e18f62de8ccdf633fc1bf037ab7cd779805e0dbcc0aae1cb" + + "cee1afb2e027df36bc04dcecbf154336c19f0af7e0a6472905e799f1953d2a0f" + + "f3348ab21aa4adafd1d234441cf807c03a00"); + + context = Convert.hexStringToByteArray("666f6f"); + runSignTest("Ed448", new EdDSAParameterSpec(false, context), + "c4eab05d357007c632f3dbb48489924d552b08fe0c353a0d4a1f00acda2c463a" + + "fbea67c5e8d2877c5e3bc397a659949ef8021e954e0a12274e", + "43ba28f430cdff456ae531545f7ecd0ac834a55d9358c0372bfa0c6c6798c086" + + "6aea01eb00742802b8438ea4cb82169c235160627b4c3a9480", + "03", + "d4f8f6131770dd46f40867d6fd5d5055de43541f8c5e35abbcd001b32a89f7d2" + + "151f7647f11d8ca2ae279fb842d607217fce6e042f6815ea000c85741de5" + + "c8da1144a6a1aba7f96de42505d7a7298524fda538fccbbb754f578c1cad" + + "10d54d0d5428407e85dcbc98a49155c13764e66c3c00"); + + runSignTest("Ed448", null, + "cd23d24f714274e744343237b93290f511f6425f98e64459ff203e898508" + + "3ffdf60500553abc0e05cd02184bdb89c4ccd67e187951267eb328", + "dcea9e78f35a1bf3499a831b10b86c90aac01cd84b67a0109b55a36e9328" + + "b1e365fce161d71ce7131a543ea4cb5f7e9f1d8b00696447001400", + "0c3e544074ec63b0265e0c", + "1f0a8888ce25e8d458a21130879b840a9089d999aaba039eaf3e3afa090a09d3" + + "89dba82c4ff2ae8ac5cdfb7c55e94d5d961a29fe0109941e00b8dbdeea6d3b05" + + "1068df7254c0cdc129cbe62db2dc957dbb47b51fd3f213fb8698f064774250a5" + + "028961c9bf8ffd973fe5d5c206492b140e00"); + + runSignTest("Ed448", null, + "258cdd4ada32ed9c9ff54e63756ae582fb8fab2ac721f2c8e676a72768513d93" + + "9f63dddb55609133f29adf86ec9929dccb52c1c5fd2ff7e21b", + "3ba16da0c6f2cc1f30187740756f5e798d6bc5fc015d7c63cc9510ee3fd44adc" + + "24d8e968b6e46e6f94d19b945361726bd75e149ef09817f580", + "64a65f3cdedcdd66811e2915", + "7eeeab7c4e50fb799b418ee5e3197ff6bf15d43a14c34389b59dd1a7b1b85b4ae904" + + "38aca634bea45e3a2695f1270f07fdcdf7c62b8efeaf00b45c2c96ba457eb1a8" + + "bf075a3db28e5c24f6b923ed4ad747c3c9e03c7079efb87cb110d3a99861e720" + + "03cbae6d6b8b827e4e6c143064ff3c00"); + + runSignTest("Ed448", null, + "7ef4e84544236752fbb56b8f31a23a10e42814f5f55ca037cdcc11c64c9a3b29" + + "49c1bb60700314611732a6c2fea98eebc0266a11a93970100e", + "b3da079b0aa493a5772029f0467baebee5a8112d9d3a22532361da294f7bb381" + + "5c5dc59e176b4d9f381ca0938e13c6c07b174be65dfa578e80", + "64a65f3cdedcdd66811e2915e7", + "6a12066f55331b6c22acd5d5bfc5d71228fbda80ae8dec26bdd306743c5027cb" + + "4890810c162c027468675ecf645a83176c0d7323a2ccde2d80efe5a1268e" + + "8aca1d6fbc194d3f77c44986eb4ab4177919ad8bec33eb47bbb5fc6e2819" + + "6fd1caf56b4e7e0ba5519234d047155ac727a1053100"); + + runSignTest("Ed448", null, + "d65df341ad13e008567688baedda8e9dcdc17dc024974ea5b4227b6530e339bf" + + "f21f99e68ca6968f3cca6dfe0fb9f4fab4fa135d5542ea3f01", + "df9705f58edbab802c7f8363cfe5560ab1c6132c20a9f1dd163483a26f8ac53a" + + "39d6808bf4a1dfbd261b099bb03b3fb50906cb28bd8a081f00", + "bd0f6a3747cd561bdddf4640a332461a4a30a12a434cd0bf40d766d9c6d458e5" + + "512204a30c17d1f50b5079631f64eb3112182da3005835461113718d1a5ef944", + "554bc2480860b49eab8532d2a533b7d578ef473eeb58c98bb2d0e1ce488a98b1" + + "8dfde9b9b90775e67f47d4a1c3482058efc9f40d2ca033a0801b63d45b3b722e" + + "f552bad3b4ccb667da350192b61c508cf7b6b5adadc2c8d9a446ef003fb05cba" + + "5f30e88e36ec2703b349ca229c2670833900"); + + runSignTest("Ed448", new EdDSAParameterSpec(false), + "2ec5fe3c17045abdb136a5e6a913e32ab75ae68b53d2fc149b77e504132d3756" + + "9b7e766ba74a19bd6162343a21c8590aa9cebca9014c636df5", + "79756f014dcfe2079f5dd9e718be4171e2ef2486a08f25186f6bff43a9936b9b" + + "fe12402b08ae65798a3d81e22e9ec80e7690862ef3d4ed3a00", + "15777532b0bdd0d1389f636c5f6b9ba734c90af572877e2d272dd078aa1e567c" + + "fa80e12928bb542330e8409f3174504107ecd5efac61ae7504dabe2a602ede89" + + "e5cca6257a7c77e27a702b3ae39fc769fc54f2395ae6a1178cab4738e543072f" + + "c1c177fe71e92e25bf03e4ecb72f47b64d0465aaea4c7fad372536c8ba516a60" + + "39c3c2a39f0e4d832be432dfa9a706a6e5c7e19f397964ca4258002f7c0541b5" + + "90316dbc5622b6b2a6fe7a4abffd96105eca76ea7b98816af0748c10df048ce0" + + "12d901015a51f189f3888145c03650aa23ce894c3bd889e030d565071c59f409" + + "a9981b51878fd6fc110624dcbcde0bf7a69ccce38fabdf86f3bef6044819de11", + "c650ddbb0601c19ca11439e1640dd931f43c518ea5bea70d3dcde5f4191fe53f" + + "00cf966546b72bcc7d58be2b9badef28743954e3a44a23f880e8d4f1cfce2d7a" + + "61452d26da05896f0a50da66a239a8a188b6d825b3305ad77b73fbac0836ecc6" + + "0987fd08527c1a8e80d5823e65cafe2a3d00"); + + runSignTest("Ed448", null, + "872d093780f5d3730df7c212664b37b8a0f24f56810daa8382cd4f" + + "a3f77634ec44dc54f1c2ed9bea86fafb7632d8be199ea165f5ad55dd9ce8", + "a81b2e8a70a5ac94ffdbcc9badfc3feb0801f258578bb114ad44ece" + + "1ec0e799da08effb81c5d685c0c56f64eecaef8cdf11cc38737838cf400", + "6ddf802e1aae4986935f7f981ba3f0351d6273c0a0c22c9c0e8339168e675412" + + "a3debfaf435ed651558007db4384b650fcc07e3b586a27a4f7a00ac8a6fec2cd" + + "86ae4bf1570c41e6a40c931db27b2faa15a8cedd52cff7362c4e6e23daec0fbc" + + "3a79b6806e316efcc7b68119bf46bc76a26067a53f296dafdbdc11c77f7777e9" + + "72660cf4b6a9b369a6665f02e0cc9b6edfad136b4fabe723d2813db3136cfde9" + + "b6d044322fee2947952e031b73ab5c603349b307bdc27bc6cb8b8bbd7bd32321" + + "9b8033a581b59eadebb09b3c4f3d2277d4f0343624acc817804728b25ab79717" + + "2b4c5c21a22f9c7839d64300232eb66e53f31c723fa37fe387c7d3e50bdf9813" + + "a30e5bb12cf4cd930c40cfb4e1fc622592a49588794494d56d24ea4b40c89fc0" + + "596cc9ebb961c8cb10adde976a5d602b1c3f85b9b9a001ed3c6a4d3b1437f520" + + "96cd1956d042a597d561a596ecd3d1735a8d570ea0ec27225a2c4aaff26306d1" + + "526c1af3ca6d9cf5a2c98f47e1c46db9a33234cfd4d81f2c98538a09ebe76998" + + "d0d8fd25997c7d255c6d66ece6fa56f11144950f027795e653008f4bd7ca2dee" + + "85d8e90f3dc315130ce2a00375a318c7c3d97be2c8ce5b6db41a6254ff264fa6" + + "155baee3b0773c0f497c573f19bb4f4240281f0b1f4f7be857a4e59d416c06b4" + + "c50fa09e1810ddc6b1467baeac5a3668d11b6ecaa901440016f389f80acc4db9" + + "77025e7f5924388c7e340a732e554440e76570f8dd71b7d640b3450d1fd5f041" + + "0a18f9a3494f707c717b79b4bf75c98400b096b21653b5d217cf3565c9597456" + + "f70703497a078763829bc01bb1cbc8fa04eadc9a6e3f6699587a9e75c94e5bab" + + "0036e0b2e711392cff0047d0d6b05bd2a588bc109718954259f1d86678a579a3" + + "120f19cfb2963f177aeb70f2d4844826262e51b80271272068ef5b3856fa8535" + + "aa2a88b2d41f2a0e2fda7624c2850272ac4a2f561f8f2f7a318bfd5caf969614" + + "9e4ac824ad3460538fdc25421beec2cc6818162d06bbed0c40a387192349db67" + + "a118bada6cd5ab0140ee273204f628aad1c135f770279a651e24d8c14d75a605" + + "9d76b96a6fd857def5e0b354b27ab937a5815d16b5fae407ff18222c6d1ed263" + + "be68c95f32d908bd895cd76207ae726487567f9a67dad79abec316f683b17f2d" + + "02bf07e0ac8b5bc6162cf94697b3c27cd1fea49b27f23ba2901871962506520c" + + "392da8b6ad0d99f7013fbc06c2c17a569500c8a7696481c1cd33e9b14e40b82e" + + "79a5f5db82571ba97bae3ad3e0479515bb0e2b0f3bfcd1fd33034efc6245eddd" + + "7ee2086ddae2600d8ca73e214e8c2b0bdb2b047c6a464a562ed77b73d2d841c4" + + "b34973551257713b753632efba348169abc90a68f42611a40126d7cb21b58695" + + "568186f7e569d2ff0f9e745d0487dd2eb997cafc5abf9dd102e62ff66cba87", + "e301345a41a39a4d72fff8df69c98075a0cc082b802fc9b2b6bc503f926b65bd" + + "df7f4c8f1cb49f6396afc8a70abe6d8aef0db478d4c6b2970076c6a0484fe76d" + + "76b3a97625d79f1ce240e7c576750d295528286f719b413de9ada3e8eb78ed57" + + "3603ce30d8bb761785dc30dbc320869e1a00"); + + runSignTest("Ed448", new EdDSAParameterSpec(true), + "833fe62409237b9d62ec77587520911e9a759cec1d19755b7da901" + + "b96dca3d42ef7822e0d5104127dc05d6dbefde69e3ab2cec7c867c6e2c49", + "259b71c19f83ef77a7abd26524cbdb3161b590a48f7d17de3ee0ba9" + + "c52beb743c09428a131d6b1b57303d90d8132c276d5ed3d5d01c0f53880", + "616263", + "822f6901f7480f3d5f562c592994d9693602875614483256505600bbc281ae38" + + "1f54d6bce2ea911574932f52a4e6cadd78769375ec3ffd1b801a0d9b3f4030cd" + + "433964b6457ea39476511214f97469b57dd32dbc560a9a94d00bff07620464a3" + + "ad203df7dc7ce360c3cd3696d9d9fab90f00"); + + runSignTest("Ed448", new EdDSAParameterSpec(true, context), + "833fe62409237b9d62ec77587520911e9a759cec1d19755b7da901b96dca3d42" + + "ef7822e0d5104127dc05d6dbefde69e3ab2cec7c867c6e2c49", + "259b71c19f83ef77a7abd26524cbdb3161b590a48f7d17de3ee0ba9c52beb743" + + "c09428a131d6b1b57303d90d8132c276d5ed3d5d01c0f53880", + "616263", + "c32299d46ec8ff02b54540982814dce9a05812f81962b649d528095916a2aa48" + + "1065b1580423ef927ecf0af5888f90da0f6a9a85ad5dc3f280d91224ba9911a3" + + "653d00e484e2ce232521481c8658df304bb7745a73514cdb9bf3e15784ab7128" + + "4f8d0704a608c54a6b62d97beb511d132100"); + + System.out.println("All test vectors passed"); + } + + private static void runSignTest(String algorithm, + AlgorithmParameterSpec params, String privateKey, String publicKey, + String message, String signature) throws Exception { + + byte[] privKeyBytes = Convert.hexStringToByteArray(privateKey); + EdECPoint pubKeyPoint = Convert.hexStringToEdPoint(publicKey); + byte[] msgBytes = Convert.hexStringToByteArray(message); + byte[] computedSig; + + NamedParameterSpec namedSpec = new NamedParameterSpec(algorithm); + EdECPrivateKeySpec privKeySpec = + new EdECPrivateKeySpec(namedSpec, privKeyBytes); + KeyFactory kf = KeyFactory.getInstance(algorithm); + PrivateKey privKey = kf.generatePrivate(privKeySpec); + Signature sig = Signature.getInstance(algorithm); + if (params != null) { + sig.setParameter(params); + } + sig.initSign(privKey); + sig.update(msgBytes); + computedSig = sig.sign(); + if (!Arrays.equals(computedSig, + Convert.hexStringToByteArray(signature))) { + throw new RuntimeException("Incorrect signature"); + } + + // test verification + sig = Signature.getInstance(algorithm); + if (params != null) { + sig.setParameter(params); + } + EdECPublicKeySpec pubKeySpec = + new EdECPublicKeySpec(namedSpec, pubKeyPoint); + PublicKey pubKey = kf.generatePublic(pubKeySpec); + sig.initVerify(pubKey); + sig.update(msgBytes); + if (!sig.verify(computedSig)) { + throw new RuntimeException("Signature did not verify"); + } + } + + + private static void runBasicTests() throws Exception { + runBasicTest("EdDSA", null); + + runBasicTest("EdDSA", 255); + runBasicTest("EdDSA", "Ed25519"); + runBasicTest("Ed25519", null); + runBasicTest("1.3.101.112", null); + runBasicTest("OID.1.3.101.112", null); + + runBasicTest("EdDSA", 448); + runBasicTest("EdDSA", "Ed448"); + runBasicTest("Ed448", null); + runBasicTest("1.3.101.113", null); + runBasicTest("OID.1.3.101.113", null); + } + + private static void runBasicTest(String name, Object param) + throws Exception { + + KeyPairGenerator kpg = KeyPairGenerator.getInstance(name); + if (param instanceof Integer) { + kpg.initialize((Integer) param, random); + } else if (param instanceof String) { + kpg.initialize(new NamedParameterSpec((String) param), random); + } + KeyPair kp = kpg.generateKeyPair(); + + Signature sig = Signature.getInstance(name); + sig.initSign(kp.getPrivate()); + byte[] testMessage = new byte[1024]; + random.nextBytes(testMessage); + sig.update(testMessage); + byte[] msgSig = sig.sign(); + + // sign again, should return false + byte[] x = sig.sign(); + if (Arrays.compare(msgSig, x) == 0) { + throw new RuntimeException("Second sign identical, didn't reset"); + } + + // verify the signature + sig.initVerify(kp.getPublic()); + sig.update(testMessage); + if (!sig.verify(msgSig)) { + throw new RuntimeException("Valid signature did not verify"); + } + + // verify again, should return false + if (sig.verify(msgSig)) { + throw new RuntimeException("Second verify succeeded, didn't reset"); + } + + // try verifying an incorrect signature + testMessage[0] ^= (byte) 0x01; + sig.update(testMessage); + if (sig.verify(msgSig)) { + throw new RuntimeException("Invalid signature verified"); + } + + KeyFactory kf = KeyFactory.getInstance(name); + // Test with X509 and PKCS8 key specs + X509EncodedKeySpec pubSpec = + kf.getKeySpec(kp.getPublic(), X509EncodedKeySpec.class); + PKCS8EncodedKeySpec priSpec = + kf.getKeySpec(kp.getPrivate(), PKCS8EncodedKeySpec.class); + + PublicKey pubKey = kf.generatePublic(pubSpec); + PrivateKey priKey = kf.generatePrivate(priSpec); + + sig.initSign(priKey); + sig.update(testMessage); + msgSig = sig.sign(); + sig.initVerify(pubKey); + sig.update(testMessage); + if (!sig.verify(msgSig)) { + throw new RuntimeException("Valid signature did not verify"); + } + + // test with EdEC key specs + EdECPublicKeySpec edPublic = + kf.getKeySpec(kp.getPublic(), EdECPublicKeySpec.class); + EdECPrivateKeySpec edPrivate = + kf.getKeySpec(kp.getPrivate(), EdECPrivateKeySpec.class); + PublicKey pubKey2 = kf.generatePublic(edPublic); + PrivateKey priKey2 = kf.generatePrivate(edPrivate); + sig.initSign(priKey2); + sig.update(testMessage); + msgSig = sig.sign(); + sig.initVerify(pubKey2); + sig.update(testMessage); + if (!sig.verify(msgSig)) { + throw new RuntimeException("Valid signature did not verify"); + } + } + + /* + * Ensure that SunEC rejects parameters/points for the wrong curve + * when the algorithm ID for a specific curve is specified. + */ + private static void runCurveMixTest() throws Exception { + runCurveMixTest("SunEC", "Ed25519", 448); + runCurveMixTest("SunEC", "Ed25519", "Ed448"); + runCurveMixTest("SunEC", "Ed448", 255); + runCurveMixTest("SunEC", "Ed448", "Ed25519"); + } + + private static void runCurveMixTest(String providerName, String name, + Object param) throws Exception { + + KeyPairGenerator kpg = KeyPairGenerator.getInstance(name, + providerName); + + try { + if (param instanceof Integer) { + kpg.initialize((Integer) param); + } else if (param instanceof String) { + kpg.initialize(new NamedParameterSpec((String) param)); + } + throw new RuntimeException(name + " KeyPairGenerator accepted " + + param.toString() + " parameters"); + } catch (InvalidParameterException ex) { + if (param instanceof String) { + throw new RuntimeException( + "InvalidAlgorithmParameterException expected", ex); + } + // expected + + } catch (InvalidAlgorithmParameterException ex) { + if (param instanceof Integer) { + throw new RuntimeException("InvalidParameterException expected", + ex); + } + // expected + } + + // the rest of the test uses the parameter as an algorithm name to + // produce keys + if (param instanceof Integer) { + return; + } + String otherName = (String) param; + KeyPairGenerator otherKpg = KeyPairGenerator.getInstance(otherName, + providerName); + KeyPair otherKp = otherKpg.generateKeyPair(); + + // ensure the KeyFactory rejects incorrect keys + KeyFactory kf = KeyFactory.getInstance(name, providerName); + try { + kf.getKeySpec(otherKp.getPublic(), EdECPublicKeySpec.class); + throw new RuntimeException(name + " KeyFactory accepted " + + param.toString() + " key"); + } catch (InvalidKeySpecException ex) { + // expected + } + try { + kf.getKeySpec(otherKp.getPrivate(), EdECPrivateKeySpec.class); + throw new RuntimeException(name + " KeyFactory accepted " + + param.toString() + " key"); + } catch (InvalidKeySpecException ex) { + // expected + } + + try { + kf.translateKey(otherKp.getPublic()); + throw new RuntimeException(name + " KeyFactory accepted " + + param.toString() + " key"); + } catch (InvalidKeyException ex) { + // expected + } + try { + kf.translateKey(otherKp.getPrivate()); + throw new RuntimeException(name + " KeyFactory accepted " + + param.toString() + " key"); + } catch (InvalidKeyException ex) { + // expected + } + + KeyFactory otherKf = KeyFactory.getInstance(otherName, providerName); + EdECPublicKeySpec otherPubSpec = otherKf.getKeySpec(otherKp.getPublic(), + EdECPublicKeySpec.class); + try { + kf.generatePublic(otherPubSpec); + throw new RuntimeException(name + " KeyFactory accepted " + + param.toString() + " key"); + } catch (InvalidKeySpecException ex) { + // expected + } + EdECPrivateKeySpec otherPriSpec = + otherKf.getKeySpec(otherKp.getPrivate(), EdECPrivateKeySpec.class); + try { + kf.generatePrivate(otherPriSpec); + throw new RuntimeException(name + " KeyFactory accepted " + + param.toString() + " key"); + } catch (InvalidKeySpecException ex) { + // expected + } + + // ensure the Signature rejects incorrect keys + Signature sig = Signature.getInstance(name, providerName); + try { + sig.initSign(otherKp.getPrivate()); + throw new RuntimeException(name + " Signature accepted " + + param.toString() + " signing key"); + } catch (InvalidKeyException ex) { + // expected + } + + try { + sig.initVerify(otherKp.getPublic()); + throw new RuntimeException(name + " Signature accepted " + + param.toString() + " verification key"); + } catch (InvalidKeyException ex) { + // expected + } + } +} diff --git a/test/jdk/sun/security/ec/ed/TestEdOps.java b/test/jdk/sun/security/ec/ed/TestEdOps.java new file mode 100644 index 00000000000..b67577cec4f --- /dev/null +++ b/test/jdk/sun/security/ec/ed/TestEdOps.java @@ -0,0 +1,291 @@ +/* + * 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 8166597 + * @summary Test EdDSA basic operations + * @library /test/lib + * @build jdk.test.lib.Convert + * @modules java.base/sun.security.provider + * java.base/sun.security.util + * java.base/sun.security.util.math + * java.base/sun.security.util.math.intpoly + * jdk.crypto.ec/sun.security.ec.ed + * @run main TestEdOps + */ + +import sun.security.ec.ed.*; +import java.security.*; +import java.security.spec.*; +import java.util.Arrays; +import sun.security.provider.SHAKE256; +import jdk.test.lib.Convert; + +public class TestEdOps { + + public static void main(String[] args) throws Exception { + + testShake(); + testVectors(); + testRandom(1000); + testInvalidPoints(); + } + + private static void testShake() { + + runShakeTest(32, "765db6ab3af389b8c775c8eb99fe72", + "ccb6564a655c94d714f80b9f8de9e2610c4478778eac1b9256237dbf90e50581"); + + runShakeTest(32, + "0e3dcd346c68bc5b5cafe3342a7e0e29272e42fba12a51081251abca989c77a1" + + "a501e2", + "c934ab7f2148da5ca2ce948432fa72be49420f10e3dbc1906016773d9819cff4"); + + runShakeTest(32, + "7e4c74f480e60565fe39e483b5204e24753841dec9ef3ec0dadd4e3f91584373" + + "fc424084f3267b5ffb8342ad6a683c05cc41f26086f18dceb921e1", + "a6450836c02f8fdfe841fbcb4b4fc7dca9bd56019b92582095ee5d11eca45fa0"); + + System.out.println("SHAKE256 tests passed"); + } + + private static void runShakeTest(int outputLen, String msg, String digest) { + byte[] msgBytes = Convert.hexStringToByteArray(msg); + byte[] digestBytes = Convert.hexStringToByteArray(digest); + SHAKE256 md = new SHAKE256(outputLen); + md.update(msgBytes, 0, msgBytes.length); + byte[] computed = md.digest(); + if (!Arrays.equals(digestBytes, computed)) { + throw new RuntimeException("hash is incorrect"); + } + } + + private static void testVectors() throws Exception { + EdDSAParameters ed25519Params = EdDSAParameters.get( + RuntimeException::new, NamedParameterSpec.ED25519); + EdDSAOperations ops = new EdDSAOperations(ed25519Params); + + runSignTest(ops, + "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60", + "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a", + "", + "e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e06522490155" + + "5fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b"); + + runSignTest(ops, + "4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb", + "3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c", + "72", + "92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da" + + "085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00"); + + runSignTest(ops, + "c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7", + "fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025", + "af82", + "6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac" + + "18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a"); + + runSignTest(ops, + "f5e5767cf153319517630f226876b86c8160cc583bc013744c6bf255f5cc0ee5", + "278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e", + "08b8b2b733424243760fe426a4b54908632110a66c2f6591eabd3345e3e4eb98" + + "fa6e264bf09efe12ee50f8f54e9f77b1e355f6c50544e23fb1433ddf73be84d8" + + "79de7c0046dc4996d9e773f4bc9efe5738829adb26c81b37c93a1b270b20329d" + + "658675fc6ea534e0810a4432826bf58c941efb65d57a338bbd2e26640f89ffbc" + + "1a858efcb8550ee3a5e1998bd177e93a7363c344fe6b199ee5d02e82d522c4fe" + + "ba15452f80288a821a579116ec6dad2b3b310da903401aa62100ab5d1a36553e" + + "06203b33890cc9b832f79ef80560ccb9a39ce767967ed628c6ad573cb116dbef" + + "efd75499da96bd68a8a97b928a8bbc103b6621fcde2beca1231d206be6cd9ec7" + + "aff6f6c94fcd7204ed3455c68c83f4a41da4af2b74ef5c53f1d8ac70bdcb7ed1" + + "85ce81bd84359d44254d95629e9855a94a7c1958d1f8ada5d0532ed8a5aa3fb2" + + "d17ba70eb6248e594e1a2297acbbb39d502f1a8c6eb6f1ce22b3de1a1f40cc24" + + "554119a831a9aad6079cad88425de6bde1a9187ebb6092cf67bf2b13fd65f270" + + "88d78b7e883c8759d2c4f5c65adb7553878ad575f9fad878e80a0c9ba63bcbcc" + + "2732e69485bbc9c90bfbd62481d9089beccf80cfe2df16a2cf65bd92dd597b07" + + "07e0917af48bbb75fed413d238f5555a7a569d80c3414a8d0859dc65a46128ba" + + "b27af87a71314f318c782b23ebfe808b82b0ce26401d2e22f04d83d1255dc51a" + + "ddd3b75a2b1ae0784504df543af8969be3ea7082ff7fc9888c144da2af58429e" + + "c96031dbcad3dad9af0dcbaaaf268cb8fcffead94f3c7ca495e056a9b47acdb7" + + "51fb73e666c6c655ade8297297d07ad1ba5e43f1bca32301651339e22904cc8c" + + "42f58c30c04aafdb038dda0847dd988dcda6f3bfd15c4b4c4525004aa06eeff8" + + "ca61783aacec57fb3d1f92b0fe2fd1a85f6724517b65e614ad6808d6f6ee34df" + + "f7310fdc82aebfd904b01e1dc54b2927094b2db68d6f903b68401adebf5a7e08" + + "d78ff4ef5d63653a65040cf9bfd4aca7984a74d37145986780fc0b16ac451649" + + "de6188a7dbdf191f64b5fc5e2ab47b57f7f7276cd419c17a3ca8e1b939ae49e4" + + "88acba6b965610b5480109c8b17b80e1b7b750dfc7598d5d5011fd2dcc5600a3" + + "2ef5b52a1ecc820e308aa342721aac0943bf6686b64b2579376504ccc493d97e" + + "6aed3fb0f9cd71a43dd497f01f17c0e2cb3797aa2a2f256656168e6c496afc5f" + + "b93246f6b1116398a346f1a641f3b041e989f7914f90cc2c7fff357876e506b5" + + "0d334ba77c225bc307ba537152f3f1610e4eafe595f6d9d90d11faa933a15ef1" + + "369546868a7f3a45a96768d40fd9d03412c091c6315cf4fde7cb68606937380d" + + "b2eaaa707b4c4185c32eddcdd306705e4dc1ffc872eeee475a64dfac86aba41c" + + "0618983f8741c5ef68d3a101e8a3b8cac60c905c15fc910840b94c00a0b9d0", + "0aab4c900501b3e24d7cdf4663326a3a87df5e4843b2cbdb67cbf6e460fec350" + + "aa5371b1508f9f4528ecea23c436d94b5e8fcd4f681e30a6ac00a9704a188a03"); + + runSignTest(ops, + "833fe62409237b9d62ec77587520911e9a759cec1d19755b7da901b96dca3d42", + "ec172b93ad5e563bf4932c70e1245034c35467ef2efd4d64ebf819683467e2bf", + "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a" + + "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f", + "dc2a4459e7369633a52b1bf277839a00201009a3efbf3ecb69bea2186c26b589" + + "09351fc9ac90b3ecfdfbc7c66431e0303dca179c138ac17ad9bef1177331a704"); + + + EdDSAParameters ed448Params = EdDSAParameters.get(RuntimeException::new, + NamedParameterSpec.ED448); + EdDSAOperations ed448Ops = new EdDSAOperations(ed448Params); + + runSignTest(ed448Ops, + "c4eab05d357007c632f3dbb48489924d552b08fe0c353a0d4a1f00acda2c463a" + + "fbea67c5e8d2877c5e3bc397a659949ef8021e954e0a12274e", + "43ba28f430cdff456ae531545f7ecd0ac834a55d9358c0372bfa0c6c6798c086" + + "6aea01eb00742802b8438ea4cb82169c235160627b4c3a9480", + "03", + "26b8f91727bd62897af15e41eb43c377efb9c610d48f2335cb0bd0087810f435" + + "2541b143c4b981b7e18f62de8ccdf633fc1bf037ab7cd779805e0dbcc0aae1cb" + + "cee1afb2e027df36bc04dcecbf154336c19f0af7e0a6472905e799f1953d2a0f" + + "f3348ab21aa4adafd1d234441cf807c03a00"); + + System.out.println("All test vectors passed"); + } + + private static void runSignTest(EdDSAOperations ops, String privateKey, + String publicKey, String message, + String signature) throws Exception { + + EdDSAParameterSpec sigParams = new EdDSAParameterSpec(false); + + byte[] privKeyBytes = Convert.hexStringToByteArray(privateKey); + byte[] pubKeyBytes = Convert.hexStringToByteArray(publicKey); + byte[] msgBytes = Convert.hexStringToByteArray(message); + byte[] computedSig = ops.sign(sigParams, privKeyBytes, msgBytes); + if (!Arrays.equals(computedSig, + Convert.hexStringToByteArray(signature))) { + throw new RuntimeException("Incorrect signature: " + + Convert.byteArrayToHexString(computedSig) + " != " + signature); + } + // Test public key computation + EdECPoint pubPoint = ops.computePublic(privKeyBytes); + EdDSAPublicKeyImpl pubKey = + new EdDSAPublicKeyImpl(ops.getParameters(), pubPoint); + byte[] computedPubKey = pubKey.getEncodedPoint(); + if (!Arrays.equals(computedPubKey, pubKeyBytes)) { + throw new RuntimeException("Incorrect public key"); + } + + // test verification + ops.verify(sigParams, pubKeyBytes, msgBytes, computedSig); + } + + private static void testRandom(int count) throws Exception { + + EdDSAParameterSpec sigParams = new EdDSAParameterSpec(false); + SecureRandom random = SecureRandom.getInstance("SHA1PRNG"); + random.setSeed(1); + + EdDSAParameters params = EdDSAParameters.get(RuntimeException::new, + NamedParameterSpec.ED25519); + EdDSAOperations ops = new EdDSAOperations(params); + + long startTime = System.currentTimeMillis(); + + for (int i = 0; i < count; i++) { + byte[] privKey = ops.generatePrivate(random); + byte[] message = new byte[1024]; + random.nextBytes(message); + byte[] sig = ops.sign(sigParams, privKey, message); + + EdECPoint pubKeyPoint = ops.computePublic(privKey); + EdDSAPublicKeyImpl pubKey = + new EdDSAPublicKeyImpl(params, pubKeyPoint); + byte[] encodedPubKey = pubKey.getEncodedPoint(); + if (!ops.verify(sigParams, encodedPubKey, message, sig)) { + throw new RuntimeException("signature did not verify"); + } + } + + long endTime = System.currentTimeMillis(); + double millisPerIter = (double) (endTime - startTime) / count; + System.out.println("Time per keygen+sign+verify: " + + millisPerIter + " ms"); + } + + private static void testInvalidPoints() throws Exception { + + // Ed25519 + + // incorrect length + testInvalidPoint(NamedParameterSpec.ED25519, ""); + testInvalidPoint(NamedParameterSpec.ED25519, "ffffff"); + testInvalidPoint(NamedParameterSpec.ED25519, + "abd75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f70751" + + "1a"); + // y value too large + testInvalidPoint(NamedParameterSpec.ED25519, + "8ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"); + // not square + testInvalidPoint(NamedParameterSpec.ED25519, + "d85a980182b10ac7d54bfed3c964073a0ee172f3daa62325af021a68f707511a"); + // x = 0, but x mod 2 == 1 + testInvalidPoint(NamedParameterSpec.ED25519, + "0100000000000000000000000000000000000000000000000000000000000080"); + + // Ed448 + testInvalidPoint(NamedParameterSpec.ED448, ""); + testInvalidPoint(NamedParameterSpec.ED448, "ffffff"); + testInvalidPoint(NamedParameterSpec.ED448, + "ab43ba28f430cdfe456ae531545f7ecd0ac834a55c9358c0372bfa0c6c6798c0" + + "866aea01eb00742802b8438ea4cb82169c235160627b4c3a9480"); + // y value too large + testInvalidPoint(NamedParameterSpec.ED448, + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + + "fffffffffffffffffffffffffffffffffffffffffffffffffff00"); + // not square + testInvalidPoint(NamedParameterSpec.ED448, + "43ba28f430cdfe456ae531545f7ecd0ac834a55c9358c0372bfa0c6c6798c086" + + "6aea01eb00742802b8438ea4cb82169c235160627b4c3a9480"); + // x = 0, but x mod 2 == 1 + testInvalidPoint(NamedParameterSpec.ED448, + "0100000000000000000000000000000000000000000000000000000000000000" + + "00000000000000000000000000000000000000000000000080"); + + } + + private static void testInvalidPoint(NamedParameterSpec curve, + String pointStr) throws Exception { + + byte[] encodedPoint = Convert.hexStringToByteArray(pointStr); + EdDSAParameters params = + EdDSAParameters.get(RuntimeException::new, curve); + EdDSAOperations ops = new EdDSAOperations(params); + try { + ops.decodeAffinePoint(InvalidKeyException::new, encodedPoint); + throw new RuntimeException("No exception on invalid point"); + } catch (InvalidKeyException ex) { + // this is expected + } + } +} diff --git a/test/jdk/sun/security/ec/xec/TestXECOps.java b/test/jdk/sun/security/ec/xec/TestXECOps.java index 58f175391df..83adba8b465 100644 --- a/test/jdk/sun/security/ec/xec/TestXECOps.java +++ b/test/jdk/sun/security/ec/xec/TestXECOps.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 @@ -32,6 +32,8 @@ */ import sun.security.ec.*; + +import java.security.spec.NamedParameterSpec; import java.util.*; import jdk.test.lib.Convert; @@ -86,7 +88,9 @@ public class TestXECOps { private void runDiffieHellmanTest(String opName, String a_str, String b_str, String result_str) { - XECParameters settings = XECParameters.getByName(opName).get(); + NamedParameterSpec paramSpec = new NamedParameterSpec(opName); + XECParameters settings = + XECParameters.get(RuntimeException::new, paramSpec); XECOperations ops = new XECOperations(settings); byte[] basePoint = Convert.byteToByteArray(settings.getBasePoint(), @@ -118,7 +122,9 @@ public class TestXECOps { byte[] u_in = Convert.hexStringToByteArray(u_in_str); byte[] u_out_expected = Convert.hexStringToByteArray(u_out_str); - XECParameters settings = XECParameters.getByName(opName).get(); + NamedParameterSpec paramSpec = new NamedParameterSpec(opName); + XECParameters settings = + XECParameters.get(RuntimeException::new, paramSpec); XECOperations ops = new XECOperations(settings); byte[] u_out = ops.encodedPointMultiply(k_in, u_in); diff --git a/test/jdk/sun/security/ec/xec/XECIterative.java b/test/jdk/sun/security/ec/xec/XECIterative.java index 05ad0f57129..4bf1dadf1c7 100644 --- a/test/jdk/sun/security/ec/xec/XECIterative.java +++ b/test/jdk/sun/security/ec/xec/XECIterative.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 @@ -43,6 +43,7 @@ import sun.security.ec.*; import java.io.*; +import java.security.spec.NamedParameterSpec; import java.util.*; import jdk.test.lib.Convert; @@ -79,7 +80,9 @@ public class XECIterative { private void runIterativeTest(String opName, long start, long end) throws IOException { - XECParameters settings = XECParameters.getByName(opName).get(); + NamedParameterSpec paramSpec = new NamedParameterSpec(opName); + XECParameters settings = + XECParameters.get(RuntimeException::new, paramSpec); XECOperations ops = new XECOperations(settings); File vectorFile = new File(System.getProperty("test.src", "."), diff --git a/test/jdk/sun/security/util/math/TestIntegerModuloP.java b/test/jdk/sun/security/util/math/TestIntegerModuloP.java index b9fc6e3b588..a887e8ef1ac 100644 --- a/test/jdk/sun/security/util/math/TestIntegerModuloP.java +++ b/test/jdk/sun/security/util/math/TestIntegerModuloP.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 @@ -36,6 +36,8 @@ * @run main TestIntegerModuloP sun.security.util.math.intpoly.P256OrderField 32 8 * @run main TestIntegerModuloP sun.security.util.math.intpoly.P384OrderField 48 9 * @run main TestIntegerModuloP sun.security.util.math.intpoly.P521OrderField 66 10 + * @run main TestIntegerModuloP sun.security.util.math.intpoly.Curve25519OrderField 32 11 + * @run main TestIntegerModuloP sun.security.util.math.intpoly.Curve448OrderField 56 12 */ import sun.security.util.math.*; @@ -104,8 +106,10 @@ public class TestIntegerModuloP { SET_FUNCTIONS.add((a, b, c) -> a.setValue(c, 0, c.length, (byte) 0)); SET_FUNCTIONS.add((a, b, c) -> - a.setValue(ByteBuffer.wrap(c, 0, c.length).order(ByteOrder.LITTLE_ENDIAN), - c.length, highByte)); + a.setValue(c, 0, c.length / 2, (byte) 0)); + SET_FUNCTIONS.add((a, b, c) -> + a.setValue(ByteBuffer.wrap(c, 0, c.length / 2).order(ByteOrder.LITTLE_ENDIAN), + c.length / 2, highByte)); // array functions return the (possibly modified) value as byte array ARRAY_FUNCTIONS.add((a, b ) -> a.asByteArray(length)); @@ -328,7 +332,7 @@ public class TestIntegerModuloP { ElemSetFunction setFunc = SET_FUNCTIONS.get(random.nextInt(SET_FUNCTIONS.size())); - byte[] valueArr = new byte[length]; + byte[] valueArr = new byte[2 * length]; random.nextBytes(valueArr); setAndCheck(setFunc, result1, result2, valueArr); diff --git a/test/lib/jdk/test/lib/Convert.java b/test/lib/jdk/test/lib/Convert.java index ac5235476ee..2f87a49ca75 100644 --- a/test/lib/jdk/test/lib/Convert.java +++ b/test/lib/jdk/test/lib/Convert.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 @@ -24,10 +24,11 @@ package jdk.test.lib; import java.math.BigInteger; +import java.security.spec.EdECPoint; /** - * Utility class containing conversions between strings, arrays, and numeric - * values. + * Utility class containing conversions between strings, arrays, numeric + * values, and other types. */ public class Convert { @@ -80,6 +81,36 @@ public class Convert { } return result; } + + private static EdECPoint byteArrayToEdPoint(byte[] arr) { + byte msb = arr[arr.length - 1]; + boolean xOdd = (msb & 0x80) != 0; + arr[arr.length - 1] &= (byte) 0x7F; + reverse(arr); + BigInteger y = new BigInteger(1, arr); + return new EdECPoint(xOdd, y); + } + + public static EdECPoint hexStringToEdPoint(String str) { + return byteArrayToEdPoint(hexStringToByteArray(str)); + } + + private static void swap(byte[] arr, int i, int j) { + byte tmp = arr[i]; + arr[i] = arr[j]; + arr[j] = tmp; + } + + private static void reverse(byte [] arr) { + int i = 0; + int j = arr.length - 1; + + while (i < j) { + swap(arr, i, j); + i++; + j--; + } + } } diff --git a/test/micro/org/openjdk/bench/javax/crypto/full/SignatureBench.java b/test/micro/org/openjdk/bench/javax/crypto/full/SignatureBench.java index e88a48762bc..aa04853f5dd 100644 --- a/test/micro/org/openjdk/bench/javax/crypto/full/SignatureBench.java +++ b/test/micro/org/openjdk/bench/javax/crypto/full/SignatureBench.java @@ -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 @@ -57,7 +57,11 @@ public class SignatureBench extends CryptoBase { private String getKeyPairGeneratorName() { - String tail = algorithm.substring(algorithm.lastIndexOf("with") + 4); + int withIndex = algorithm.lastIndexOf("with"); + if (withIndex < 0) { + return algorithm; + } + String tail = algorithm.substring(withIndex + 4); return "ECDSA".equals(tail) ? "EC" : tail; } @@ -122,4 +126,14 @@ public class SignatureBench extends CryptoBase { } + public static class EdDSA extends SignatureBench { + + @Param({"EdDSA"}) + private String algorithm; + + @Param({"255", "448"}) + private int keyLength; + + } + } From 3eaf944203f2f828f4d65e52687cb5f15bc348bb Mon Sep 17 00:00:00 2001 From: Joe Wang Date: Mon, 18 May 2020 17:15:32 +0000 Subject: [PATCH 101/143] 8244342: Compilation warnings about unexpected serialization related method signatures Reviewed-by: lancea, naoto, rriggs --- .../internal/xsltc/trax/TemplatesImpl.java | 6 ++-- .../internal/jaxp/datatype/DurationImpl.java | 6 ++-- .../xpath/internal/axes/LocPathIterator.java | 17 +++------- .../internal/axes/PredicatedNodeTest.java | 33 ++++++++----------- .../internal/axes/UnionPathIterator.java | 17 +++------- 5 files changed, 29 insertions(+), 50 deletions(-) diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesImpl.java index e5d08de11e1..c139c4b4fcf 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesImpl.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -68,7 +68,7 @@ import jdk.xml.internal.SecuritySupport; * @author G. Todd Millerj * @author Jochen Cordes * @author Santiago Pericas-Geertsen - * @LastModified: Nov 2017 + * @LastModified: May 2020 */ public final class TemplatesImpl implements Templates, Serializable { static final long serialVersionUID = 673094361519270707L; @@ -295,7 +295,7 @@ public final class TemplatesImpl implements Templates, Serializable { * then we want it to get serialized */ private void writeObject(ObjectOutputStream os) - throws IOException, ClassNotFoundException { + throws IOException { if (_auxClasses != null) { //throw with the same message as when Hashtable was used for compatibility. throw new NotSerializableException( diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/datatype/DurationImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/datatype/DurationImpl.java index f6cca92f9f7..4940822bc4a 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/datatype/DurationImpl.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/datatype/DurationImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -98,7 +98,7 @@ import javax.xml.datatype.XMLGregorianCalendar; * @author Kohsuke Kawaguchi * @author Joseph Fialli * @see XMLGregorianCalendar#add(Duration) - * @LastModified: June 2018 + * @LastModified: May 2020 */ class DurationImpl extends Duration @@ -1857,7 +1857,7 @@ class DurationImpl * An object that encapsulates the string * returned by this.toString(). */ - private Object writeReplace() throws IOException { + private Object writeReplace() { return new DurationStream(this.toString()); } diff --git a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/LocPathIterator.java b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/LocPathIterator.java index 835b43b5fa7..98ada7a328f 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/LocPathIterator.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/LocPathIterator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -45,7 +45,7 @@ import com.sun.org.apache.xpath.internal.res.XPATHErrorResources; * the case where the LocPathIterator is "owned" by a UnionPathIterator, * in which case the UnionPathIterator will cache the nodes.

* @xsl.usage advanced - * @LastModified: Nov 2017 + * @LastModified: May 2020 */ public abstract class LocPathIterator extends PredicatedNodeTest implements Cloneable, DTMIterator, java.io.Serializable, PathComponent @@ -134,17 +134,10 @@ public abstract class LocPathIterator extends PredicatedNodeTest * @throws javax.xml.transform.TransformerException */ private void readObject(java.io.ObjectInputStream stream) - throws java.io.IOException, javax.xml.transform.TransformerException + throws java.io.IOException, ClassNotFoundException { - try - { - stream.defaultReadObject(); - m_clones = new IteratorPool(this); - } - catch (ClassNotFoundException cnfe) - { - throw new javax.xml.transform.TransformerException(cnfe); - } + stream.defaultReadObject(); + m_clones = new IteratorPool(this); } /** diff --git a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/PredicatedNodeTest.java b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/PredicatedNodeTest.java index 418ff527df8..3fd8959f89b 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/PredicatedNodeTest.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/PredicatedNodeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2020 Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -34,7 +34,7 @@ import com.sun.org.apache.xpath.internal.patterns.NodeTest; import java.util.List; /** - * @LastModified: Oct 2017 + * @LastModified: May 2020 */ public abstract class PredicatedNodeTest extends NodeTest implements SubContextList { @@ -67,26 +67,19 @@ public abstract class PredicatedNodeTest extends NodeTest implements SubContextL * @throws javax.xml.transform.TransformerException */ private void readObject(java.io.ObjectInputStream stream) - throws java.io.IOException, javax.xml.transform.TransformerException + throws java.io.IOException, ClassNotFoundException { - try - { - stream.defaultReadObject(); - m_predicateIndex = -1; + stream.defaultReadObject(); + m_predicateIndex = -1; - /** - * Initialize to the declared value. - * As noted at declaration, this variable is used only for clones for getLastPos, - * it should have been excluded from serialization. For compatibility, we'll - * keep it as is but initializing to the declared value. - */ - m_predCount = -1; - resetProximityPositions(); - } - catch (ClassNotFoundException cnfe) - { - throw new javax.xml.transform.TransformerException(cnfe); - } + /** + * Initialize to the declared value. + * As noted at declaration, this variable is used only for clones for getLastPos, + * it should have been excluded from serialization. For compatibility, we'll + * keep it as is but initializing to the declared value. + */ + m_predCount = -1; + resetProximityPositions(); } /** diff --git a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/UnionPathIterator.java b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/UnionPathIterator.java index 7e7276ef048..47dff50e134 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/UnionPathIterator.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/UnionPathIterator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -39,7 +39,7 @@ import java.util.List; * As each node is iterated via nextNode(), the node is also stored * in the NodeVector, so that previousNode() can easily be done. * @xsl.usage advanced - * @LastModified: Oct 2017 + * @LastModified: May 2020 */ public class UnionPathIterator extends LocPathIterator implements Cloneable, DTMIterator, java.io.Serializable, PathComponent @@ -258,17 +258,10 @@ public class UnionPathIterator extends LocPathIterator * @throws javax.xml.transform.TransformerException */ private void readObject(java.io.ObjectInputStream stream) - throws java.io.IOException, javax.xml.transform.TransformerException + throws java.io.IOException, ClassNotFoundException { - try - { - stream.defaultReadObject(); - m_clones = new IteratorPool(this); - } - catch (ClassNotFoundException cnfe) - { - throw new javax.xml.transform.TransformerException(cnfe); - } + stream.defaultReadObject(); + m_clones = new IteratorPool(this); } /** From b26516309a3836c04eab2d5a7b116c8395b7f361 Mon Sep 17 00:00:00 2001 From: Zhengyu Gu Date: Mon, 18 May 2020 14:47:09 -0400 Subject: [PATCH 102/143] 8245124: Shenandoah: optimize code root evacuation/update during concurrent class unloading Reviewed-by: shade --- .../gc/shenandoah/shenandoahCodeRoots.cpp | 4 +++- .../share/gc/shenandoah/shenandoahNMethod.cpp | 21 +---------------- .../share/gc/shenandoah/shenandoahNMethod.hpp | 3 ++- .../shenandoah/shenandoahNMethod.inline.hpp | 23 +++++++++++++++++++ 4 files changed, 29 insertions(+), 22 deletions(-) diff --git a/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp b/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp index 8647084555f..f7168844170 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp @@ -26,6 +26,7 @@ #include "code/codeCache.hpp" #include "code/icBuffer.hpp" #include "code/nmethod.hpp" +#include "gc/shenandoah/shenandoahClosures.inline.hpp" #include "gc/shenandoah/shenandoahCodeRoots.hpp" #include "gc/shenandoah/shenandoahEvacOOMHandler.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" @@ -272,7 +273,8 @@ public: // Heal oops and disarm if (_bs->is_armed(nm)) { - ShenandoahNMethod::heal_nmethod(nm); + ShenandoahEvacOOMScope oom_evac_scope; + ShenandoahNMethod::heal_nmethod_metadata(nm_data); _bs->disarm(nm); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahNMethod.cpp b/src/hotspot/share/gc/shenandoah/shenandoahNMethod.cpp index 8aaddc49f17..a14292e3c9b 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahNMethod.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahNMethod.cpp @@ -110,24 +110,6 @@ void ShenandoahNMethod::update() { assert_same_oops(); } -void ShenandoahNMethod::oops_do(OopClosure* oops, bool fix_relocations) { - for (int c = 0; c < _oops_count; c ++) { - oops->do_oop(_oops[c]); - } - - oop* const begin = _nm->oops_begin(); - oop* const end = _nm->oops_end(); - for (oop* p = begin; p < end; p++) { - if (*p != Universe::non_oop_word()) { - oops->do_oop(p); - } - } - - if (fix_relocations && _has_non_immed_oops) { - _nm->fix_oop_relocations(); - } -} - void ShenandoahNMethod::detect_reloc_oops(nmethod* nm, GrowableArray& oops, bool& has_non_immed_oops) { has_non_immed_oops = false; // Find all oops relocations @@ -215,8 +197,7 @@ void ShenandoahNMethod::heal_nmethod(nmethod* nm) { } } else if (heap->is_concurrent_weak_root_in_progress()) { ShenandoahEvacOOMScope evac_scope; - ShenandoahEvacuateUpdateRootsClosure<> cl; - data->oops_do(&cl, true /*fix relocation*/); + heal_nmethod_metadata(data); } else { // There is possibility that GC is cancelled when it arrives final mark. // In this case, concurrent root phase is skipped and degenerated GC should be diff --git a/src/hotspot/share/gc/shenandoah/shenandoahNMethod.hpp b/src/hotspot/share/gc/shenandoah/shenandoahNMethod.hpp index 80dc3a3d69d..b1dcf8ed036 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahNMethod.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahNMethod.hpp @@ -51,7 +51,7 @@ public: inline nmethod* nm() const; inline ShenandoahReentrantLock* lock(); - void oops_do(OopClosure* oops, bool fix_relocations = false); + inline void oops_do(OopClosure* oops, bool fix_relocations = false); // Update oops when the nmethod is re-registered void update(); @@ -67,6 +67,7 @@ public: static inline ShenandoahReentrantLock* lock_for_nmethod(nmethod* nm); static void heal_nmethod(nmethod* nm); + static inline void heal_nmethod_metadata(ShenandoahNMethod* nmethod_data); static inline void disarm_nmethod(nmethod* nm); static inline ShenandoahNMethod* gc_data(nmethod* nm); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahNMethod.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahNMethod.inline.hpp index f7dec26a554..deab8c89032 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahNMethod.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahNMethod.inline.hpp @@ -54,6 +54,29 @@ bool ShenandoahNMethod::is_unregistered() const { return _unregistered; } +void ShenandoahNMethod::oops_do(OopClosure* oops, bool fix_relocations) { + for (int c = 0; c < _oops_count; c ++) { + oops->do_oop(_oops[c]); + } + + oop* const begin = _nm->oops_begin(); + oop* const end = _nm->oops_end(); + for (oop* p = begin; p < end; p++) { + if (*p != Universe::non_oop_word()) { + oops->do_oop(p); + } + } + + if (fix_relocations && _has_non_immed_oops) { + _nm->fix_oop_relocations(); + } +} + +void ShenandoahNMethod::heal_nmethod_metadata(ShenandoahNMethod* nmethod_data) { + ShenandoahEvacuateUpdateRootsClosure<> cl; + nmethod_data->oops_do(&cl, true /*fix relocation*/); +} + void ShenandoahNMethod::disarm_nmethod(nmethod* nm) { if (!ShenandoahConcurrentRoots::can_do_concurrent_class_unloading()) { return; From 039cb657539a71fcdc76bdadd98167be48b1c34f Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Mon, 18 May 2020 13:24:35 -0700 Subject: [PATCH 103/143] 8239816: Make handling of module / package / types consistent Reviewed-by: hannesw --- .../formats/html/ModuleWriterImpl.java | 8 +----- .../formats/html/markup/HtmlStyle.java | 8 ------ .../doclets/toolkit/ModuleSummaryWriter.java | 9 ------- .../builders/ModuleSummaryBuilder.java | 12 --------- .../doclet/testModules/TestModules.java | 25 ++++++++++++------- 5 files changed, 17 insertions(+), 45 deletions(-) diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java index 9ce512ddc64..2e89df46671 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java @@ -840,17 +840,11 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW addDeprecationInfo(tree); tree.add(MarkerComments.START_OF_MODULE_DESCRIPTION); addInlineComment(mdle, tree); + addTagsInfo(mdle, tree); moduleContentTree.add(tree); } } - @Override - public void addModuleTags(Content moduleContentTree) { - Content tree = HtmlTree.SECTION(HtmlStyle.moduleTags); - addTagsInfo(mdle, tree); - moduleContentTree.add(tree); - } - @Override public void addModuleContent(Content moduleContentTree) { bodyContents.addMainContent(moduleContentTree); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlStyle.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlStyle.java index 16c607956ea..bc52ba33843 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlStyle.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlStyle.java @@ -231,14 +231,6 @@ public enum HtmlStyle { */ moduleDescription, - /** - * The class of the {@code dl} element used to present the block tags in the documentation - * comment for a module element. - * Additional (derived) information, such as implementation or inheritance details, may - * also appear in this element. - */ - moduleTags, - /** * The class of the element used to present the documentation comment for package element. * The content of the block tags will be in a nested element with class {@link #notes}. diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/ModuleSummaryWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/ModuleSummaryWriter.java index 0eb5af503aa..4f3a3029f1e 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/ModuleSummaryWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/ModuleSummaryWriter.java @@ -76,15 +76,6 @@ public interface ModuleSummaryWriter { */ void addModuleDescription(Content moduleContentTree); - /** - * Adds the tag information from the "module-info.java" file to the documentation - * tree. - * - * @param moduleContentTree the content tree to which the module tags will - * be added - */ - void addModuleTags(Content moduleContentTree); - /** * Adds the summary of modules to the list of summaries. * diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/ModuleSummaryBuilder.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/ModuleSummaryBuilder.java index 2c91d45ada8..dcc69972ab8 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/ModuleSummaryBuilder.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/ModuleSummaryBuilder.java @@ -122,7 +122,6 @@ public class ModuleSummaryBuilder extends AbstractBuilder { Content moduleContentTree = moduleWriter.getContentHeader(); buildModuleDescription(moduleContentTree); - buildModuleTags(moduleContentTree); buildSummary(moduleContentTree); moduleWriter.addModuleContent(moduleContentTree); @@ -183,15 +182,4 @@ public class ModuleSummaryBuilder extends AbstractBuilder { moduleWriter.addModuleDescription(moduleContentTree); } } - - /** - * Build the tags of the summary. - * - * @param moduleContentTree the tree to which the module tags will be added - */ - protected void buildModuleTags(Content moduleContentTree) { - if (!options.noComment()) { - moduleWriter.addModuleTags(moduleContentTree); - } - } } diff --git a/test/langtools/jdk/javadoc/doclet/testModules/TestModules.java b/test/langtools/jdk/javadoc/doclet/testModules/TestModules.java index d213bbc7153..20badb0af07 100644 --- a/test/langtools/jdk/javadoc/doclet/testModules/TestModules.java +++ b/test/langtools/jdk/javadoc/doclet/testModules/TestModules.java @@ -27,7 +27,7 @@ * 8168766 8168688 8162674 8160196 8175799 8174974 8176778 8177562 8175218 * 8175823 8166306 8178043 8181622 8183511 8169819 8074407 8183037 8191464 * 8164407 8192007 8182765 8196200 8196201 8196202 8196202 8205593 8202462 - * 8184205 8219060 8223378 8234746 8239804 + * 8184205 8219060 8223378 8234746 8239804 8239816 * @summary Test modules support in javadoc. * @library ../../lib * @modules jdk.javadoc/jdk.javadoc.internal.tool @@ -633,8 +633,12 @@ public class TestModules extends JavadocTester { lang.String)">testMethod(String).""", """ Package Link: testpkgmdltags.""", - "
Since:
\n" - + "
JDK 9
", + """ + +
""", + """ +
Since:
+
JDK 9
""", """
See Also:
"Test see tag",\s @@ -646,10 +650,12 @@ public class TestModules extends JavadocTester { """
Module Tag:
Just a simple module tag.
""", - "
Version:
\n" - + "
1.0
", - "
Author:
\n" - + "
Alice
"); + """ +
Version:
+
1.0
""", + """ +
Author:
+
Alice
"""); checkOutput("moduletags/testpkgmdltags/TestClassInModuleTags.html", false, """
Module Tag:
@@ -1222,8 +1228,9 @@ public class TestModules extends JavadocTester {
This module is deprecated using just the javadoc tag.
"""); checkOutput("moduletags/module-summary.html", found, - "

@Deprecated\n" - + "

", + """ +

@Deprecated +

""", """
Deprecated.
"""); } From b08140dade8d485e1d93e3ee9a2bffb39925d315 Mon Sep 17 00:00:00 2001 From: Joe Wang Date: Mon, 18 May 2020 22:13:35 +0000 Subject: [PATCH 104/143] 8245231: Javadoc for the readObject methods needs to be updated Reviewed-by: lancea, msheppar --- .../sun/org/apache/xpath/internal/axes/LocPathIterator.java | 4 ++-- .../org/apache/xpath/internal/axes/PredicatedNodeTest.java | 6 +++--- .../org/apache/xpath/internal/axes/UnionPathIterator.java | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/LocPathIterator.java b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/LocPathIterator.java index 98ada7a328f..d8b22840157 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/LocPathIterator.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/LocPathIterator.java @@ -130,8 +130,8 @@ public abstract class LocPathIterator extends PredicatedNodeTest * * @param stream Input stream to read from * - * @throws java.io.IOException - * @throws javax.xml.transform.TransformerException + * @throws java.io.IOException in case of any IO related exceptions + * @throws ClassNotFoundException if Class of the serialized object cannot be found */ private void readObject(java.io.ObjectInputStream stream) throws java.io.IOException, ClassNotFoundException diff --git a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/PredicatedNodeTest.java b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/PredicatedNodeTest.java index 3fd8959f89b..6e52dc80393 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/PredicatedNodeTest.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/PredicatedNodeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -63,8 +63,8 @@ public abstract class PredicatedNodeTest extends NodeTest implements SubContextL * * @param stream Input stream to read from * - * @throws java.io.IOException - * @throws javax.xml.transform.TransformerException + * @throws java.io.IOException in case of any IO related exceptions + * @throws ClassNotFoundException if Class of the serialized object cannot be found */ private void readObject(java.io.ObjectInputStream stream) throws java.io.IOException, ClassNotFoundException diff --git a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/UnionPathIterator.java b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/UnionPathIterator.java index 47dff50e134..0b67aed9046 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/UnionPathIterator.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/UnionPathIterator.java @@ -254,8 +254,8 @@ public class UnionPathIterator extends LocPathIterator * * @param stream Input stream to read from * - * @throws java.io.IOException - * @throws javax.xml.transform.TransformerException + * @throws java.io.IOException in case of any IO related exceptions + * @throws ClassNotFoundException if Class of the serialized object cannot be found */ private void readObject(java.io.ObjectInputStream stream) throws java.io.IOException, ClassNotFoundException From 4159f6852ed1de0cac7ff27b36361fa0ad35495b Mon Sep 17 00:00:00 2001 From: Yasumasa Suenaga Date: Tue, 19 May 2020 09:02:30 +0900 Subject: [PATCH 105/143] 8233706: JFR emergency dump should be performed after error reporting Reviewed-by: mgronlun, egahlin --- src/hotspot/share/jfr/jfr.cpp | 9 +- src/hotspot/share/jfr/jfr.hpp | 3 +- .../recorder/repository/jfrEmergencyDump.cpp | 442 +++++++++++------- .../recorder/repository/jfrEmergencyDump.hpp | 8 +- .../jfr/recorder/repository/jfrRepository.cpp | 9 +- .../jfr/recorder/repository/jfrRepository.hpp | 3 +- src/hotspot/share/utilities/vmError.cpp | 15 +- .../jfr/event/runtime/TestShutdownEvent.java | 2 +- 8 files changed, 292 insertions(+), 199 deletions(-) diff --git a/src/hotspot/share/jfr/jfr.cpp b/src/hotspot/share/jfr/jfr.cpp index 4a5fd0e4020..ecd535e5ddb 100644 --- a/src/hotspot/share/jfr/jfr.cpp +++ b/src/hotspot/share/jfr/jfr.cpp @@ -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 @@ -30,6 +30,7 @@ #include "jfr/recorder/checkpoint/jfrCheckpointManager.hpp" #include "jfr/recorder/repository/jfrEmergencyDump.hpp" #include "jfr/recorder/service/jfrOptionSet.hpp" +#include "jfr/recorder/repository/jfrRepository.hpp" #include "jfr/support/jfrThreadLocal.hpp" #include "runtime/java.hpp" @@ -101,6 +102,12 @@ void Jfr::on_vm_shutdown(bool exception_handler) { } } +void Jfr::on_vm_error_report(outputStream* st) { + if (JfrRecorder::is_recording()) { + JfrRepository::on_vm_error_report(st); + } +} + void Jfr::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f) { if (LeakProfiler::is_running()) { LeakProfiler::weak_oops_do(is_alive, f); diff --git a/src/hotspot/share/jfr/jfr.hpp b/src/hotspot/share/jfr/jfr.hpp index 9e525b0fa67..6b1317832dd 100644 --- a/src/hotspot/share/jfr/jfr.hpp +++ b/src/hotspot/share/jfr/jfr.hpp @@ -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 @@ -53,6 +53,7 @@ class Jfr : AllStatic { static void on_vm_shutdown(bool exception_handler = false); static bool on_flight_recorder_option(const JavaVMOption** option, char* delimiter); static bool on_start_flight_recording_option(const JavaVMOption** option, char* delimiter); + static void on_vm_error_report(outputStream* st); static void weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f); static void exclude_thread(Thread* thread); static bool is_excluded(Thread* thread); diff --git a/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.cpp b/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.cpp index 04111613fd0..ddf63dc592d 100644 --- a/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.cpp +++ b/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.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,25 +31,134 @@ #include "jfr/recorder/service/jfrRecorderService.hpp" #include "jfr/utilities/jfrTypes.hpp" #include "logging/log.hpp" -#include "memory/resourceArea.hpp" #include "runtime/atomic.hpp" -#include "runtime/handles.inline.hpp" #include "runtime/globals.hpp" #include "runtime/mutexLocker.hpp" #include "runtime/os.hpp" #include "runtime/thread.inline.hpp" #include "utilities/growableArray.hpp" +#include "utilities/ostream.hpp" static const char vm_error_filename_fmt[] = "hs_err_pid%p.jfr"; static const char vm_oom_filename_fmt[] = "hs_oom_pid%p.jfr"; static const char vm_soe_filename_fmt[] = "hs_soe_pid%p.jfr"; static const char chunk_file_jfr_ext[] = ".jfr"; static const size_t iso8601_len = 19; // "YYYY-MM-DDTHH:MM:SS" +static fio_fd emergency_fd = invalid_fd; +static const int64_t chunk_file_header_size = 68; +static const size_t chunk_file_extension_length = sizeof chunk_file_jfr_ext - 1; + +/* + * The emergency dump logic is restrictive when it comes to + * using internal VM constructs such as ResourceArea / Handle / Arena. + * The reason being that the thread context is unknown. + * + * A single static buffer of size JVM_MAXPATHLEN is used for building paths. + * os::malloc / os::free are used in a few places. + */ + +static char _path_buffer[JVM_MAXPATHLEN] = { 0 }; + +static bool is_path_empty() { + return *_path_buffer == '\0'; +} + +// returns with an appended file separator (if successful) +static size_t get_current_directory() { + if (os::get_current_directory(_path_buffer, sizeof(_path_buffer)) == NULL) { + return 0; + } + const size_t cwd_len = strlen(_path_buffer); + const int result = jio_snprintf(_path_buffer + cwd_len, + sizeof(_path_buffer), + "%s", + os::file_separator()); + return (result == -1) ? 0 : strlen(_path_buffer); +} static fio_fd open_exclusivly(const char* path) { + assert((path != NULL) && (*path != '\0'), "invariant"); return os::open(path, O_CREAT | O_RDWR, S_IREAD | S_IWRITE); } +static bool is_emergency_dump_file_open() { + return emergency_fd != invalid_fd; +} + +static bool open_emergency_dump_fd(const char* path) { + if (path == NULL) { + return false; + } + assert(emergency_fd == invalid_fd, "invariant"); + emergency_fd = open_exclusivly(path); + return emergency_fd != invalid_fd; +} + +static void close_emergency_dump_file() { + if (is_emergency_dump_file_open()) { + os::close(emergency_fd); + } +} + +static const char* create_emergency_dump_path() { + assert(is_path_empty(), "invariant"); + + const size_t path_len = get_current_directory(); + if (path_len == 0) { + return NULL; + } + const char* filename_fmt = NULL; + // fetch specific error cause + switch (JfrJavaSupport::cause()) { + case JfrJavaSupport::OUT_OF_MEMORY: + filename_fmt = vm_oom_filename_fmt; + break; + case JfrJavaSupport::STACK_OVERFLOW: + filename_fmt = vm_soe_filename_fmt; + break; + default: + filename_fmt = vm_error_filename_fmt; + } + const bool result = Arguments::copy_expand_pid(filename_fmt, strlen(filename_fmt), _path_buffer + path_len, JVM_MAXPATHLEN - path_len); + return result ? _path_buffer : NULL; +} + +static bool open_emergency_dump_file() { + if (is_emergency_dump_file_open()) { + // opened already + return true; + } + return open_emergency_dump_fd(create_emergency_dump_path()); +} + +static void report(outputStream* st, bool emergency_file_opened, const char* repository_path) { + assert(st != NULL, "invariant"); + if (emergency_file_opened) { + st->print_raw("# JFR recording file will be written. Location: "); + st->print_raw_cr(_path_buffer); + st->print_raw_cr("#"); + } else if (repository_path != NULL) { + st->print_raw("# The JFR repository may contain useful JFR files. Location: "); + st->print_raw_cr(repository_path); + st->print_raw_cr("#"); + } else if (!is_path_empty()) { + st->print_raw("# Unable to create a JFR recording file at location: "); + st->print_raw_cr(_path_buffer); + st->print_raw_cr("#"); + } +} + +void JfrEmergencyDump::on_vm_error_report(outputStream* st, const char* repository_path) { + assert(st != NULL, "invariant"); + Thread* thread = Thread::current_or_null_safe(); + if (thread != NULL) { + report(st, open_emergency_dump_file(), repository_path); + } else if (repository_path != NULL) { + // a non-attached thread will not be able to write anything later + report(st, false, repository_path); + } +} + static int file_sort(const char** const file1, const char** file2) { assert(NULL != *file1 && NULL != *file2, "invariant"); int cmp = strncmp(*file1, *file2, iso8601_len); @@ -109,227 +218,198 @@ static int64_t file_size(fio_fd fd) { class RepositoryIterator : public StackObj { private: - const char* const _repo; - const size_t _repository_len; - GrowableArray* _files; - const char* const fully_qualified(const char* entry) const; + GrowableArray* _file_names; + int _path_buffer_file_name_offset; mutable int _iterator; - + const char* fully_qualified(const char* file_name) const; + const char* filter(const char* file_name) const; public: - RepositoryIterator(const char* repository, size_t repository_len); - ~RepositoryIterator() {} - const char* const filter(const char* entry) const; + RepositoryIterator(const char* repository_path); + ~RepositoryIterator(); bool has_next() const; - const char* const next() const; + const char* next() const; }; -const char* const RepositoryIterator::fully_qualified(const char* entry) const { - assert(NULL != entry, "invariant"); - char* file_path_entry = NULL; - // only use files that have content, not placeholders - const char* const file_separator = os::file_separator(); - if (NULL != file_separator) { - const size_t entry_len = strlen(entry); - const size_t file_separator_length = strlen(file_separator); - const size_t file_path_entry_length = _repository_len + file_separator_length + entry_len; - file_path_entry = NEW_RESOURCE_ARRAY_RETURN_NULL(char, file_path_entry_length + 1); - if (NULL == file_path_entry) { - return NULL; - } - int position = 0; - position += jio_snprintf(&file_path_entry[position], _repository_len + 1, "%s", _repo); - position += jio_snprintf(&file_path_entry[position], file_separator_length + 1, "%s", os::file_separator()); - position += jio_snprintf(&file_path_entry[position], entry_len + 1, "%s", entry); - file_path_entry[position] = '\0'; - assert((size_t)position == file_path_entry_length, "invariant"); - assert(strlen(file_path_entry) == (size_t)position, "invariant"); - } - return file_path_entry; +// append the file_name at the _path_buffer_file_name_offset position +const char* RepositoryIterator::fully_qualified(const char* file_name) const { + assert(NULL != file_name, "invariant"); + assert(!is_path_empty(), "invariant"); + assert(_path_buffer_file_name_offset != 0, "invariant"); + + const int result = jio_snprintf(_path_buffer + _path_buffer_file_name_offset, + sizeof(_path_buffer) - _path_buffer_file_name_offset, + "%s", + file_name); + return result != -1 ? _path_buffer : NULL; } -const char* const RepositoryIterator::filter(const char* entry) const { - if (entry == NULL) { +// caller responsible for deallocation +const char* RepositoryIterator::filter(const char* file_name) const { + if (file_name == NULL) { return NULL; } - const size_t entry_len = strlen(entry); - if (entry_len <= 2) { - // for "." and ".." + const size_t len = strlen(file_name); + if ((len < chunk_file_extension_length) || + (strncmp(&file_name[len - chunk_file_extension_length], + chunk_file_jfr_ext, + chunk_file_extension_length) != 0)) { + // not a .jfr file return NULL; } - char* entry_name = NEW_RESOURCE_ARRAY_RETURN_NULL(char, entry_len + 1); - if (entry_name == NULL) { + const char* fqn = fully_qualified(file_name); + if (fqn == NULL) { return NULL; } - strncpy(entry_name, entry, entry_len + 1); - const char* const fully_qualified_path_entry = fully_qualified(entry_name); - if (NULL == fully_qualified_path_entry) { + const fio_fd fd = open_exclusivly(fqn); + if (invalid_fd == fd) { return NULL; } - const fio_fd entry_fd = open_exclusivly(fully_qualified_path_entry); - if (invalid_fd == entry_fd) { + const int64_t size = file_size(fd); + os::close(fd); + if (size <= chunk_file_header_size) { return NULL; } - const int64_t entry_size = file_size(entry_fd); - os::close(entry_fd); - if (0 == entry_size) { + char* const file_name_copy = (char*)os::malloc(len + 1, mtTracing); + if (file_name_copy == NULL) { + log_error(jfr, system)("Unable to malloc memory during jfr emergency dump"); return NULL; } - return entry_name; + strncpy(file_name_copy, file_name, len + 1); + return file_name_copy; } -RepositoryIterator::RepositoryIterator(const char* repository, size_t repository_len) : - _repo(repository), - _repository_len(repository_len), - _files(NULL), +RepositoryIterator::RepositoryIterator(const char* repository_path) : + _file_names(NULL), + _path_buffer_file_name_offset(0), _iterator(0) { - if (NULL != _repo) { - assert(strlen(_repo) == _repository_len, "invariant"); - _files = new GrowableArray(10); - DIR* dirp = os::opendir(_repo); + DIR* dirp = os::opendir(repository_path); if (dirp == NULL) { - log_error(jfr, system)("Unable to open repository %s", _repo); + log_error(jfr, system)("Unable to open repository %s", repository_path); return; } + // store repository path in the path buffer and save that position + _path_buffer_file_name_offset = jio_snprintf(_path_buffer, + sizeof(_path_buffer), + "%s%s", + repository_path, + os::file_separator()); + if (_path_buffer_file_name_offset == -1) { + return; + } + _file_names = new (ResourceObj::C_HEAP, mtTracing) GrowableArray(10, true, mtTracing); + if (_file_names == NULL) { + log_error(jfr, system)("Unable to malloc memory during jfr emergency dump"); + return; + } + // iterate files in the repository and append filtered file names to the files array struct dirent* dentry; while ((dentry = os::readdir(dirp)) != NULL) { - const char* const entry_path = filter(dentry->d_name); - if (NULL != entry_path) { - _files->append(entry_path); + const char* file_name = filter(dentry->d_name); + if (file_name != NULL) { + _file_names->append(file_name); } } os::closedir(dirp); - if (_files->length() > 1) { - _files->sort(file_sort); + if (_file_names->length() > 1) { + _file_names->sort(file_sort); } +} + +RepositoryIterator::~RepositoryIterator() { + if (_file_names != NULL) { + for (int i = 0; i < _file_names->length(); ++i) { + os::free(const_cast(_file_names->at(i))); + } + delete _file_names; } } bool RepositoryIterator::has_next() const { - return (_files != NULL && _iterator < _files->length()); + return _file_names != NULL && _iterator < _file_names->length(); } -const char* const RepositoryIterator::next() const { - return _iterator >= _files->length() ? NULL : fully_qualified(_files->at(_iterator++)); +const char* RepositoryIterator::next() const { + return _iterator >= _file_names->length() ? NULL : fully_qualified(_file_names->at(_iterator++)); } -static void write_emergency_file(fio_fd emergency_fd, const RepositoryIterator& iterator) { - assert(emergency_fd != invalid_fd, "invariant"); - const size_t size_of_file_copy_block = 1 * M; // 1 mb - jbyte* const file_copy_block = NEW_RESOURCE_ARRAY_RETURN_NULL(jbyte, size_of_file_copy_block); - if (file_copy_block == NULL) { - return; - } +static void write_repository_files(const RepositoryIterator& iterator, char* const copy_block, size_t block_size) { + assert(is_emergency_dump_file_open(), "invariant"); while (iterator.has_next()) { fio_fd current_fd = invalid_fd; const char* const fqn = iterator.next(); - if (fqn != NULL) { - current_fd = open_exclusivly(fqn); - if (current_fd != invalid_fd) { - const int64_t current_filesize = file_size(current_fd); - assert(current_filesize > 0, "invariant"); - int64_t bytes_read = 0; - int64_t bytes_written = 0; - while (bytes_read < current_filesize) { - const ssize_t read_result = os::read_at(current_fd, file_copy_block, size_of_file_copy_block, bytes_read); - if (-1 == read_result) { - log_info(jfr)( // For user, should not be "jfr, system" + assert(fqn != NULL, "invariant"); + current_fd = open_exclusivly(fqn); + if (current_fd != invalid_fd) { + const int64_t size = file_size(current_fd); + assert(size > 0, "invariant"); + int64_t bytes_read = 0; + int64_t bytes_written = 0; + while (bytes_read < size) { + const ssize_t read_result = os::read_at(current_fd, copy_block, (int)block_size, bytes_read); + if (-1 == read_result) { + log_info(jfr)( // For user, should not be "jfr, system" "Unable to recover JFR data"); - break; - } - bytes_read += (int64_t)read_result; - assert(bytes_read - bytes_written <= (int64_t)size_of_file_copy_block, "invariant"); - bytes_written += (int64_t)os::write(emergency_fd, file_copy_block, bytes_read - bytes_written); - assert(bytes_read == bytes_written, "invariant"); + break; } - os::close(current_fd); + bytes_read += (int64_t)read_result; + assert(bytes_read - bytes_written <= (int64_t)block_size, "invariant"); + bytes_written += (int64_t)os::write(emergency_fd, copy_block, bytes_read - bytes_written); + assert(bytes_read == bytes_written, "invariant"); } + os::close(current_fd); } } } -static const char* create_emergency_dump_path() { - char* buffer = NEW_RESOURCE_ARRAY_RETURN_NULL(char, JVM_MAXPATHLEN); - if (NULL == buffer) { - return NULL; +static void write_emergency_dump_file(const RepositoryIterator& iterator) { + static const size_t block_size = 1 * M; // 1 mb + char* const copy_block = (char*)os::malloc(block_size, mtTracing); + if (copy_block == NULL) { + log_error(jfr, system)("Unable to malloc memory during jfr emergency dump"); + log_error(jfr, system)("Unable to write jfr emergency dump file"); } - const char* const cwd = os::get_current_directory(buffer, JVM_MAXPATHLEN); - if (NULL == cwd) { - return NULL; - } - size_t pos = strlen(cwd); - const int fsep_len = jio_snprintf(&buffer[pos], JVM_MAXPATHLEN - pos, "%s", os::file_separator()); - const char* filename_fmt = NULL; - // fetch specific error cause - switch (JfrJavaSupport::cause()) { - case JfrJavaSupport::OUT_OF_MEMORY: - filename_fmt = vm_oom_filename_fmt; - break; - case JfrJavaSupport::STACK_OVERFLOW: - filename_fmt = vm_soe_filename_fmt; - break; - default: - filename_fmt = vm_error_filename_fmt; - } - char* emergency_dump_path = NULL; - pos += fsep_len; - if (Arguments::copy_expand_pid(filename_fmt, strlen(filename_fmt), &buffer[pos], JVM_MAXPATHLEN - pos)) { - const size_t emergency_filename_length = strlen(buffer); - emergency_dump_path = NEW_RESOURCE_ARRAY_RETURN_NULL(char, emergency_filename_length + 1); - if (NULL == emergency_dump_path) { - return NULL; - } - strncpy(emergency_dump_path, buffer, emergency_filename_length + 1); - } - if (emergency_dump_path != NULL) { - log_info(jfr)( // For user, should not be "jfr, system" - "Attempting to recover JFR data, emergency jfr file: %s", emergency_dump_path); - } - return emergency_dump_path; -} - -// Caller needs ResourceMark -static const char* create_emergency_chunk_path(const char* repository_path) { - assert(repository_path != NULL, "invariant"); - const size_t repository_path_len = strlen(repository_path); - // date time - char date_time_buffer[32] = { 0 }; - date_time(date_time_buffer, sizeof(date_time_buffer)); - size_t date_time_len = strlen(date_time_buffer); - size_t chunkname_max_len = repository_path_len // repository_base_path - + 1 // "/" - + date_time_len // date_time - + strlen(chunk_file_jfr_ext) // .jfr - + 1; - char* chunk_path = NEW_RESOURCE_ARRAY_RETURN_NULL(char, chunkname_max_len); - if (chunk_path == NULL) { - return NULL; - } - // append the individual substrings - jio_snprintf(chunk_path, chunkname_max_len, "%s%s%s%s", repository_path, os::file_separator(), date_time_buffer, chunk_file_jfr_ext); - return chunk_path; -} - -static fio_fd emergency_dump_file_descriptor() { - ResourceMark rm; - const char* const emergency_dump_path = create_emergency_dump_path(); - return emergency_dump_path != NULL ? open_exclusivly(emergency_dump_path) : invalid_fd; -} - -const char* JfrEmergencyDump::build_dump_path(const char* repository_path) { - return repository_path == NULL ? create_emergency_dump_path() : create_emergency_chunk_path(repository_path); + write_repository_files(iterator, copy_block, block_size); + os::free(copy_block); } void JfrEmergencyDump::on_vm_error(const char* repository_path) { assert(repository_path != NULL, "invariant"); - ResourceMark rm; - const fio_fd emergency_fd = emergency_dump_file_descriptor(); - if (emergency_fd != invalid_fd) { - RepositoryIterator iterator(repository_path, strlen(repository_path)); - write_emergency_file(emergency_fd, iterator); - os::close(emergency_fd); + if (open_emergency_dump_file()) { + RepositoryIterator iterator(repository_path); + write_emergency_dump_file(iterator); + close_emergency_dump_file(); } } +static const char* create_emergency_chunk_path(const char* repository_path) { + const size_t repository_path_len = strlen(repository_path); + char date_time_buffer[32] = { 0 }; + date_time(date_time_buffer, sizeof(date_time_buffer)); + // append the individual substrings + const int result = jio_snprintf(_path_buffer, + JVM_MAXPATHLEN, + "%s%s%s%s", + repository_path, + os::file_separator(), + date_time_buffer, + chunk_file_jfr_ext); + return result == -1 ? NULL : _path_buffer; +} + +const char* JfrEmergencyDump::chunk_path(const char* repository_path) { + if (repository_path == NULL) { + if (!open_emergency_dump_file()) { + return NULL; + } + // We can directly use the emergency dump file name as the chunk. + // The chunk writer will open its own fd so we close this descriptor. + close_emergency_dump_file(); + assert(!is_path_empty(), "invariant"); + return _path_buffer; + } + return create_emergency_chunk_path(repository_path); +} + /* * We are just about to exit the VM, so we will be very aggressive * at this point in order to increase overall success of dumping jfr data. @@ -443,11 +523,25 @@ class JavaThreadInVM : public StackObj { }; +static void post_events(bool exception_handler) { + if (exception_handler) { + EventShutdown e; + e.set_reason("VM Error"); + e.commit(); + } else { + // OOM + LeakProfiler::emit_events(max_jlong, false); + } + EventDumpReason event; + event.set_reason(exception_handler ? "Crash" : "Out of Memory"); + event.set_recordingId(-1); + event.commit(); +} + void JfrEmergencyDump::on_vm_shutdown(bool exception_handler) { if (!guard_reentrancy()) { return; } - Thread* thread = Thread::current_or_null_safe(); if (thread == NULL) { return; @@ -457,17 +551,7 @@ void JfrEmergencyDump::on_vm_shutdown(bool exception_handler) { if (!prepare_for_emergency_dump(thread)) { return; } - - EventDumpReason event; - if (event.should_commit()) { - event.set_reason(exception_handler ? "Crash" : "Out of Memory"); - event.set_recordingId(-1); - event.commit(); - } - if (!exception_handler) { - // OOM - LeakProfiler::emit_events(max_jlong, false); - } + post_events(exception_handler); const int messages = MSGBIT(MSG_VM_ERROR); JfrRecorderService service; service.rotate(messages); diff --git a/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.hpp b/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.hpp index 2752dec1356..909f73bf892 100644 --- a/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.hpp +++ b/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 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 @@ -26,15 +26,17 @@ #define SHARE_JFR_RECORDER_REPOSITORY_JFREMERGENCYDUMP_HPP #include "memory/allocation.hpp" +#include "utilities/ostream.hpp" // // Responsible for creating an hs_err.jfr file in exceptional shutdown situations (crash, OOM) // class JfrEmergencyDump : AllStatic { public: - static void on_vm_shutdown(bool exception_handler); + static const char* chunk_path(const char* repository_path); static void on_vm_error(const char* repository_path); - static const char* build_dump_path(const char* repository_path); + static void on_vm_error_report(outputStream* st, const char* repository_path); + static void on_vm_shutdown(bool exception_handler); }; #endif // SHARE_JFR_RECORDER_REPOSITORY_JFREMERGENCYDUMP_HPP diff --git a/src/hotspot/share/jfr/recorder/repository/jfrRepository.cpp b/src/hotspot/share/jfr/recorder/repository/jfrRepository.cpp index 168b8928a55..234e0ed0953 100644 --- a/src/hotspot/share/jfr/recorder/repository/jfrRepository.cpp +++ b/src/hotspot/share/jfr/recorder/repository/jfrRepository.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2019, 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 @@ -89,6 +89,10 @@ void JfrRepository::on_vm_error() { JfrEmergencyDump::on_vm_error(_path); } +void JfrRepository::on_vm_error_report(outputStream* st) { + JfrEmergencyDump::on_vm_error_report(st, instance()._path); +} + bool JfrRepository::set_path(const char* path) { assert(path != NULL, "trying to set the repository path with a NULL string!"); if (_path != NULL) { @@ -158,8 +162,7 @@ void JfrRepository::set_path(jstring location, JavaThread* jt) { bool JfrRepository::open_chunk(bool vm_error /* false */) { if (vm_error) { - ResourceMark rm; - _chunkwriter->set_path(JfrEmergencyDump::build_dump_path(_path)); + _chunkwriter->set_path(JfrEmergencyDump::chunk_path(_path)); } return _chunkwriter->open(); } diff --git a/src/hotspot/share/jfr/recorder/repository/jfrRepository.hpp b/src/hotspot/share/jfr/recorder/repository/jfrRepository.hpp index 82c8365953d..76ff714f6c9 100644 --- a/src/hotspot/share/jfr/recorder/repository/jfrRepository.hpp +++ b/src/hotspot/share/jfr/recorder/repository/jfrRepository.hpp @@ -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 @@ -73,6 +73,7 @@ class JfrRepository : public JfrCHeapObj { static void mark_chunk_final(); static void flush(JavaThread* jt); static jlong current_chunk_start_nanos(); + static void on_vm_error_report(outputStream* st); }; #endif // SHARE_JFR_RECORDER_REPOSITORY_JFRREPOSITORY_HPP diff --git a/src/hotspot/share/utilities/vmError.cpp b/src/hotspot/share/utilities/vmError.cpp index a16ec25e793..2c94d6eefe5 100644 --- a/src/hotspot/share/utilities/vmError.cpp +++ b/src/hotspot/share/utilities/vmError.cpp @@ -29,7 +29,6 @@ #include "compiler/disassembler.hpp" #include "gc/shared/gcConfig.hpp" #include "logging/logConfiguration.hpp" -#include "jfr/jfrEvents.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.hpp" #include "oops/compressedOops.hpp" @@ -620,6 +619,9 @@ void VMError::report(outputStream* st, bool _verbose) { st->cr(); st->print_cr("#"); + JFR_ONLY(STEP("printing jfr information")) + JFR_ONLY(Jfr::on_vm_error_report(st);) + STEP("printing bug submit message") if (should_report_bug(_id) && _verbose) { @@ -1410,15 +1412,6 @@ void VMError::report_and_die(int id, const char* message, const char* detail_fmt // reset signal handlers or exception filter; make sure recursive crashes // are handled properly. reset_signal_handlers(); - - EventShutdown e; - if (e.should_commit()) { - e.set_reason("VM Error"); - e.commit(); - } - - JFR_ONLY(Jfr::on_vm_shutdown(true);) - } else { // If UseOsErrorReporting we call this for each level of the call stack // while searching for the exception handler. Only the first level needs @@ -1540,6 +1533,8 @@ void VMError::report_and_die(int id, const char* message, const char* detail_fmt log.set_fd(-1); } + JFR_ONLY(Jfr::on_vm_shutdown(true);) + if (PrintNMTStatistics) { fdStream fds(fd_out); MemTracker::final_report(&fds); diff --git a/test/jdk/jdk/jfr/event/runtime/TestShutdownEvent.java b/test/jdk/jdk/jfr/event/runtime/TestShutdownEvent.java index 37ad0ba9ead..ba84006ad39 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestShutdownEvent.java +++ b/test/jdk/jdk/jfr/event/runtime/TestShutdownEvent.java @@ -103,7 +103,7 @@ public class TestShutdownEvent { int exitCode = output.getExitValue(); System.out.println("Exit code: " + exitCode); - String recordingName = output.firstMatch("emergency jfr file: (.*.jfr)", 1); + String recordingName = output.firstMatch("JFR recording file will be written. Location: (.*.jfr)", 1); if (recordingName == null) { recordingName = "./dumped.jfr"; } From a97932d8fcb24da24d18b9033000238a8d608453 Mon Sep 17 00:00:00 2001 From: Hai-May Chao Date: Tue, 19 May 2020 11:55:44 +0800 Subject: [PATCH 106/143] 8245151: jarsigner should not raise duplicate warnings on verification Reviewed-by: weijun --- .../share/classes/sun/security/tools/jarsigner/Main.java | 2 +- .../share/classes/sun/security/tools/jarsigner/Resources.java | 2 ++ test/jdk/sun/security/tools/jarsigner/TimestampCheck.java | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java index d56433d3983..87e066ac32e 100644 --- a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java +++ b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java @@ -1195,7 +1195,7 @@ public class Main { if ((legacyAlg & 4) != 0) { warnings.add(String.format( - rb.getString("The.digest.algorithm.1.is.considered.a.security.risk..This.algorithm.will.be.disabled.in.a.future.update."), + rb.getString("The.timestamp.digest.algorithm.1.is.considered.a.security.risk..This.algorithm.will.be.disabled.in.a.future.update."), legacyTsaDigestAlg)); } diff --git a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java index adb314189c0..addd961df32 100644 --- a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java +++ b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java @@ -282,6 +282,8 @@ public class Resources extends java.util.ListResourceBundle { "The %1$s algorithm specified for the %2$s option is considered a security risk. This algorithm will be disabled in a future update."}, {"The.1.algorithm.specified.for.the.2.option.is.considered.a.security.risk.and.is.disabled.", "The %1$s algorithm specified for the %2$s option is considered a security risk and is disabled."}, + {"The.timestamp.digest.algorithm.1.is.considered.a.security.risk..This.algorithm.will.be.disabled.in.a.future.update.", + "The %1$s timestamp digest algorithm is considered a security risk. This algorithm will be disabled in a future update."}, {"The.digest.algorithm.1.is.considered.a.security.risk..This.algorithm.will.be.disabled.in.a.future.update.", "The %1$s digest algorithm is considered a security risk. This algorithm will be disabled in a future update."}, {"The.signature.algorithm.1.is.considered.a.security.risk..This.algorithm.will.be.disabled.in.a.future.update.", diff --git a/test/jdk/sun/security/tools/jarsigner/TimestampCheck.java b/test/jdk/sun/security/tools/jarsigner/TimestampCheck.java index d1bc0ae0491..2f48b511a10 100644 --- a/test/jdk/sun/security/tools/jarsigner/TimestampCheck.java +++ b/test/jdk/sun/security/tools/jarsigner/TimestampCheck.java @@ -445,7 +445,7 @@ public class TimestampCheck { verify("sha1tsaalg.jar", "-strict") .shouldHaveExitValue(0) .shouldContain("jar verified, with signer errors") - .shouldContain("SHA-1 digest algorithm is considered a security risk") + .shouldContain("SHA-1 timestamp digest algorithm is considered a security risk") .shouldNotContain("is disabled"); // Disabled algorithms From 080b3b83ebffe5149fbc9ac48e921fb51e9c3c63 Mon Sep 17 00:00:00 2001 From: Valerie Peng Date: Tue, 19 May 2020 04:05:03 +0000 Subject: [PATCH 107/143] 8242151: Improve OID mapping and reuse among JDK security providers for aliases registration Use sun.security.util.KnownOIDs enum instead of hardcoding oid strings everywhere Reviewed-by: weijun --- .../classes/apple/security/KeychainStore.java | 4 +- .../com/sun/crypto/provider/DHPublicKey.java | 2 +- .../com/sun/crypto/provider/KeyProtector.java | 18 +- .../sun/crypto/provider/OAEPParameters.java | 4 +- .../sun/crypto/provider/PBES2Parameters.java | 54 +- .../com/sun/crypto/provider/SunJCE.java | 563 +++++++---------- .../java/security/PKCS12Attribute.java | 2 +- .../cert/CertificateRevokedException.java | 4 +- .../java/security/cert/X509CertSelector.java | 16 +- .../sun/security/pkcs/ContentInfo.java | 22 +- .../classes/sun/security/pkcs/PKCS7.java | 2 +- .../sun/security/pkcs/PKCS9Attribute.java | 187 ++---- .../sun/security/pkcs12/PKCS12KeyStore.java | 43 +- .../sun/security/provider/KeyProtector.java | 12 +- .../sun/security/provider/SunEntries.java | 170 +++-- .../provider/certpath/OCSPResponse.java | 7 +- .../provider/certpath/RevocationChecker.java | 3 +- .../sun/security/rsa/PSSParameters.java | 4 +- .../sun/security/rsa/SunRsaSignEntries.java | 89 ++- .../classes/sun/security/ssl/SunJSSE.java | 16 +- .../sun/security/ssl/X509KeyManagerImpl.java | 18 +- .../sun/security/timestamp/TSRequest.java | 4 +- .../sun/security/tools/keytool/Main.java | 87 +-- .../security/util/ConstraintsParameters.java | 4 +- .../classes/sun/security/util/CurveDB.java | 291 ++++----- .../classes/sun/security/util/KnownOIDs.java | 495 +++++++++++++++ .../classes/sun/security/util/NamedCurve.java | 40 +- .../sun/security/util/ObjectIdentifier.java | 43 +- .../util/SecurityProviderConstants.java | 90 ++- .../security/validator/EndEntityChecker.java | 28 +- .../security/validator/SimpleValidator.java | 23 +- .../share/classes/sun/security/x509/AVA.java | 6 +- .../sun/security/x509/AccessDescription.java | 8 +- .../sun/security/x509/AlgorithmId.java | 590 ++++-------------- .../x509/ExtendedKeyUsageExtension.java | 31 +- .../x509/InhibitAnyPolicyExtension.java | 7 +- .../x509/NetscapeCertTypeExtension.java | 2 +- .../classes/sun/security/x509/OIDMap.java | 4 +- .../classes/sun/security/x509/OIDName.java | 4 +- .../sun/security/x509/PKIXExtensions.java | 54 +- .../classes/sun/security/x509/X500Name.java | 34 +- .../sun/security/x509/X509CRLEntryImpl.java | 7 +- .../sun/security/x509/X509CRLImpl.java | 4 +- .../sun/security/x509/X509CertImpl.java | 19 +- .../share/classes/org/ietf/jgss/Oid.java | 4 +- .../sun/security/jgss/GSSContextImpl.java | 4 +- .../sun/security/jgss/GSSNameImpl.java | 4 +- .../sun/security/jgss/krb5/Krb5Token.java | 4 +- .../sun/security/jgss/spnego/SpNegoToken.java | 4 +- .../security/jgss/wrapper/GSSNameElement.java | 4 +- .../jgss/wrapper/NativeGSSContext.java | 4 +- .../sun/security/pkcs11/SunPKCS11.java | 208 +++--- .../share/classes/sun/security/ec/SunEC.java | 99 ++- .../sun/security/ec/XECParameters.java | 2 +- .../sun/security/ec/ed/EdDSAParameters.java | 64 +- .../sun/security/mscapi/SunMSCAPI.java | 83 +-- .../oracle/security/ucrypto/LibMDMech.java | 22 +- .../oracle/security/ucrypto/ServiceDesc.java | 10 +- .../oracle/security/ucrypto/UcryptoMech.java | 132 ++-- .../security/ucrypto/UcryptoProvider.java | 8 +- .../tools/jarsigner/TimestampedSigner.java | 22 +- .../testlibrary/CertificateBuilder.java | 4 +- .../testlibrary/SimpleOCSPServer.java | 9 +- .../jgss/spnego/NotPreferredMech.java | 8 +- .../pkcs/pkcs10/PKCS10AttrEncoding.java | 6 +- .../pkcs/pkcs10/PKCS10AttributeReader.java | 6 +- .../security/pkcs/pkcs9/UnknownAttribute.java | 8 +- .../sun/security/pkcs12/PKCS12SameKeyId.java | 6 +- .../security/pkcs12/ParamsPreferences.java | 76 +-- test/jdk/sun/security/pkcs12/ParamsTest.java | 66 +- .../tools/jarsigner/TimestampCheck.java | 7 +- .../security/tools/keytool/KeyToolTest.java | 22 +- test/jdk/sun/security/util/Oid/OidEquals.java | 6 +- test/jdk/sun/security/util/Oid/OidFormat.java | 8 +- test/jdk/sun/security/util/Oid/S11N.java | 6 +- .../security/x509/AVA/AVAEqualsHashCode.java | 4 +- .../AlgorithmId/ExtensibleAlgorithmId.java | 51 +- .../x509/X509CertImpl/V3Certificate.java | 4 +- .../x509/equalNames/AltNamesEqualsTest.java | 6 +- 79 files changed, 2016 insertions(+), 2080 deletions(-) create mode 100644 src/java.base/share/classes/sun/security/util/KnownOIDs.java diff --git a/src/java.base/macosx/classes/apple/security/KeychainStore.java b/src/java.base/macosx/classes/apple/security/KeychainStore.java index f40518c9519..01e4df357bc 100644 --- a/src/java.base/macosx/classes/apple/security/KeychainStore.java +++ b/src/java.base/macosx/classes/apple/security/KeychainStore.java @@ -93,9 +93,9 @@ public final class KeychainStore extends KeyStoreSpi { * PKCS12 bag we get from the Keychain. */ private static ObjectIdentifier PKCS8ShroudedKeyBag_OID = - ObjectIdentifier.of("1.2.840.113549.1.12.10.1.2"); + ObjectIdentifier.of(KnownOIDs.PKCS8ShroudedKeyBag); private static ObjectIdentifier pbeWithSHAAnd3KeyTripleDESCBC_OID = - ObjectIdentifier.of("1.2.840.113549.1.12.1.3"); + ObjectIdentifier.of(KnownOIDs.PBEWithSHA1AndDESede); /** * Constnats used in PBE decryption. diff --git a/src/java.base/share/classes/com/sun/crypto/provider/DHPublicKey.java b/src/java.base/share/classes/com/sun/crypto/provider/DHPublicKey.java index 7c54d7482b5..bf33173ff2e 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/DHPublicKey.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/DHPublicKey.java @@ -71,7 +71,7 @@ javax.crypto.interfaces.DHPublicKey, Serializable { // Note: this OID is used by DHPrivateKey as well. static ObjectIdentifier DH_OID = - ObjectIdentifier.of("1.2.840.113549.1.3.1"); + ObjectIdentifier.of(KnownOIDs.DiffieHellman); /** * Make a DH public key out of a public value y, a prime diff --git a/src/java.base/share/classes/com/sun/crypto/provider/KeyProtector.java b/src/java.base/share/classes/com/sun/crypto/provider/KeyProtector.java index 408e445a9e3..974685befc5 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/KeyProtector.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/KeyProtector.java @@ -48,6 +48,7 @@ import javax.security.auth.DestroyFailedException; import sun.security.x509.AlgorithmId; import sun.security.util.ObjectIdentifier; +import sun.security.util.KnownOIDs; import sun.security.util.SecurityProperties; /** @@ -67,14 +68,6 @@ import sun.security.util.SecurityProperties; final class KeyProtector { - // defined by SunSoft (SKI project) - private static final String PBE_WITH_MD5_AND_DES3_CBC_OID - = "1.3.6.1.4.1.42.2.19.1"; - - // JavaSoft proprietary key-protection algorithm (used to protect private - // keys in the keystore implementation that comes with JDK 1.2) - private static final String KEY_PROTECTOR_OID = "1.3.6.1.4.1.42.2.17.1.1"; - private static final int MAX_ITERATION_COUNT = 5000000; private static final int MIN_ITERATION_COUNT = 10000; private static final int DEFAULT_ITERATION_COUNT = 200000; @@ -154,7 +147,8 @@ final class KeyProtector { pbeParams.init(pbeSpec); AlgorithmId encrAlg = new AlgorithmId - (new ObjectIdentifier(PBE_WITH_MD5_AND_DES3_CBC_OID), pbeParams); + (ObjectIdentifier.of(KnownOIDs.JAVASOFT_JCEKeyProtector), + pbeParams); return new EncryptedPrivateKeyInfo(encrAlg,encrKey).getEncoded(); } @@ -169,13 +163,13 @@ final class KeyProtector { SecretKey sKey = null; try { String encrAlg = encrInfo.getAlgorithm().getOID().toString(); - if (!encrAlg.equals(PBE_WITH_MD5_AND_DES3_CBC_OID) - && !encrAlg.equals(KEY_PROTECTOR_OID)) { + if (!encrAlg.equals(KnownOIDs.JAVASOFT_JCEKeyProtector.value()) + && !encrAlg.equals(KnownOIDs.JAVASOFT_JDKKeyProtector.value())) { throw new UnrecoverableKeyException("Unsupported encryption " + "algorithm"); } - if (encrAlg.equals(KEY_PROTECTOR_OID)) { + if (encrAlg.equals(KnownOIDs.JAVASOFT_JDKKeyProtector.value())) { // JDK 1.2 style recovery plain = recover(encrInfo.getEncryptedData()); } else { diff --git a/src/java.base/share/classes/com/sun/crypto/provider/OAEPParameters.java b/src/java.base/share/classes/com/sun/crypto/provider/OAEPParameters.java index ca2d70fe69a..57261376d78 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/OAEPParameters.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/OAEPParameters.java @@ -56,9 +56,9 @@ public final class OAEPParameters extends AlgorithmParametersSpi { private MGF1ParameterSpec mgfSpec; private byte[] p; private static ObjectIdentifier OID_MGF1 = - ObjectIdentifier.of("1.2.840.113549.1.1.8"); + ObjectIdentifier.of(KnownOIDs.MGF1); private static ObjectIdentifier OID_PSpecified = - ObjectIdentifier.of("1.2.840.113549.1.1.9"); + ObjectIdentifier.of(KnownOIDs.PSpecified); public OAEPParameters() { } diff --git a/src/java.base/share/classes/com/sun/crypto/provider/PBES2Parameters.java b/src/java.base/share/classes/com/sun/crypto/provider/PBES2Parameters.java index 0c2e420eedc..8b199f7abd2 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/PBES2Parameters.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/PBES2Parameters.java @@ -93,25 +93,15 @@ import sun.security.util.*; abstract class PBES2Parameters extends AlgorithmParametersSpi { private static ObjectIdentifier pkcs5PBKDF2_OID = - ObjectIdentifier.of("1.2.840.113549.1.5.12"); + ObjectIdentifier.of(KnownOIDs.PBKDF2WithHmacSHA1); private static ObjectIdentifier pkcs5PBES2_OID = - ObjectIdentifier.of("1.2.840.113549.1.5.13"); - private static ObjectIdentifier hmacWithSHA1_OID = - ObjectIdentifier.of("1.2.840.113549.2.7"); - private static ObjectIdentifier hmacWithSHA224_OID = - ObjectIdentifier.of("1.2.840.113549.2.8"); - private static ObjectIdentifier hmacWithSHA256_OID = - ObjectIdentifier.of("1.2.840.113549.2.9"); - private static ObjectIdentifier hmacWithSHA384_OID = - ObjectIdentifier.of("1.2.840.113549.2.10"); - private static ObjectIdentifier hmacWithSHA512_OID = - ObjectIdentifier.of("1.2.840.113549.2.11"); + ObjectIdentifier.of(KnownOIDs.PBES2); private static ObjectIdentifier aes128CBC_OID = - ObjectIdentifier.of("2.16.840.1.101.3.4.1.2"); + ObjectIdentifier.of(KnownOIDs.AES_128$CBC$NoPadding); private static ObjectIdentifier aes192CBC_OID = - ObjectIdentifier.of("2.16.840.1.101.3.4.1.22"); + ObjectIdentifier.of(KnownOIDs.AES_192$CBC$NoPadding); private static ObjectIdentifier aes256CBC_OID = - ObjectIdentifier.of("2.16.840.1.101.3.4.1.42"); + ObjectIdentifier.of(KnownOIDs.AES_256$CBC$NoPadding); // the PBES2 algorithm name private String pbes2AlgorithmName = null; @@ -126,7 +116,8 @@ abstract class PBES2Parameters extends AlgorithmParametersSpi { private AlgorithmParameterSpec cipherParam = null; // the key derivation function (default is HmacSHA1) - private ObjectIdentifier kdfAlgo_OID = hmacWithSHA1_OID; + private ObjectIdentifier kdfAlgo_OID = + ObjectIdentifier.of(KnownOIDs.HmacSHA1); // the encryption function private ObjectIdentifier cipherAlgo_OID = null; @@ -171,19 +162,11 @@ abstract class PBES2Parameters extends AlgorithmParametersSpi { switch (kdfAlgo) { case "HmacSHA1": - kdfAlgo_OID = hmacWithSHA1_OID; - break; case "HmacSHA224": - kdfAlgo_OID = hmacWithSHA224_OID; - break; case "HmacSHA256": - kdfAlgo_OID = hmacWithSHA256_OID; - break; case "HmacSHA384": - kdfAlgo_OID = hmacWithSHA384_OID; - break; case "HmacSHA512": - kdfAlgo_OID = hmacWithSHA512_OID; + kdfAlgo_OID = ObjectIdentifier.of(KnownOIDs.findMatch(kdfAlgo)); break; default: throw new NoSuchAlgorithmException( @@ -255,7 +238,7 @@ abstract class PBES2Parameters extends AlgorithmParametersSpi { } cipherAlgo = parseES(pBES2_params.data.getDerValue()); - pbes2AlgorithmName = new StringBuilder().append("PBEWith") + this.pbes2AlgorithmName = new StringBuilder().append("PBEWith") .append(kdfAlgo).append("And").append(cipherAlgo).toString(); } @@ -306,21 +289,18 @@ abstract class PBES2Parameters extends AlgorithmParametersSpi { } if (prf != null) { kdfAlgo_OID = prf.data.getOID(); - if (hmacWithSHA1_OID.equals(kdfAlgo_OID)) { - kdfAlgo = "HmacSHA1"; - } else if (hmacWithSHA224_OID.equals(kdfAlgo_OID)) { - kdfAlgo = "HmacSHA224"; - } else if (hmacWithSHA256_OID.equals(kdfAlgo_OID)) { - kdfAlgo = "HmacSHA256"; - } else if (hmacWithSHA384_OID.equals(kdfAlgo_OID)) { - kdfAlgo = "HmacSHA384"; - } else if (hmacWithSHA512_OID.equals(kdfAlgo_OID)) { - kdfAlgo = "HmacSHA512"; - } else { + KnownOIDs o = KnownOIDs.findMatch(kdfAlgo_OID.toString()); + if (o == null || (!o.stdName().equals("HmacSHA1") && + !o.stdName().equals("HmacSHA224") && + !o.stdName().equals("HmacSHA256") && + !o.stdName().equals("HmacSHA384") && + !o.stdName().equals("HmacSHA512"))) { throw new IOException("PBE parameter parsing error: " + "expecting the object identifier for a HmacSHA key " + "derivation function"); } + kdfAlgo = o.stdName(); + if (prf.data.available() != 0) { // parameter is 'NULL' for all HmacSHA KDFs DerValue parameter = prf.data.getDerValue(); diff --git a/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java b/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java index fa03b6b3622..0c7e0ed266a 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java @@ -32,8 +32,7 @@ import java.security.PrivilegedAction; import java.util.HashMap; import java.util.List; import static sun.security.util.SecurityConstants.PROVIDER_VER; -import static sun.security.provider.SunEntries.createAliases; -import static sun.security.provider.SunEntries.createAliasesWithOid; +import static sun.security.util.SecurityProviderConstants.*; /** * The "SunJCE" Cryptographic Service Provider. @@ -100,9 +99,22 @@ public final class SunJCE extends Provider { } static SecureRandom getRandom() { return SecureRandomHolder.RANDOM; } - private void ps(String type, String algo, String cn, - List aliases, HashMap attrs) { - putService(new Provider.Service(this, type, algo, cn, aliases, attrs)); + // ps: putService + private void ps(String type, String algo, String cn) { + putService(new Provider.Service(this, type, algo, cn, null, null)); + } + + private void ps(String type, String algo, String cn, List als, + HashMap attrs) { + putService(new Provider.Service(this, type, algo, cn, als, + attrs)); + } + + // psA: putService with default aliases + private void psA(String type, String algo, String cn, + HashMap attrs) { + putService(new Provider.Service(this, type, algo, cn, getAliases(algo), + attrs)); } public SunJCE() { @@ -128,69 +140,6 @@ public final class SunJCE extends Provider { } void putEntries() { - // common aliases and oids - List aesAliases = createAliases("Rijndael"); - List desEdeAliases = createAliases("TripleDES"); - List arcFourAliases = createAliases("RC4"); - List sunTlsMSAliases = createAliases( - "SunTls12MasterSecret", "SunTlsExtendedMasterSecret" - ); - List sunTlsKMAliases = createAliases("SunTls12KeyMaterial"); - List sunTlsRsaPMSAliases = createAliases("SunTls12RsaPremasterSecret"); - - String aes128Oid = "2.16.840.1.101.3.4.1."; - String aes192Oid = "2.16.840.1.101.3.4.1.2"; - String aes256Oid = "2.16.840.1.101.3.4.1.4"; - - List pkcs12RC4_128Aliases = - createAliasesWithOid("1.2.840.113549.1.12.1.1"); - - List pkcs12RC4_40Aliases = - createAliasesWithOid("1.2.840.113549.1.12.1.2"); - - List pkcs12DESedeAliases = - createAliasesWithOid("1.2.840.113549.1.12.1.3"); - - List pkcs12RC2_128Aliases = - createAliasesWithOid("1.2.840.113549.1.12.1.5"); - - List pkcs12RC2_40Aliases = - createAliasesWithOid("1.2.840.113549.1.12.1.6"); - - List pkcs5MD5_DESAliases = - createAliasesWithOid("1.2.840.113549.1.5.3", "PBE"); - - List pkcs5PBKDF2Aliases = - createAliasesWithOid("1.2.840.113549.1.5.12"); - - List pkcs5PBES2Aliases = - createAliasesWithOid("1.2.840.113549.1.5.13"); - - List diffieHellmanAliases = - createAliasesWithOid("1.2.840.113549.1.3.1", "DH"); - - List chachaPolyAliases = - createAliasesWithOid("1.2.840.113549.1.9.16.3.18"); - - String macOidBase = "1.2.840.113549.2."; - List macSHA1Aliases = createAliasesWithOid(macOidBase + "7"); - List macSHA224Aliases = createAliasesWithOid(macOidBase + "8"); - List macSHA256Aliases = createAliasesWithOid(macOidBase + "9"); - List macSHA384Aliases = createAliasesWithOid(macOidBase + "10"); - List macSHA512Aliases = createAliasesWithOid(macOidBase + "11"); - List macSHA512_224Aliases = createAliasesWithOid(macOidBase + "12"); - List macSHA512_256Aliases = createAliasesWithOid(macOidBase + "13"); - - String nistHashAlgsOidBase = "2.16.840.1.101.3.4.2."; - List macSHA3_224Aliases = - createAliasesWithOid(nistHashAlgsOidBase + "13"); - List macSHA3_256Aliases = - createAliasesWithOid(nistHashAlgsOidBase + "14"); - List macSHA3_384Aliases = - createAliasesWithOid(nistHashAlgsOidBase + "15"); - List macSHA3_512Aliases = - createAliasesWithOid(nistHashAlgsOidBase + "16"); - // reuse attribute map and reset before each reuse HashMap attrs = new HashMap<>(3); attrs.put("SupportedModes", "ECB"); @@ -225,8 +174,8 @@ public final class SunJCE extends Provider { attrs.put("SupportedKeyFormats", "RAW"); ps("Cipher", "DES", "com.sun.crypto.provider.DESCipher", null, attrs); - ps("Cipher", "DESede", "com.sun.crypto.provider.DESedeCipher", - desEdeAliases, attrs); + psA("Cipher", "DESede", "com.sun.crypto.provider.DESedeCipher", + attrs); ps("Cipher", "Blowfish", "com.sun.crypto.provider.BlowfishCipher", null, attrs); @@ -237,58 +186,58 @@ public final class SunJCE extends Provider { attrs.put("SupportedModes", BLOCK_MODES128); attrs.put("SupportedPaddings", BLOCK_PADS); attrs.put("SupportedKeyFormats", "RAW"); - ps("Cipher", "AES", "com.sun.crypto.provider.AESCipher$General", - aesAliases, attrs); + psA("Cipher", "AES", + "com.sun.crypto.provider.AESCipher$General", attrs); attrs.clear(); attrs.put("SupportedKeyFormats", "RAW"); - ps("Cipher", "AES_128/ECB/NoPadding", + psA("Cipher", "AES_128/ECB/NoPadding", "com.sun.crypto.provider.AESCipher$AES128_ECB_NoPadding", - createAliasesWithOid(aes128Oid+"1"), attrs); - ps("Cipher", "AES_128/CBC/NoPadding", + attrs); + psA("Cipher", "AES_128/CBC/NoPadding", "com.sun.crypto.provider.AESCipher$AES128_CBC_NoPadding", - createAliasesWithOid(aes128Oid+"2"), attrs); - ps("Cipher", "AES_128/OFB/NoPadding", + attrs); + psA("Cipher", "AES_128/OFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES128_OFB_NoPadding", - createAliasesWithOid(aes128Oid+"3"), attrs); - ps("Cipher", "AES_128/CFB/NoPadding", + attrs); + psA("Cipher", "AES_128/CFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES128_CFB_NoPadding", - createAliasesWithOid(aes128Oid+"4"), attrs); - ps("Cipher", "AES_128/GCM/NoPadding", + attrs); + psA("Cipher", "AES_128/GCM/NoPadding", "com.sun.crypto.provider.AESCipher$AES128_GCM_NoPadding", - createAliasesWithOid(aes128Oid+"6"), attrs); + attrs); - ps("Cipher", "AES_192/ECB/NoPadding", + psA("Cipher", "AES_192/ECB/NoPadding", "com.sun.crypto.provider.AESCipher$AES192_ECB_NoPadding", - createAliasesWithOid(aes192Oid+"1"), attrs); - ps("Cipher", "AES_192/CBC/NoPadding", + attrs); + psA("Cipher", "AES_192/CBC/NoPadding", "com.sun.crypto.provider.AESCipher$AES192_CBC_NoPadding", - createAliasesWithOid(aes192Oid+"2"), attrs); - ps("Cipher", "AES_192/OFB/NoPadding", + attrs); + psA("Cipher", "AES_192/OFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES192_OFB_NoPadding", - createAliasesWithOid(aes192Oid+"3"), attrs); - ps("Cipher", "AES_192/CFB/NoPadding", + attrs); + psA("Cipher", "AES_192/CFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES192_CFB_NoPadding", - createAliasesWithOid(aes192Oid+"4"), attrs); - ps("Cipher", "AES_192/GCM/NoPadding", + attrs); + psA("Cipher", "AES_192/GCM/NoPadding", "com.sun.crypto.provider.AESCipher$AES192_GCM_NoPadding", - createAliasesWithOid(aes192Oid+"6"), attrs); + attrs); - ps("Cipher", "AES_256/ECB/NoPadding", + psA("Cipher", "AES_256/ECB/NoPadding", "com.sun.crypto.provider.AESCipher$AES256_ECB_NoPadding", - createAliasesWithOid(aes256Oid+"1"), attrs); - ps("Cipher", "AES_256/CBC/NoPadding", + attrs); + psA("Cipher", "AES_256/CBC/NoPadding", "com.sun.crypto.provider.AESCipher$AES256_CBC_NoPadding", - createAliasesWithOid(aes256Oid+"2"), attrs); - ps("Cipher", "AES_256/OFB/NoPadding", + attrs); + psA("Cipher", "AES_256/OFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES256_OFB_NoPadding", - createAliasesWithOid(aes256Oid+"3"), attrs); - ps("Cipher", "AES_256/CFB/NoPadding", + attrs); + psA("Cipher", "AES_256/CFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES256_CFB_NoPadding", - createAliasesWithOid(aes256Oid+"4"), attrs); - ps("Cipher", "AES_256/GCM/NoPadding", + attrs); + psA("Cipher", "AES_256/GCM/NoPadding", "com.sun.crypto.provider.AESCipher$AES256_GCM_NoPadding", - createAliasesWithOid(aes256Oid+"6"), attrs); + attrs); attrs.clear(); attrs.put("SupportedModes", "CBC"); @@ -301,167 +250,150 @@ public final class SunJCE extends Provider { attrs.put("SupportedModes", "ECB"); attrs.put("SupportedPaddings", "NOPADDING"); attrs.put("SupportedKeyFormats", "RAW"); - ps("Cipher", "ARCFOUR", "com.sun.crypto.provider.ARCFOURCipher", - arcFourAliases, attrs); + psA("Cipher", "ARCFOUR", + "com.sun.crypto.provider.ARCFOURCipher", attrs); ps("Cipher", "AESWrap", "com.sun.crypto.provider.AESWrapCipher$General", null, attrs); - ps("Cipher", "AESWrap_128", + psA("Cipher", "AESWrap_128", "com.sun.crypto.provider.AESWrapCipher$AES128", - createAliasesWithOid(aes128Oid+"5"), attrs); - ps("Cipher", "AESWrap_192", + attrs); + psA("Cipher", "AESWrap_192", "com.sun.crypto.provider.AESWrapCipher$AES192", - createAliasesWithOid(aes192Oid+"5"), attrs); - ps("Cipher", "AESWrap_256", + attrs); + psA("Cipher", "AESWrap_256", "com.sun.crypto.provider.AESWrapCipher$AES256", - createAliasesWithOid(aes256Oid+"5"), attrs); + attrs); attrs.clear(); attrs.put("SupportedKeyFormats", "RAW"); ps("Cipher", "ChaCha20", "com.sun.crypto.provider.ChaCha20Cipher$ChaCha20Only", null, attrs); - ps("Cipher", "ChaCha20-Poly1305", + psA("Cipher", "ChaCha20-Poly1305", "com.sun.crypto.provider.ChaCha20Cipher$ChaCha20Poly1305", - chachaPolyAliases, attrs); + attrs); // PBES1 - ps("Cipher", "PBEWithMD5AndDES", + psA("Cipher", "PBEWithMD5AndDES", "com.sun.crypto.provider.PBEWithMD5AndDESCipher", - pkcs5MD5_DESAliases, null); + null); ps("Cipher", "PBEWithMD5AndTripleDES", - "com.sun.crypto.provider.PBEWithMD5AndTripleDESCipher", - null, null); - ps("Cipher", "PBEWithSHA1AndDESede", + "com.sun.crypto.provider.PBEWithMD5AndTripleDESCipher"); + psA("Cipher", "PBEWithSHA1AndDESede", "com.sun.crypto.provider.PKCS12PBECipherCore$PBEWithSHA1AndDESede", - pkcs12DESedeAliases, null); - ps("Cipher", "PBEWithSHA1AndRC2_40", + null); + psA("Cipher", "PBEWithSHA1AndRC2_40", "com.sun.crypto.provider.PKCS12PBECipherCore$PBEWithSHA1AndRC2_40", - pkcs12RC2_40Aliases, null); - ps("Cipher", "PBEWithSHA1AndRC2_128", + null); + psA("Cipher", "PBEWithSHA1AndRC2_128", "com.sun.crypto.provider.PKCS12PBECipherCore$PBEWithSHA1AndRC2_128", - pkcs12RC2_128Aliases, null); - ps("Cipher", "PBEWithSHA1AndRC4_40", + null); + psA("Cipher", "PBEWithSHA1AndRC4_40", "com.sun.crypto.provider.PKCS12PBECipherCore$PBEWithSHA1AndRC4_40", - pkcs12RC4_40Aliases, null); + null); - ps("Cipher", "PBEWithSHA1AndRC4_128", + psA("Cipher", "PBEWithSHA1AndRC4_128", "com.sun.crypto.provider.PKCS12PBECipherCore$PBEWithSHA1AndRC4_128", - pkcs12RC4_128Aliases, null); + null); // PBES2 ps("Cipher", "PBEWithHmacSHA1AndAES_128", - "com.sun.crypto.provider.PBES2Core$HmacSHA1AndAES_128", - null, null); + "com.sun.crypto.provider.PBES2Core$HmacSHA1AndAES_128"); ps("Cipher", "PBEWithHmacSHA224AndAES_128", - "com.sun.crypto.provider.PBES2Core$HmacSHA224AndAES_128", - null, null); + "com.sun.crypto.provider.PBES2Core$HmacSHA224AndAES_128"); ps("Cipher", "PBEWithHmacSHA256AndAES_128", - "com.sun.crypto.provider.PBES2Core$HmacSHA256AndAES_128", - null, null); + "com.sun.crypto.provider.PBES2Core$HmacSHA256AndAES_128"); ps("Cipher", "PBEWithHmacSHA384AndAES_128", - "com.sun.crypto.provider.PBES2Core$HmacSHA384AndAES_128", - null, null); + "com.sun.crypto.provider.PBES2Core$HmacSHA384AndAES_128"); ps("Cipher", "PBEWithHmacSHA512AndAES_128", - "com.sun.crypto.provider.PBES2Core$HmacSHA512AndAES_128", - null, null); + "com.sun.crypto.provider.PBES2Core$HmacSHA512AndAES_128"); ps("Cipher", "PBEWithHmacSHA1AndAES_256", - "com.sun.crypto.provider.PBES2Core$HmacSHA1AndAES_256", - null, null); + "com.sun.crypto.provider.PBES2Core$HmacSHA1AndAES_256"); ps("Cipher", "PBEWithHmacSHA224AndAES_256", - "com.sun.crypto.provider.PBES2Core$HmacSHA224AndAES_256", - null, null); + "com.sun.crypto.provider.PBES2Core$HmacSHA224AndAES_256"); ps("Cipher", "PBEWithHmacSHA256AndAES_256", - "com.sun.crypto.provider.PBES2Core$HmacSHA256AndAES_256", - null, null); + "com.sun.crypto.provider.PBES2Core$HmacSHA256AndAES_256"); ps("Cipher", "PBEWithHmacSHA384AndAES_256", - "com.sun.crypto.provider.PBES2Core$HmacSHA384AndAES_256", - null, null); + "com.sun.crypto.provider.PBES2Core$HmacSHA384AndAES_256"); ps("Cipher", "PBEWithHmacSHA512AndAES_256", - "com.sun.crypto.provider.PBES2Core$HmacSHA512AndAES_256", - null, null); + "com.sun.crypto.provider.PBES2Core$HmacSHA512AndAES_256"); /* * Key(pair) Generator engines */ ps("KeyGenerator", "DES", - "com.sun.crypto.provider.DESKeyGenerator", - null, null); - ps("KeyGenerator", "DESede", + "com.sun.crypto.provider.DESKeyGenerator"); + psA("KeyGenerator", "DESede", "com.sun.crypto.provider.DESedeKeyGenerator", - desEdeAliases, null); + null); ps("KeyGenerator", "Blowfish", - "com.sun.crypto.provider.BlowfishKeyGenerator", - null, null); - ps("KeyGenerator", "AES", + "com.sun.crypto.provider.BlowfishKeyGenerator"); + psA("KeyGenerator", "AES", "com.sun.crypto.provider.AESKeyGenerator", - aesAliases, null); + null); ps("KeyGenerator", "RC2", - "com.sun.crypto.provider.KeyGeneratorCore$RC2KeyGenerator", - null, null); - ps("KeyGenerator", "ARCFOUR", + "com.sun.crypto.provider.KeyGeneratorCore$RC2KeyGenerator"); + psA("KeyGenerator", "ARCFOUR", "com.sun.crypto.provider.KeyGeneratorCore$ARCFOURKeyGenerator", - arcFourAliases, null); + null); ps("KeyGenerator", "ChaCha20", - "com.sun.crypto.provider.KeyGeneratorCore$ChaCha20KeyGenerator", - null, null); + "com.sun.crypto.provider.KeyGeneratorCore$ChaCha20KeyGenerator"); ps("KeyGenerator", "HmacMD5", - "com.sun.crypto.provider.HmacMD5KeyGenerator", - null, null); + "com.sun.crypto.provider.HmacMD5KeyGenerator"); - ps("KeyGenerator", "HmacSHA1", - "com.sun.crypto.provider.HmacSHA1KeyGenerator", - macSHA1Aliases, null); - ps("KeyGenerator", "HmacSHA224", + psA("KeyGenerator", "HmacSHA1", + "com.sun.crypto.provider.HmacSHA1KeyGenerator", null); + psA("KeyGenerator", "HmacSHA224", "com.sun.crypto.provider.KeyGeneratorCore$HmacKG$SHA224", - macSHA224Aliases, null); - ps("KeyGenerator", "HmacSHA256", + null); + psA("KeyGenerator", "HmacSHA256", "com.sun.crypto.provider.KeyGeneratorCore$HmacKG$SHA256", - macSHA256Aliases, null); - ps("KeyGenerator", "HmacSHA384", + null); + psA("KeyGenerator", "HmacSHA384", "com.sun.crypto.provider.KeyGeneratorCore$HmacKG$SHA384", - macSHA384Aliases, null); - ps("KeyGenerator", "HmacSHA512", + null); + psA("KeyGenerator", "HmacSHA512", "com.sun.crypto.provider.KeyGeneratorCore$HmacKG$SHA512", - macSHA512Aliases, null); - ps("KeyGenerator", "HmacSHA512/224", + null); + psA("KeyGenerator", "HmacSHA512/224", "com.sun.crypto.provider.KeyGeneratorCore$HmacKG$SHA512_224", - macSHA512_224Aliases, null); - ps("KeyGenerator", "HmacSHA512/256", + null); + psA("KeyGenerator", "HmacSHA512/256", "com.sun.crypto.provider.KeyGeneratorCore$HmacKG$SHA512_256", - macSHA512_256Aliases, null); + null); - ps("KeyGenerator", "HmacSHA3-224", + psA("KeyGenerator", "HmacSHA3-224", "com.sun.crypto.provider.KeyGeneratorCore$HmacKG$SHA3_224", - macSHA3_224Aliases, null); - ps("KeyGenerator", "HmacSHA3-256", + null); + psA("KeyGenerator", "HmacSHA3-256", "com.sun.crypto.provider.KeyGeneratorCore$HmacKG$SHA3_256", - macSHA3_256Aliases, null); - ps("KeyGenerator", "HmacSHA3-384", + null); + psA("KeyGenerator", "HmacSHA3-384", "com.sun.crypto.provider.KeyGeneratorCore$HmacKG$SHA3_384", - macSHA3_384Aliases, null); - ps("KeyGenerator", "HmacSHA3-512", + null); + psA("KeyGenerator", "HmacSHA3-512", "com.sun.crypto.provider.KeyGeneratorCore$HmacKG$SHA3_512", - macSHA3_512Aliases, null); + null); - ps("KeyPairGenerator", "DiffieHellman", + psA("KeyPairGenerator", "DiffieHellman", "com.sun.crypto.provider.DHKeyPairGenerator", - diffieHellmanAliases, null); + null); /* * Algorithm parameter generation engines */ - ps("AlgorithmParameterGenerator", + psA("AlgorithmParameterGenerator", "DiffieHellman", "com.sun.crypto.provider.DHParameterGenerator", - diffieHellmanAliases, null); + null); /* * Key Agreement engines @@ -469,142 +401,120 @@ public final class SunJCE extends Provider { attrs.clear(); attrs.put("SupportedKeyClasses", "javax.crypto.interfaces.DHPublicKey" + "|javax.crypto.interfaces.DHPrivateKey"); - ps("KeyAgreement", "DiffieHellman", + psA("KeyAgreement", "DiffieHellman", "com.sun.crypto.provider.DHKeyAgreement", - diffieHellmanAliases, attrs); + attrs); /* * Algorithm Parameter engines */ - ps("AlgorithmParameters", "DiffieHellman", - "com.sun.crypto.provider.DHParameters", - diffieHellmanAliases, null); + psA("AlgorithmParameters", "DiffieHellman", + "com.sun.crypto.provider.DHParameters", null); ps("AlgorithmParameters", "DES", - "com.sun.crypto.provider.DESParameters", - null, null); + "com.sun.crypto.provider.DESParameters"); - ps("AlgorithmParameters", "DESede", - "com.sun.crypto.provider.DESedeParameters", - desEdeAliases, null); + psA("AlgorithmParameters", "DESede", + "com.sun.crypto.provider.DESedeParameters", null); - ps("AlgorithmParameters", "PBEWithMD5AndDES", + psA("AlgorithmParameters", "PBEWithMD5AndDES", "com.sun.crypto.provider.PBEParameters", - pkcs5MD5_DESAliases, null); + null); ps("AlgorithmParameters", "PBEWithMD5AndTripleDES", - "com.sun.crypto.provider.PBEParameters", - null, null); + "com.sun.crypto.provider.PBEParameters"); - ps("AlgorithmParameters", "PBEWithSHA1AndDESede", + psA("AlgorithmParameters", "PBEWithSHA1AndDESede", "com.sun.crypto.provider.PBEParameters", - pkcs12DESedeAliases, null); + null); - ps("AlgorithmParameters", "PBEWithSHA1AndRC2_40", + psA("AlgorithmParameters", "PBEWithSHA1AndRC2_40", "com.sun.crypto.provider.PBEParameters", - pkcs12RC2_40Aliases, null); + null); - ps("AlgorithmParameters", "PBEWithSHA1AndRC2_128", + psA("AlgorithmParameters", "PBEWithSHA1AndRC2_128", "com.sun.crypto.provider.PBEParameters", - pkcs12RC2_128Aliases, null); + null); - ps("AlgorithmParameters", "PBEWithSHA1AndRC4_40", + psA("AlgorithmParameters", "PBEWithSHA1AndRC4_40", "com.sun.crypto.provider.PBEParameters", - pkcs12RC4_40Aliases, null); + null); - ps("AlgorithmParameters", "PBEWithSHA1AndRC4_128", + psA("AlgorithmParameters", "PBEWithSHA1AndRC4_128", "com.sun.crypto.provider.PBEParameters", - pkcs12RC4_128Aliases, null); + null); - ps("AlgorithmParameters", "PBES2", + psA("AlgorithmParameters", "PBES2", "com.sun.crypto.provider.PBES2Parameters$General", - pkcs5PBES2Aliases, null); + null); ps("AlgorithmParameters", "PBEWithHmacSHA1AndAES_128", - "com.sun.crypto.provider.PBES2Parameters$HmacSHA1AndAES_128", - null, null); + "com.sun.crypto.provider.PBES2Parameters$HmacSHA1AndAES_128"); ps("AlgorithmParameters", "PBEWithHmacSHA224AndAES_128", - "com.sun.crypto.provider.PBES2Parameters$HmacSHA224AndAES_128", - null, null); + "com.sun.crypto.provider.PBES2Parameters$HmacSHA224AndAES_128"); ps("AlgorithmParameters", "PBEWithHmacSHA256AndAES_128", - "com.sun.crypto.provider.PBES2Parameters$HmacSHA256AndAES_128", - null, null); + "com.sun.crypto.provider.PBES2Parameters$HmacSHA256AndAES_128"); ps("AlgorithmParameters", "PBEWithHmacSHA384AndAES_128", - "com.sun.crypto.provider.PBES2Parameters$HmacSHA384AndAES_128", - null, null); + "com.sun.crypto.provider.PBES2Parameters$HmacSHA384AndAES_128"); ps("AlgorithmParameters", "PBEWithHmacSHA512AndAES_128", - "com.sun.crypto.provider.PBES2Parameters$HmacSHA512AndAES_128", - null, null); + "com.sun.crypto.provider.PBES2Parameters$HmacSHA512AndAES_128"); ps("AlgorithmParameters", "PBEWithHmacSHA1AndAES_256", - "com.sun.crypto.provider.PBES2Parameters$HmacSHA1AndAES_256", - null, null); + "com.sun.crypto.provider.PBES2Parameters$HmacSHA1AndAES_256"); ps("AlgorithmParameters", "PBEWithHmacSHA224AndAES_256", - "com.sun.crypto.provider.PBES2Parameters$HmacSHA224AndAES_256", - null, null); + "com.sun.crypto.provider.PBES2Parameters$HmacSHA224AndAES_256"); ps("AlgorithmParameters", "PBEWithHmacSHA256AndAES_256", - "com.sun.crypto.provider.PBES2Parameters$HmacSHA256AndAES_256", - null, null); + "com.sun.crypto.provider.PBES2Parameters$HmacSHA256AndAES_256"); ps("AlgorithmParameters", "PBEWithHmacSHA384AndAES_256", - "com.sun.crypto.provider.PBES2Parameters$HmacSHA384AndAES_256", - null, null); + "com.sun.crypto.provider.PBES2Parameters$HmacSHA384AndAES_256"); ps("AlgorithmParameters", "PBEWithHmacSHA512AndAES_256", - "com.sun.crypto.provider.PBES2Parameters$HmacSHA512AndAES_256", - null, null); + "com.sun.crypto.provider.PBES2Parameters$HmacSHA512AndAES_256"); ps("AlgorithmParameters", "Blowfish", - "com.sun.crypto.provider.BlowfishParameters", - null, null); + "com.sun.crypto.provider.BlowfishParameters"); - ps("AlgorithmParameters", "AES", - "com.sun.crypto.provider.AESParameters", - aesAliases, null); + psA("AlgorithmParameters", "AES", + "com.sun.crypto.provider.AESParameters", null); ps("AlgorithmParameters", "GCM", - "com.sun.crypto.provider.GCMParameters", - null, null); + "com.sun.crypto.provider.GCMParameters"); ps("AlgorithmParameters", "RC2", - "com.sun.crypto.provider.RC2Parameters", - null, null); + "com.sun.crypto.provider.RC2Parameters"); ps("AlgorithmParameters", "OAEP", - "com.sun.crypto.provider.OAEPParameters", - null, null); + "com.sun.crypto.provider.OAEPParameters"); - ps("AlgorithmParameters", "ChaCha20-Poly1305", - "com.sun.crypto.provider.ChaCha20Poly1305Parameters", - chachaPolyAliases, null); + psA("AlgorithmParameters", "ChaCha20-Poly1305", + "com.sun.crypto.provider.ChaCha20Poly1305Parameters", null); /* * Key factories */ - ps("KeyFactory", "DiffieHellman", + psA("KeyFactory", "DiffieHellman", "com.sun.crypto.provider.DHKeyFactory", - diffieHellmanAliases, null); + null); /* * Secret-key factories */ ps("SecretKeyFactory", "DES", - "com.sun.crypto.provider.DESKeyFactory", - null, null); + "com.sun.crypto.provider.DESKeyFactory"); - ps("SecretKeyFactory", "DESede", - "com.sun.crypto.provider.DESedeKeyFactory", - desEdeAliases, null); + psA("SecretKeyFactory", "DESede", + "com.sun.crypto.provider.DESedeKeyFactory", null); - ps("SecretKeyFactory", "PBEWithMD5AndDES", + psA("SecretKeyFactory", "PBEWithMD5AndDES", "com.sun.crypto.provider.PBEKeyFactory$PBEWithMD5AndDES", - pkcs5MD5_DESAliases, null); + null); /* * Internal in-house crypto algorithm used for @@ -613,85 +523,70 @@ public final class SunJCE extends Provider { * algorithm. */ ps("SecretKeyFactory", "PBEWithMD5AndTripleDES", - "com.sun.crypto.provider.PBEKeyFactory$PBEWithMD5AndTripleDES", - null, null); + "com.sun.crypto.provider.PBEKeyFactory$PBEWithMD5AndTripleDES"); - ps("SecretKeyFactory", "PBEWithSHA1AndDESede", + psA("SecretKeyFactory", "PBEWithSHA1AndDESede", "com.sun.crypto.provider.PBEKeyFactory$PBEWithSHA1AndDESede", - pkcs12DESedeAliases, null); + null); - ps("SecretKeyFactory", "PBEWithSHA1AndRC2_40", + psA("SecretKeyFactory", "PBEWithSHA1AndRC2_40", "com.sun.crypto.provider.PBEKeyFactory$PBEWithSHA1AndRC2_40", - pkcs12RC2_40Aliases, null); + null); - ps("SecretKeyFactory", "PBEWithSHA1AndRC2_128", + psA("SecretKeyFactory", "PBEWithSHA1AndRC2_128", "com.sun.crypto.provider.PBEKeyFactory$PBEWithSHA1AndRC2_128", - pkcs12RC2_128Aliases, null); + null); - ps("SecretKeyFactory", "PBEWithSHA1AndRC4_40", + psA("SecretKeyFactory", "PBEWithSHA1AndRC4_40", "com.sun.crypto.provider.PBEKeyFactory$PBEWithSHA1AndRC4_40", - pkcs12RC4_40Aliases,null); + null); - ps("SecretKeyFactory", "PBEWithSHA1AndRC4_128", + psA("SecretKeyFactory", "PBEWithSHA1AndRC4_128", "com.sun.crypto.provider.PBEKeyFactory$PBEWithSHA1AndRC4_128", - pkcs12RC4_128Aliases, null); + null); ps("SecretKeyFactory", "PBEWithHmacSHA1AndAES_128", - "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA1AndAES_128", - null, null); + "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA1AndAES_128"); ps("SecretKeyFactory", "PBEWithHmacSHA224AndAES_128", - "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA224AndAES_128", - null, null); + "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA224AndAES_128"); ps("SecretKeyFactory", "PBEWithHmacSHA256AndAES_128", - "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA256AndAES_128", - null, null); + "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA256AndAES_128"); ps("SecretKeyFactory", "PBEWithHmacSHA384AndAES_128", - "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA384AndAES_128", - null, null); + "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA384AndAES_128"); ps("SecretKeyFactory", "PBEWithHmacSHA512AndAES_128", - "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA512AndAES_128", - null, null); + "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA512AndAES_128"); ps("SecretKeyFactory", "PBEWithHmacSHA1AndAES_256", - "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA1AndAES_256", - null, null); + "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA1AndAES_256"); ps("SecretKeyFactory", "PBEWithHmacSHA224AndAES_256", - "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA224AndAES_256", - null, null); + "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA224AndAES_256"); ps("SecretKeyFactory", "PBEWithHmacSHA256AndAES_256", - "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA256AndAES_256", - null, null); + "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA256AndAES_256"); ps("SecretKeyFactory", "PBEWithHmacSHA384AndAES_256", - "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA384AndAES_256", - null, null); + "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA384AndAES_256"); ps("SecretKeyFactory", "PBEWithHmacSHA512AndAES_256", - "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA512AndAES_256", - null, null); + "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA512AndAES_256"); // PBKDF2 - ps("SecretKeyFactory", "PBKDF2WithHmacSHA1", + psA("SecretKeyFactory", "PBKDF2WithHmacSHA1", "com.sun.crypto.provider.PBKDF2Core$HmacSHA1", - pkcs5PBKDF2Aliases, null); + null); ps("SecretKeyFactory", "PBKDF2WithHmacSHA224", - "com.sun.crypto.provider.PBKDF2Core$HmacSHA224", - null, null); + "com.sun.crypto.provider.PBKDF2Core$HmacSHA224"); ps("SecretKeyFactory", "PBKDF2WithHmacSHA256", - "com.sun.crypto.provider.PBKDF2Core$HmacSHA256", - null, null); + "com.sun.crypto.provider.PBKDF2Core$HmacSHA256"); ps("SecretKeyFactory", "PBKDF2WithHmacSHA384", - "com.sun.crypto.provider.PBKDF2Core$HmacSHA384", - null, null); + "com.sun.crypto.provider.PBKDF2Core$HmacSHA384"); ps("SecretKeyFactory", "PBKDF2WithHmacSHA512", - "com.sun.crypto.provider.PBKDF2Core$HmacSHA512", - null, null); + "com.sun.crypto.provider.PBKDF2Core$HmacSHA512"); /* * MAC @@ -699,35 +594,28 @@ public final class SunJCE extends Provider { attrs.clear(); attrs.put("SupportedKeyFormats", "RAW"); ps("Mac", "HmacMD5", "com.sun.crypto.provider.HmacMD5", null, attrs); - ps("Mac", "HmacSHA1", "com.sun.crypto.provider.HmacSHA1", - macSHA1Aliases, attrs); - ps("Mac", "HmacSHA224", "com.sun.crypto.provider.HmacCore$HmacSHA224", - macSHA224Aliases, attrs); - ps("Mac", "HmacSHA256", "com.sun.crypto.provider.HmacCore$HmacSHA256", - macSHA256Aliases, attrs); - ps("Mac", "HmacSHA384", "com.sun.crypto.provider.HmacCore$HmacSHA384", - macSHA384Aliases, attrs); - ps("Mac", "HmacSHA512", "com.sun.crypto.provider.HmacCore$HmacSHA512", - macSHA512Aliases, attrs); - ps("Mac", "HmacSHA512/224", - "com.sun.crypto.provider.HmacCore$HmacSHA512_224", - macSHA512_224Aliases, attrs); - ps("Mac", "HmacSHA512/256", - "com.sun.crypto.provider.HmacCore$HmacSHA512_256", - macSHA512_256Aliases, attrs); - - ps("Mac", "HmacSHA3-224", - "com.sun.crypto.provider.HmacCore$HmacSHA3_224", - macSHA3_224Aliases, attrs); - ps("Mac", "HmacSHA3-256", - "com.sun.crypto.provider.HmacCore$HmacSHA3_256", - macSHA3_256Aliases, attrs); - ps("Mac", "HmacSHA3-384", - "com.sun.crypto.provider.HmacCore$HmacSHA3_384", - macSHA3_384Aliases, attrs); - ps("Mac", "HmacSHA3-512", - "com.sun.crypto.provider.HmacCore$HmacSHA3_512", - macSHA3_512Aliases, attrs); + psA("Mac", "HmacSHA1", "com.sun.crypto.provider.HmacSHA1", + attrs); + psA("Mac", "HmacSHA224", + "com.sun.crypto.provider.HmacCore$HmacSHA224", attrs); + psA("Mac", "HmacSHA256", + "com.sun.crypto.provider.HmacCore$HmacSHA256", attrs); + psA("Mac", "HmacSHA384", + "com.sun.crypto.provider.HmacCore$HmacSHA384", attrs); + psA("Mac", "HmacSHA512", + "com.sun.crypto.provider.HmacCore$HmacSHA512", attrs); + psA("Mac", "HmacSHA512/224", + "com.sun.crypto.provider.HmacCore$HmacSHA512_224", attrs); + psA("Mac", "HmacSHA512/256", + "com.sun.crypto.provider.HmacCore$HmacSHA512_256", attrs); + psA("Mac", "HmacSHA3-224", + "com.sun.crypto.provider.HmacCore$HmacSHA3_224", attrs); + psA("Mac", "HmacSHA3-256", + "com.sun.crypto.provider.HmacCore$HmacSHA3_256", attrs); + psA("Mac", "HmacSHA3-384", + "com.sun.crypto.provider.HmacCore$HmacSHA3_384", attrs); + psA("Mac", "HmacSHA3-512", + "com.sun.crypto.provider.HmacCore$HmacSHA3_512", attrs); ps("Mac", "HmacPBESHA1", "com.sun.crypto.provider.HmacPKCS12PBECore$HmacPKCS12PBE_SHA1", @@ -772,8 +660,7 @@ public final class SunJCE extends Provider { * KeyStore */ ps("KeyStore", "JCEKS", - "com.sun.crypto.provider.JceKeyStore", - null, null); + "com.sun.crypto.provider.JceKeyStore"); /* * SSL/TLS mechanisms @@ -784,24 +671,22 @@ public final class SunJCE extends Provider { * mechanisms, and it will cause calls to come here. */ ps("KeyGenerator", "SunTlsPrf", - "com.sun.crypto.provider.TlsPrfGenerator$V10", - null, null); + "com.sun.crypto.provider.TlsPrfGenerator$V10"); ps("KeyGenerator", "SunTls12Prf", - "com.sun.crypto.provider.TlsPrfGenerator$V12", - null, null); + "com.sun.crypto.provider.TlsPrfGenerator$V12"); ps("KeyGenerator", "SunTlsMasterSecret", "com.sun.crypto.provider.TlsMasterSecretGenerator", - createAliases("SunTls12MasterSecret", - "SunTlsExtendedMasterSecret"), null); + List.of("SunTls12MasterSecret", "SunTlsExtendedMasterSecret"), + null); ps("KeyGenerator", "SunTlsKeyMaterial", "com.sun.crypto.provider.TlsKeyMaterialGenerator", - createAliases("SunTls12KeyMaterial"), null); + List.of("SunTls12KeyMaterial"), null); ps("KeyGenerator", "SunTlsRsaPremasterSecret", "com.sun.crypto.provider.TlsRsaPremasterSecretGenerator", - createAliases("SunTls12RsaPremasterSecret"), null); + List.of("SunTls12RsaPremasterSecret"), null); } // Return the instance of this class or create one if needed. diff --git a/src/java.base/share/classes/java/security/PKCS12Attribute.java b/src/java.base/share/classes/java/security/PKCS12Attribute.java index b625bf0997d..6e5a375978f 100644 --- a/src/java.base/share/classes/java/security/PKCS12Attribute.java +++ b/src/java.base/share/classes/java/security/PKCS12Attribute.java @@ -76,7 +76,7 @@ public final class PKCS12Attribute implements KeyStore.Entry.Attribute { // Validate name ObjectIdentifier type; try { - type = new ObjectIdentifier(name); + type = ObjectIdentifier.of(name); } catch (IOException e) { throw new IllegalArgumentException("Incorrect format: name", e); } diff --git a/src/java.base/share/classes/java/security/cert/CertificateRevokedException.java b/src/java.base/share/classes/java/security/cert/CertificateRevokedException.java index 5ee459c30c7..9fa8be22f08 100644 --- a/src/java.base/share/classes/java/security/cert/CertificateRevokedException.java +++ b/src/java.base/share/classes/java/security/cert/CertificateRevokedException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2019, 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 @@ -246,7 +246,7 @@ public class CertificateRevokedException extends CertificateException { boolean critical = ois.readBoolean(); byte[] extVal = IOUtils.readExactlyNBytes(ois, ois.readInt()); Extension ext = sun.security.x509.Extension.newExtension - (new ObjectIdentifier(oid), critical, extVal); + (ObjectIdentifier.of(oid), critical, extVal); extensions.put(oid, ext); } } diff --git a/src/java.base/share/classes/java/security/cert/X509CertSelector.java b/src/java.base/share/classes/java/security/cert/X509CertSelector.java index 6314a5ae1ad..2db9cc255dd 100644 --- a/src/java.base/share/classes/java/security/cert/X509CertSelector.java +++ b/src/java.base/share/classes/java/security/cert/X509CertSelector.java @@ -31,11 +31,7 @@ import java.security.PublicKey; import java.util.*; import javax.security.auth.x500.X500Principal; -import sun.security.util.HexDumpEncoder; -import sun.security.util.Debug; -import sun.security.util.DerInputStream; -import sun.security.util.DerValue; -import sun.security.util.ObjectIdentifier; +import sun.security.util.*; import sun.security.x509.*; /** @@ -88,7 +84,7 @@ public class X509CertSelector implements CertSelector { private static final Debug debug = Debug.getInstance("certpath"); private static final ObjectIdentifier ANY_EXTENDED_KEY_USAGE = - ObjectIdentifier.of("2.5.29.37.0"); + ObjectIdentifier.of(KnownOIDs.anyExtendedKeyUsage); static { CertPathHelperImpl.initialize(); @@ -506,7 +502,7 @@ public class X509CertSelector implements CertSelector { if (oid == null) { subjectPublicKeyAlgID = null; } else { - subjectPublicKeyAlgID = new ObjectIdentifier(oid); + subjectPublicKeyAlgID = ObjectIdentifier.of(oid); } } @@ -622,7 +618,7 @@ public class X509CertSelector implements CertSelector { Collections.unmodifiableSet(new HashSet<>(keyPurposeSet)); keyPurposeOIDSet = new HashSet<>(); for (String s : this.keyPurposeSet) { - keyPurposeOIDSet.add(new ObjectIdentifier(s)); + keyPurposeOIDSet.add(ObjectIdentifier.of(s)); } } } @@ -1105,8 +1101,8 @@ public class X509CertSelector implements CertSelector { if (!(o instanceof String)) { throw new IOException("non String in certPolicySet"); } - polIdVector.add(new CertificatePolicyId(new ObjectIdentifier( - (String)o))); + polIdVector.add(new CertificatePolicyId + (ObjectIdentifier.of((String)o))); } // If everything went OK, make the changes policySet = tempSet; diff --git a/src/java.base/share/classes/sun/security/pkcs/ContentInfo.java b/src/java.base/share/classes/sun/security/pkcs/ContentInfo.java index 00abc8d2d0c..bc73d47ba69 100644 --- a/src/java.base/share/classes/sun/security/pkcs/ContentInfo.java +++ b/src/java.base/share/classes/sun/security/pkcs/ContentInfo.java @@ -39,35 +39,35 @@ public class ContentInfo { // pkcs7 pre-defined content types public static ObjectIdentifier PKCS7_OID = - ObjectIdentifier.of("1.2.840.113549.1.7"); + ObjectIdentifier.of(KnownOIDs.PKCS7); public static ObjectIdentifier DATA_OID = - ObjectIdentifier.of("1.2.840.113549.1.7.1"); + ObjectIdentifier.of(KnownOIDs.Data); public static ObjectIdentifier SIGNED_DATA_OID = - ObjectIdentifier.of("1.2.840.113549.1.7.2"); + ObjectIdentifier.of(KnownOIDs.SignedData); public static ObjectIdentifier ENVELOPED_DATA_OID = - ObjectIdentifier.of("1.2.840.113549.1.7.3"); + ObjectIdentifier.of(KnownOIDs.EnvelopedData); public static ObjectIdentifier SIGNED_AND_ENVELOPED_DATA_OID = - ObjectIdentifier.of("1.2.840.113549.1.7.4"); + ObjectIdentifier.of(KnownOIDs.SignedAndEnvelopedData); public static ObjectIdentifier DIGESTED_DATA_OID = - ObjectIdentifier.of("1.2.840.113549.1.7.5"); + ObjectIdentifier.of(KnownOIDs.DigestedData); public static ObjectIdentifier ENCRYPTED_DATA_OID = - ObjectIdentifier.of("1.2.840.113549.1.7.6"); + ObjectIdentifier.of(KnownOIDs.EncryptedData); // this is for backwards-compatibility with JDK 1.1.x public static ObjectIdentifier OLD_SIGNED_DATA_OID = - ObjectIdentifier.of("1.2.840.1113549.1.7.2"); + ObjectIdentifier.of(KnownOIDs.JDK_OLD_SignedData); public static ObjectIdentifier OLD_DATA_OID = - ObjectIdentifier.of("1.2.840.1113549.1.7.1"); + ObjectIdentifier.of(KnownOIDs.JDK_OLD_Data); // The ASN.1 systax for the Netscape Certificate Sequence data type is // defined at: // http://wp.netscape.com/eng/security/comm4-cert-download.html public static ObjectIdentifier NETSCAPE_CERT_SEQUENCE_OID = - ObjectIdentifier.of("2.16.840.1.113730.2.5"); + ObjectIdentifier.of(KnownOIDs.NETSCAPE_CertSequence); // timestamp token (id-ct-TSTInfo) from RFC 3161 public static ObjectIdentifier TIMESTAMP_TOKEN_INFO_OID = - ObjectIdentifier.of("1.2.840.113549.1.9.16.1.4"); + ObjectIdentifier.of(KnownOIDs.TimeStampTokenInfo); ObjectIdentifier contentType; DerValue content; // OPTIONAL diff --git a/src/java.base/share/classes/sun/security/pkcs/PKCS7.java b/src/java.base/share/classes/sun/security/pkcs/PKCS7.java index 2a217d4b4ee..f9179e7ae50 100644 --- a/src/java.base/share/classes/sun/security/pkcs/PKCS7.java +++ b/src/java.base/share/classes/sun/security/pkcs/PKCS7.java @@ -819,7 +819,7 @@ public class PKCS7 { unauthAttrs = new PKCS9Attributes(new PKCS9Attribute[]{ new PKCS9Attribute( - PKCS9Attribute.SIGNATURE_TIMESTAMP_TOKEN_STR, + PKCS9Attribute.SIGNATURE_TIMESTAMP_TOKEN_OID, tsToken)}); } diff --git a/src/java.base/share/classes/sun/security/pkcs/PKCS9Attribute.java b/src/java.base/share/classes/sun/security/pkcs/PKCS9Attribute.java index d66878182f5..b9ef2d6337f 100644 --- a/src/java.base/share/classes/sun/security/pkcs/PKCS9Attribute.java +++ b/src/java.base/share/classes/sun/security/pkcs/PKCS9Attribute.java @@ -32,13 +32,7 @@ import java.util.Locale; import java.util.Date; import java.util.HashMap; import sun.security.x509.CertificateExtensions; -import sun.security.util.Debug; -import sun.security.util.DerEncoder; -import sun.security.util.DerValue; -import sun.security.util.DerInputStream; -import sun.security.util.DerOutputStream; -import sun.security.util.ObjectIdentifier; -import sun.security.util.HexDumpEncoder; +import sun.security.util.*; /** * Class supporting any PKCS9 attributes. @@ -188,17 +182,11 @@ public class PKCS9Attribute implements DerEncoder { private static final Class BYTE_ARRAY_CLASS; - static { // static initializer for PKCS9_OIDS - for (int i = 1; i < PKCS9_OIDS.length - 2; i++) { - PKCS9_OIDS[i] = ObjectIdentifier.of("1.2.840.113549.1.9." + i); - } - // Initialize SigningCertificate and SignatureTimestampToken - // separately (because their values are out of sequence) - PKCS9_OIDS[PKCS9_OIDS.length - 2] = - ObjectIdentifier.of("1.2.840.113549.1.9.16.2.12"); - PKCS9_OIDS[PKCS9_OIDS.length - 1] = - ObjectIdentifier.of("1.2.840.113549.1.9.16.2.14"); - + static { + // set unused PKCS9_OIDS entries to null + // rest are initialized with public constants + PKCS9_OIDS[0] = PKCS9_OIDS[11] = PKCS9_OIDS[12] = PKCS9_OIDS[13] = + PKCS9_OIDS[15] = null; try { BYTE_ARRAY_CLASS = Class.forName("[B"); } catch (ClassNotFoundException e) { @@ -206,99 +194,37 @@ public class PKCS9Attribute implements DerEncoder { } } - // first element [0] not used - public static final ObjectIdentifier EMAIL_ADDRESS_OID = PKCS9_OIDS[1]; - public static final ObjectIdentifier UNSTRUCTURED_NAME_OID = PKCS9_OIDS[2]; - public static final ObjectIdentifier CONTENT_TYPE_OID = PKCS9_OIDS[3]; - public static final ObjectIdentifier MESSAGE_DIGEST_OID = PKCS9_OIDS[4]; - public static final ObjectIdentifier SIGNING_TIME_OID = PKCS9_OIDS[5]; - public static final ObjectIdentifier COUNTERSIGNATURE_OID = PKCS9_OIDS[6]; - public static final ObjectIdentifier CHALLENGE_PASSWORD_OID = PKCS9_OIDS[7]; - public static final ObjectIdentifier UNSTRUCTURED_ADDRESS_OID = PKCS9_OIDS[8]; - public static final ObjectIdentifier EXTENDED_CERTIFICATE_ATTRIBUTES_OID - = PKCS9_OIDS[9]; - public static final ObjectIdentifier ISSUER_SERIALNUMBER_OID = PKCS9_OIDS[10]; + public static final ObjectIdentifier EMAIL_ADDRESS_OID = PKCS9_OIDS[1] = + ObjectIdentifier.of(KnownOIDs.EmailAddress); + public static final ObjectIdentifier UNSTRUCTURED_NAME_OID = PKCS9_OIDS[2] = + ObjectIdentifier.of(KnownOIDs.UnstructuredName); + public static final ObjectIdentifier CONTENT_TYPE_OID = PKCS9_OIDS[3] = + ObjectIdentifier.of(KnownOIDs.ContentType); + public static final ObjectIdentifier MESSAGE_DIGEST_OID = PKCS9_OIDS[4] = + ObjectIdentifier.of(KnownOIDs.MessageDigest); + public static final ObjectIdentifier SIGNING_TIME_OID = PKCS9_OIDS[5] = + ObjectIdentifier.of(KnownOIDs.SigningTime); + public static final ObjectIdentifier COUNTERSIGNATURE_OID = PKCS9_OIDS[6] = + ObjectIdentifier.of(KnownOIDs.CounterSignature); + public static final ObjectIdentifier CHALLENGE_PASSWORD_OID = + PKCS9_OIDS[7] = ObjectIdentifier.of(KnownOIDs.ChallengePassword); + public static final ObjectIdentifier UNSTRUCTURED_ADDRESS_OID = + PKCS9_OIDS[8] = ObjectIdentifier.of(KnownOIDs.UnstructuredAddress); + public static final ObjectIdentifier EXTENDED_CERTIFICATE_ATTRIBUTES_OID = + PKCS9_OIDS[9] = + ObjectIdentifier.of(KnownOIDs.ExtendedCertificateAttributes); + public static final ObjectIdentifier ISSUER_SERIALNUMBER_OID = + PKCS9_OIDS[10] = + ObjectIdentifier.of(KnownOIDs.IssuerAndSerialNumber); // [11], [12] are RSA DSI proprietary // [13] ==> signingDescription, S/MIME, not used anymore - public static final ObjectIdentifier EXTENSION_REQUEST_OID = PKCS9_OIDS[14]; - public static final ObjectIdentifier SMIME_CAPABILITY_OID = PKCS9_OIDS[15]; - public static final ObjectIdentifier SIGNING_CERTIFICATE_OID = PKCS9_OIDS[16]; + public static final ObjectIdentifier EXTENSION_REQUEST_OID = + PKCS9_OIDS[14] = ObjectIdentifier.of(KnownOIDs.ExtensionRequest); + public static final ObjectIdentifier SIGNING_CERTIFICATE_OID = + PKCS9_OIDS[16] = ObjectIdentifier.of(KnownOIDs.SigningCertificate); public static final ObjectIdentifier SIGNATURE_TIMESTAMP_TOKEN_OID = - PKCS9_OIDS[17]; - public static final String EMAIL_ADDRESS_STR = "EmailAddress"; - public static final String UNSTRUCTURED_NAME_STR = "UnstructuredName"; - public static final String CONTENT_TYPE_STR = "ContentType"; - public static final String MESSAGE_DIGEST_STR = "MessageDigest"; - public static final String SIGNING_TIME_STR = "SigningTime"; - public static final String COUNTERSIGNATURE_STR = "Countersignature"; - public static final String CHALLENGE_PASSWORD_STR = "ChallengePassword"; - public static final String UNSTRUCTURED_ADDRESS_STR = "UnstructuredAddress"; - public static final String EXTENDED_CERTIFICATE_ATTRIBUTES_STR = - "ExtendedCertificateAttributes"; - public static final String ISSUER_SERIALNUMBER_STR = "IssuerAndSerialNumber"; - // [11], [12] are RSA DSI proprietary - private static final String RSA_PROPRIETARY_STR = "RSAProprietary"; - // [13] ==> signingDescription, S/MIME, not used anymore - private static final String SMIME_SIGNING_DESC_STR = "SMIMESigningDesc"; - public static final String EXTENSION_REQUEST_STR = "ExtensionRequest"; - public static final String SMIME_CAPABILITY_STR = "SMIMECapability"; - public static final String SIGNING_CERTIFICATE_STR = "SigningCertificate"; - public static final String SIGNATURE_TIMESTAMP_TOKEN_STR = - "SignatureTimestampToken"; - - /** - * HashMap mapping names and variant names of supported - * attributes to their OIDs. This table contains all name forms - * that occur in PKCS9, in lower case. - */ - private static final HashMap NAME_OID_TABLE = - new HashMap(17); - - static { // static initializer for PCKS9_NAMES - NAME_OID_TABLE.put("emailaddress", PKCS9_OIDS[1]); - NAME_OID_TABLE.put("unstructuredname", PKCS9_OIDS[2]); - NAME_OID_TABLE.put("contenttype", PKCS9_OIDS[3]); - NAME_OID_TABLE.put("messagedigest", PKCS9_OIDS[4]); - NAME_OID_TABLE.put("signingtime", PKCS9_OIDS[5]); - NAME_OID_TABLE.put("countersignature", PKCS9_OIDS[6]); - NAME_OID_TABLE.put("challengepassword", PKCS9_OIDS[7]); - NAME_OID_TABLE.put("unstructuredaddress", PKCS9_OIDS[8]); - NAME_OID_TABLE.put("extendedcertificateattributes", PKCS9_OIDS[9]); - NAME_OID_TABLE.put("issuerandserialnumber", PKCS9_OIDS[10]); - NAME_OID_TABLE.put("rsaproprietary", PKCS9_OIDS[11]); - NAME_OID_TABLE.put("rsaproprietary", PKCS9_OIDS[12]); - NAME_OID_TABLE.put("signingdescription", PKCS9_OIDS[13]); - NAME_OID_TABLE.put("extensionrequest", PKCS9_OIDS[14]); - NAME_OID_TABLE.put("smimecapability", PKCS9_OIDS[15]); - NAME_OID_TABLE.put("signingcertificate", PKCS9_OIDS[16]); - NAME_OID_TABLE.put("signaturetimestamptoken", PKCS9_OIDS[17]); - }; - - /** - * HashMap mapping attribute OIDs defined in PKCS9 to the - * corresponding attribute value type. - */ - private static final HashMap OID_NAME_TABLE = - new HashMap(17); - static { - OID_NAME_TABLE.put(PKCS9_OIDS[1], EMAIL_ADDRESS_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[2], UNSTRUCTURED_NAME_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[3], CONTENT_TYPE_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[4], MESSAGE_DIGEST_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[5], SIGNING_TIME_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[6], COUNTERSIGNATURE_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[7], CHALLENGE_PASSWORD_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[8], UNSTRUCTURED_ADDRESS_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[9], EXTENDED_CERTIFICATE_ATTRIBUTES_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[10], ISSUER_SERIALNUMBER_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[11], RSA_PROPRIETARY_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[12], RSA_PROPRIETARY_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[13], SMIME_SIGNING_DESC_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[14], EXTENSION_REQUEST_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[15], SMIME_CAPABILITY_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[16], SIGNING_CERTIFICATE_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[17], SIGNATURE_TIMESTAMP_TOKEN_STR); - } + PKCS9_OIDS[17] = + ObjectIdentifier.of(KnownOIDs.SignatureTimestampToken); /** * Acceptable ASN.1 tags for DER encodings of values of PKCS9 @@ -427,34 +353,6 @@ public class PKCS9Attribute implements DerEncoder { init(oid, value); } - /** - * Construct an attribute object from the attribute's name and - * value. If the attribute is single-valued, provide only one - * value. If the attribute is multi-valued, provide an array - * containing all the values. - * Arrays of length zero are accepted, though probably useless. - * - *

The - * table gives the class that value - * must have for a given attribute. Reasonable variants of these - * attributes are accepted; in particular, case does not matter. - * - * @exception IllegalArgumentException - * if the name is not recognized or the - * value has the wrong type. - */ - public PKCS9Attribute(String name, Object value) - throws IllegalArgumentException { - ObjectIdentifier oid = getOID(name); - - if (oid == null) - throw new IllegalArgumentException( - "Unrecognized attribute name " + name + - " constructing PKCS9Attribute."); - - init(oid, value); - } - private void init(ObjectIdentifier oid, Object value) throws IllegalArgumentException { @@ -766,9 +664,9 @@ public class PKCS9Attribute implements DerEncoder { * Return the name of this attribute. */ public String getName() { - return index == -1 ? - oid.toString() : - OID_NAME_TABLE.get(PKCS9_OIDS[index]); + String n = oid.toString(); + KnownOIDs os = KnownOIDs.findMatch(n); + return (os == null? n : os.stdName()); } /** @@ -776,7 +674,12 @@ public class PKCS9Attribute implements DerEncoder { * the name. */ public static ObjectIdentifier getOID(String name) { - return NAME_OID_TABLE.get(name.toLowerCase(Locale.ENGLISH)); + KnownOIDs o = KnownOIDs.findMatch(name); + if (o != null) { + return ObjectIdentifier.of(o); + } else { + return null; + } } /** @@ -784,7 +687,7 @@ public class PKCS9Attribute implements DerEncoder { * the oid. */ public static String getName(ObjectIdentifier oid) { - return OID_NAME_TABLE.get(oid); + return KnownOIDs.findMatch(oid.toString()).stdName(); } /** @@ -799,7 +702,7 @@ public class PKCS9Attribute implements DerEncoder { if (index == -1) { sb.append(oid.toString()); } else { - sb.append(OID_NAME_TABLE.get(PKCS9_OIDS[index])); + sb.append(getName(oid)); } sb.append(": "); diff --git a/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java b/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java index ae9b5a7a217..1a8c0095fa7 100644 --- a/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java +++ b/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java @@ -66,17 +66,11 @@ import javax.security.auth.DestroyFailedException; import javax.security.auth.x500.X500Principal; import sun.security.tools.KeyStoreUtil; -import sun.security.util.Debug; -import sun.security.util.DerInputStream; -import sun.security.util.DerOutputStream; -import sun.security.util.DerValue; -import sun.security.util.ObjectIdentifier; +import sun.security.util.*; import sun.security.pkcs.ContentInfo; -import sun.security.util.SecurityProperties; import sun.security.x509.AlgorithmId; import sun.security.pkcs.EncryptedPrivateKeyInfo; import sun.security.provider.JavaKeyStore.JKS; -import sun.security.util.KeyStoreDelegator; import sun.security.x509.AuthorityKeyIdentifierExtension; @@ -148,29 +142,29 @@ public final class PKCS12KeyStore extends KeyStoreSpi { private static final int MAX_ITERATION_COUNT = 5000000; private static final int SALT_LEN = 20; - // friendlyName, localKeyId, trustedKeyUsage - private static final String[] CORE_ATTRIBUTES = { - "1.2.840.113549.1.9.20", - "1.2.840.113549.1.9.21", - "2.16.840.1.113894.746875.1.1" + private static final KnownOIDs[] CORE_ATTRIBUTES = { + KnownOIDs.FriendlyName, + KnownOIDs.LocalKeyID, + KnownOIDs.ORACLE_TrustedKeyUsage }; private static final Debug debug = Debug.getInstance("pkcs12"); private static final ObjectIdentifier PKCS8ShroudedKeyBag_OID = - ObjectIdentifier.of("1.2.840.113549.1.12.10.1.2"); + ObjectIdentifier.of(KnownOIDs.PKCS8ShroudedKeyBag); private static final ObjectIdentifier CertBag_OID = - ObjectIdentifier.of("1.2.840.113549.1.12.10.1.3"); + ObjectIdentifier.of(KnownOIDs.CertBag); private static final ObjectIdentifier SecretBag_OID = - ObjectIdentifier.of("1.2.840.113549.1.12.10.1.5"); + ObjectIdentifier.of(KnownOIDs.SecretBag); + private static final ObjectIdentifier PKCS9FriendlyName_OID = - ObjectIdentifier.of("1.2.840.113549.1.9.20"); + ObjectIdentifier.of(KnownOIDs.FriendlyName); private static final ObjectIdentifier PKCS9LocalKeyId_OID = - ObjectIdentifier.of("1.2.840.113549.1.9.21"); + ObjectIdentifier.of(KnownOIDs.LocalKeyID); private static final ObjectIdentifier PKCS9CertType_OID = - ObjectIdentifier.of("1.2.840.113549.1.9.22.1"); + ObjectIdentifier.of(KnownOIDs.CertTypeX509); private static final ObjectIdentifier pbes2_OID = - ObjectIdentifier.of("1.2.840.113549.1.5.13"); + ObjectIdentifier.of(KnownOIDs.PBES2); /* * Temporary Oracle OID @@ -179,11 +173,10 @@ public final class PKCS12KeyStore extends KeyStoreSpi { * oracle(113894) jdk(746875) crypto(1) id-at-trustedKeyUsage(1)} */ private static final ObjectIdentifier TrustedKeyUsage_OID = - ObjectIdentifier.of("2.16.840.1.113894.746875.1.1"); + ObjectIdentifier.of(KnownOIDs.ORACLE_TrustedKeyUsage); private static final ObjectIdentifier[] AnyUsage = new ObjectIdentifier[] { - // AnyExtendedKeyUsage - ObjectIdentifier.of("2.5.29.37.0") + ObjectIdentifier.of(KnownOIDs.anyExtendedKeyUsage) }; private int counter = 0; @@ -1643,9 +1636,9 @@ public final class PKCS12KeyStore extends KeyStoreSpi { for (KeyStore.Entry.Attribute attribute : attributes) { String attributeName = attribute.getName(); // skip friendlyName, localKeyId and trustedKeyUsage - if (CORE_ATTRIBUTES[0].equals(attributeName) || - CORE_ATTRIBUTES[1].equals(attributeName) || - CORE_ATTRIBUTES[2].equals(attributeName)) { + if (CORE_ATTRIBUTES[0].value().equals(attributeName) || + CORE_ATTRIBUTES[1].value().equals(attributeName) || + CORE_ATTRIBUTES[2].value().equals(attributeName)) { continue; } attrs.write(((PKCS12Attribute) attribute).getEncoded()); diff --git a/src/java.base/share/classes/sun/security/provider/KeyProtector.java b/src/java.base/share/classes/sun/security/provider/KeyProtector.java index 1a7cf122ea8..62057bcb4ec 100644 --- a/src/java.base/share/classes/sun/security/provider/KeyProtector.java +++ b/src/java.base/share/classes/sun/security/provider/KeyProtector.java @@ -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 @@ -38,6 +38,7 @@ import sun.security.pkcs.PKCS8Key; import sun.security.pkcs.EncryptedPrivateKeyInfo; import sun.security.x509.AlgorithmId; import sun.security.util.ObjectIdentifier; +import sun.security.util.KnownOIDs; import sun.security.util.DerValue; /** @@ -105,9 +106,6 @@ final class KeyProtector { private static final String DIGEST_ALG = "SHA"; private static final int DIGEST_LEN = 20; - // defined by JavaSoft - private static final String KEY_PROTECTOR_OID = "1.3.6.1.4.1.42.2.17.1.1"; - // The password used for protecting/recovering keys passed through this // key protector. We store it as a byte array, so that we can digest it. private byte[] passwdBytes; @@ -213,7 +211,8 @@ final class KeyProtector { // EncryptedPrivateKeyInfo, and returns its encoding AlgorithmId encrAlg; try { - encrAlg = new AlgorithmId(new ObjectIdentifier(KEY_PROTECTOR_OID)); + encrAlg = new AlgorithmId(ObjectIdentifier.of + (KnownOIDs.JAVASOFT_JDKKeyProtector)); return new EncryptedPrivateKeyInfo(encrAlg,encrKey).getEncoded(); } catch (IOException ioe) { throw new KeyStoreException(ioe.getMessage()); @@ -235,7 +234,8 @@ final class KeyProtector { // do we support the algorithm? AlgorithmId encrAlg = encrInfo.getAlgorithm(); - if (!(encrAlg.getOID().toString().equals(KEY_PROTECTOR_OID))) { + if (!(encrAlg.getOID().toString().equals + (KnownOIDs.JAVASOFT_JDKKeyProtector.value()))) { throw new UnrecoverableKeyException("Unsupported key protection " + "algorithm"); } diff --git a/src/java.base/share/classes/sun/security/provider/SunEntries.java b/src/java.base/share/classes/sun/security/provider/SunEntries.java index 4f6639349a6..79007f4d8ef 100644 --- a/src/java.base/share/classes/sun/security/provider/SunEntries.java +++ b/src/java.base/share/classes/sun/security/provider/SunEntries.java @@ -32,6 +32,8 @@ import java.security.*; import jdk.internal.util.StaticProperty; import sun.security.action.GetPropertyAction; +import sun.security.util.SecurityProviderConstants; +import static sun.security.util.SecurityProviderConstants.getAliases; /** * Defines the entries of the SUN provider. @@ -80,18 +82,6 @@ public final class SunEntries { // the default algo used by SecureRandom class for new SecureRandom() calls public static final String DEF_SECURE_RANDOM_ALGO; - // create an aliases List from the specified aliases - public static List createAliases(String ... aliases) { - return Arrays.asList(aliases); - } - - // create an aliases List from the specified oid followed by other aliases - public static List createAliasesWithOid(String ... oids) { - String[] result = Arrays.copyOf(oids, oids.length + 1); - result[result.length - 1] = "OID." + oids[0]; - return Arrays.asList(result); - } - SunEntries(Provider p) { services = new LinkedHashSet<>(50, 0.9f); @@ -106,22 +96,20 @@ public final class SunEntries { attrs.put("ThreadSafe", "true"); if (NativePRNG.isAvailable()) { add(p, "SecureRandom", "NativePRNG", - "sun.security.provider.NativePRNG", - null, attrs); + "sun.security.provider.NativePRNG", attrs); } if (NativePRNG.Blocking.isAvailable()) { add(p, "SecureRandom", "NativePRNGBlocking", - "sun.security.provider.NativePRNG$Blocking", null, attrs); + "sun.security.provider.NativePRNG$Blocking", attrs); } if (NativePRNG.NonBlocking.isAvailable()) { add(p, "SecureRandom", "NativePRNGNonBlocking", - "sun.security.provider.NativePRNG$NonBlocking", null, attrs); + "sun.security.provider.NativePRNG$NonBlocking", attrs); } attrs.put("ImplementedIn", "Software"); - add(p, "SecureRandom", "DRBG", "sun.security.provider.DRBG", - null, attrs); + add(p, "SecureRandom", "DRBG", "sun.security.provider.DRBG", attrs); add(p, "SecureRandom", "SHA1PRNG", - "sun.security.provider.SecureRandom", null, attrs); + "sun.security.provider.SecureRandom", attrs); /* * Signature engines @@ -134,37 +122,28 @@ public final class SunEntries { attrs.put("KeySize", "1024"); // for NONE and SHA1 DSA signatures - add(p, "Signature", "SHA1withDSA", - "sun.security.provider.DSA$SHA1withDSA", - createAliasesWithOid("1.2.840.10040.4.3", "DSA", "DSS", - "SHA/DSA", "SHA-1/DSA", "SHA1/DSA", "SHAwithDSA", - "DSAWithSHA1", "1.3.14.3.2.13", "1.3.14.3.2.27"), attrs); - add(p, "Signature", "NONEwithDSA", "sun.security.provider.DSA$RawDSA", - createAliases("RawDSA"), attrs); + addWithAlias(p, "Signature", "SHA1withDSA", + "sun.security.provider.DSA$SHA1withDSA", attrs); + addWithAlias(p, "Signature", "NONEwithDSA", + "sun.security.provider.DSA$RawDSA", attrs); attrs.put("KeySize", "2048"); // for SHA224 and SHA256 DSA signatures - add(p, "Signature", "SHA224withDSA", - "sun.security.provider.DSA$SHA224withDSA", - createAliasesWithOid("2.16.840.1.101.3.4.3.1"), attrs); - add(p, "Signature", "SHA256withDSA", - "sun.security.provider.DSA$SHA256withDSA", - createAliasesWithOid("2.16.840.1.101.3.4.3.2"), attrs); + addWithAlias(p, "Signature", "SHA224withDSA", + "sun.security.provider.DSA$SHA224withDSA", attrs); + addWithAlias(p, "Signature", "SHA256withDSA", + "sun.security.provider.DSA$SHA256withDSA", attrs); attrs.remove("KeySize"); add(p, "Signature", "SHA1withDSAinP1363Format", - "sun.security.provider.DSA$SHA1withDSAinP1363Format", - null, null); + "sun.security.provider.DSA$SHA1withDSAinP1363Format"); add(p, "Signature", "NONEwithDSAinP1363Format", - "sun.security.provider.DSA$RawDSAinP1363Format", - null, null); + "sun.security.provider.DSA$RawDSAinP1363Format"); add(p, "Signature", "SHA224withDSAinP1363Format", - "sun.security.provider.DSA$SHA224withDSAinP1363Format", - null, null); + "sun.security.provider.DSA$SHA224withDSAinP1363Format"); add(p, "Signature", "SHA256withDSAinP1363Format", - "sun.security.provider.DSA$SHA256withDSAinP1363Format", - null, null); + "sun.security.provider.DSA$SHA256withDSAinP1363Format"); /* * Key Pair Generator engines @@ -173,85 +152,75 @@ public final class SunEntries { attrs.put("ImplementedIn", "Software"); attrs.put("KeySize", "2048"); // for DSA KPG and APG only - String dsaOid = "1.2.840.10040.4.1"; - List dsaAliases = createAliasesWithOid(dsaOid, "1.3.14.3.2.12"); String dsaKPGImplClass = "sun.security.provider.DSAKeyPairGenerator$"; dsaKPGImplClass += (useLegacyDSA? "Legacy" : "Current"); - add(p, "KeyPairGenerator", "DSA", dsaKPGImplClass, dsaAliases, attrs); + addWithAlias(p, "KeyPairGenerator", "DSA", dsaKPGImplClass, attrs); /* * Algorithm Parameter Generator engines */ - add(p, "AlgorithmParameterGenerator", "DSA", - "sun.security.provider.DSAParameterGenerator", dsaAliases, - attrs); + addWithAlias(p, "AlgorithmParameterGenerator", "DSA", + "sun.security.provider.DSAParameterGenerator", attrs); attrs.remove("KeySize"); /* * Algorithm Parameter engines */ - add(p, "AlgorithmParameters", "DSA", - "sun.security.provider.DSAParameters", dsaAliases, attrs); + addWithAlias(p, "AlgorithmParameters", "DSA", + "sun.security.provider.DSAParameters", attrs); /* * Key factories */ - add(p, "KeyFactory", "DSA", "sun.security.provider.DSAKeyFactory", - dsaAliases, attrs); + addWithAlias(p, "KeyFactory", "DSA", + "sun.security.provider.DSAKeyFactory", attrs); /* * Digest engines */ - add(p, "MessageDigest", "MD2", "sun.security.provider.MD2", null, attrs); - add(p, "MessageDigest", "MD5", "sun.security.provider.MD5", null, attrs); - add(p, "MessageDigest", "SHA", "sun.security.provider.SHA", - createAliasesWithOid("1.3.14.3.2.26", "SHA-1", "SHA1"), attrs); + add(p, "MessageDigest", "MD2", "sun.security.provider.MD2", attrs); + add(p, "MessageDigest", "MD5", "sun.security.provider.MD5", attrs); + addWithAlias(p, "MessageDigest", "SHA-1", "sun.security.provider.SHA", + attrs); - String sha2BaseOid = "2.16.840.1.101.3.4.2"; - add(p, "MessageDigest", "SHA-224", "sun.security.provider.SHA2$SHA224", - createAliasesWithOid(sha2BaseOid + ".4"), attrs); - add(p, "MessageDigest", "SHA-256", "sun.security.provider.SHA2$SHA256", - createAliasesWithOid(sha2BaseOid + ".1"), attrs); - add(p, "MessageDigest", "SHA-384", "sun.security.provider.SHA5$SHA384", - createAliasesWithOid(sha2BaseOid + ".2"), attrs); - add(p, "MessageDigest", "SHA-512", "sun.security.provider.SHA5$SHA512", - createAliasesWithOid(sha2BaseOid + ".3"), attrs); - add(p, "MessageDigest", "SHA-512/224", - "sun.security.provider.SHA5$SHA512_224", - createAliasesWithOid(sha2BaseOid + ".5"), attrs); - add(p, "MessageDigest", "SHA-512/256", - "sun.security.provider.SHA5$SHA512_256", - createAliasesWithOid(sha2BaseOid + ".6"), attrs); - add(p, "MessageDigest", "SHA3-224", "sun.security.provider.SHA3$SHA224", - createAliasesWithOid(sha2BaseOid + ".7"), attrs); - add(p, "MessageDigest", "SHA3-256", "sun.security.provider.SHA3$SHA256", - createAliasesWithOid(sha2BaseOid + ".8"), attrs); - add(p, "MessageDigest", "SHA3-384", "sun.security.provider.SHA3$SHA384", - createAliasesWithOid(sha2BaseOid + ".9"), attrs); - add(p, "MessageDigest", "SHA3-512", "sun.security.provider.SHA3$SHA512", - createAliasesWithOid(sha2BaseOid + ".10"), attrs); + addWithAlias(p, "MessageDigest", "SHA-224", + "sun.security.provider.SHA2$SHA224", attrs); + addWithAlias(p, "MessageDigest", "SHA-256", + "sun.security.provider.SHA2$SHA256", attrs); + addWithAlias(p, "MessageDigest", "SHA-384", + "sun.security.provider.SHA5$SHA384", attrs); + addWithAlias(p, "MessageDigest", "SHA-512", + "sun.security.provider.SHA5$SHA512", attrs); + addWithAlias(p, "MessageDigest", "SHA-512/224", + "sun.security.provider.SHA5$SHA512_224", attrs); + addWithAlias(p, "MessageDigest", "SHA-512/256", + "sun.security.provider.SHA5$SHA512_256", attrs); + addWithAlias(p, "MessageDigest", "SHA3-224", + "sun.security.provider.SHA3$SHA224", attrs); + addWithAlias(p, "MessageDigest", "SHA3-256", + "sun.security.provider.SHA3$SHA256", attrs); + addWithAlias(p, "MessageDigest", "SHA3-384", + "sun.security.provider.SHA3$SHA384", attrs); + addWithAlias(p, "MessageDigest", "SHA3-512", + "sun.security.provider.SHA3$SHA512", attrs); /* * Certificates */ - add(p, "CertificateFactory", "X.509", - "sun.security.provider.X509Factory", - createAliases("X509"), attrs); + addWithAlias(p, "CertificateFactory", "X.509", + "sun.security.provider.X509Factory", attrs); /* * KeyStore */ add(p, "KeyStore", "PKCS12", - "sun.security.pkcs12.PKCS12KeyStore$DualFormatPKCS12", - null, null); + "sun.security.pkcs12.PKCS12KeyStore$DualFormatPKCS12"); add(p, "KeyStore", "JKS", - "sun.security.provider.JavaKeyStore$DualFormatJKS", - null, attrs); + "sun.security.provider.JavaKeyStore$DualFormatJKS", attrs); add(p, "KeyStore", "CaseExactJKS", - "sun.security.provider.JavaKeyStore$CaseExactJKS", - null, attrs); + "sun.security.provider.JavaKeyStore$CaseExactJKS", attrs); add(p, "KeyStore", "DKS", "sun.security.provider.DomainKeyStore$DKS", - null, attrs); + attrs); /* @@ -259,22 +228,21 @@ public final class SunEntries { */ add(p, "CertStore", "Collection", "sun.security.provider.certpath.CollectionCertStore", - null, attrs); + attrs); add(p, "CertStore", "com.sun.security.IndexedCollection", "sun.security.provider.certpath.IndexedCollectionCertStore", - null, attrs); + attrs); /* * Policy */ - add(p, "Policy", "JavaPolicy", "sun.security.provider.PolicySpiFile", - null, null); + add(p, "Policy", "JavaPolicy", "sun.security.provider.PolicySpiFile"); /* * Configuration */ add(p, "Configuration", "JavaLoginConfig", - "sun.security.provider.ConfigFile$Spi", null, null); + "sun.security.provider.ConfigFile$Spi"); /* * CertPathBuilder and CertPathValidator @@ -285,19 +253,29 @@ public final class SunEntries { add(p, "CertPathBuilder", "PKIX", "sun.security.provider.certpath.SunCertPathBuilder", - null, attrs); + attrs); add(p, "CertPathValidator", "PKIX", "sun.security.provider.certpath.PKIXCertPathValidator", - null, attrs); + attrs); } Iterator iterator() { return services.iterator(); } + private void add(Provider p, String type, String algo, String cn) { + services.add(new Provider.Service(p, type, algo, cn, null, null)); + } + private void add(Provider p, String type, String algo, String cn, - List aliases, HashMap attrs) { - services.add(new Provider.Service(p, type, algo, cn, aliases, attrs)); + HashMap attrs) { + services.add(new Provider.Service(p, type, algo, cn, null, attrs)); + } + + private void addWithAlias(Provider p, String type, String algo, String cn, + HashMap attrs) { + services.add(new Provider.Service(p, type, algo, cn, + getAliases(algo), attrs)); } private LinkedHashSet services; diff --git a/src/java.base/share/classes/sun/security/provider/certpath/OCSPResponse.java b/src/java.base/share/classes/sun/security/provider/certpath/OCSPResponse.java index 9747835f870..644c61b796a 100644 --- a/src/java.base/share/classes/sun/security/provider/certpath/OCSPResponse.java +++ b/src/java.base/share/classes/sun/security/provider/certpath/OCSPResponse.java @@ -135,7 +135,7 @@ public final class OCSPResponse { private static final Debug debug = Debug.getInstance("certpath"); private static final boolean dump = debug != null && Debug.isOn("ocsp"); private static final ObjectIdentifier OCSP_BASIC_RESPONSE_OID = - ObjectIdentifier.of("1.3.6.1.5.5.7.48.1.1"); + ObjectIdentifier.of(KnownOIDs.OCSPBasicResponse); private static final int CERT_STATUS_GOOD = 0; private static final int CERT_STATUS_REVOKED = 1; private static final int CERT_STATUS_UNKNOWN = 2; @@ -144,9 +144,6 @@ public final class OCSPResponse { private static final int NAME_TAG = 1; private static final int KEY_TAG = 2; - // Object identifier for the OCSPSigning key purpose - private static final String KP_OCSP_SIGNING_OID = "1.3.6.1.5.5.7.3.9"; - // Default maximum clock skew in milliseconds (15 minutes) // allowed when checking validity of OCSP responses private static final int DEFAULT_MAX_CLOCK_SKEW = 900000; @@ -493,7 +490,7 @@ public final class OCSPResponse { try { List keyPurposes = signerCert.getExtendedKeyUsage(); if (keyPurposes == null || - !keyPurposes.contains(KP_OCSP_SIGNING_OID)) { + !keyPurposes.contains(KnownOIDs.OCSPSigning.value())) { throw new CertPathValidatorException( "Responder's certificate not valid for signing " + "OCSP responses"); diff --git a/src/java.base/share/classes/sun/security/provider/certpath/RevocationChecker.java b/src/java.base/share/classes/sun/security/provider/certpath/RevocationChecker.java index 68c5d0573ba..e4d79b0897e 100644 --- a/src/java.base/share/classes/sun/security/provider/certpath/RevocationChecker.java +++ b/src/java.base/share/classes/sun/security/provider/certpath/RevocationChecker.java @@ -46,6 +46,7 @@ import static sun.security.provider.certpath.PKIX.*; import sun.security.x509.*; import static sun.security.x509.PKIXExtensions.*; import sun.security.util.Debug; +import sun.security.util.KnownOIDs; class RevocationChecker extends PKIXRevocationChecker { @@ -722,7 +723,7 @@ class RevocationChecker extends PKIXRevocationChecker { // verify the response byte[] nonce = null; for (Extension ext : ocspExtensions) { - if (ext.getId().equals("1.3.6.1.5.5.7.48.1.2")) { + if (ext.getId().equals(KnownOIDs.OCSPNonceExt.value())) { nonce = ext.getValue(); } } diff --git a/src/java.base/share/classes/sun/security/rsa/PSSParameters.java b/src/java.base/share/classes/sun/security/rsa/PSSParameters.java index 25625a89f59..a4bdd4b5dca 100644 --- a/src/java.base/share/classes/sun/security/rsa/PSSParameters.java +++ b/src/java.base/share/classes/sun/security/rsa/PSSParameters.java @@ -99,7 +99,7 @@ public final class PSSParameters extends AlgorithmParametersSpi { } else if (d.isContextSpecific((byte) 0x01)) { // mgf algid AlgorithmId val = AlgorithmId.parse(d.data.getDerValue()); - if (!val.getOID().equals(AlgorithmId.mgf1_oid)) { + if (!val.getOID().equals(AlgorithmId.MGF1_oid)) { throw new IOException("Only MGF1 mgf is supported"); } AlgorithmId params = AlgorithmId.parse( @@ -242,7 +242,7 @@ public final class PSSParameters extends AlgorithmParametersSpi { if (!mgfDigestId.getOID().equals(AlgorithmId.SHA_oid)) { tmp2 = new DerOutputStream(); - tmp2.putOID(AlgorithmId.mgf1_oid); + tmp2.putOID(AlgorithmId.MGF1_oid); mgfDigestId.encode(tmp2); tmp3 = new DerOutputStream(); tmp3.write(DerValue.tag_Sequence, tmp2); diff --git a/src/java.base/share/classes/sun/security/rsa/SunRsaSignEntries.java b/src/java.base/share/classes/sun/security/rsa/SunRsaSignEntries.java index a5cab587d28..f3edf4f25e1 100644 --- a/src/java.base/share/classes/sun/security/rsa/SunRsaSignEntries.java +++ b/src/java.base/share/classes/sun/security/rsa/SunRsaSignEntries.java @@ -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 @@ -27,7 +27,7 @@ package sun.security.rsa; import java.util.*; import java.security.Provider; -import static sun.security.provider.SunEntries.createAliasesWithOid; +import static sun.security.util.SecurityProviderConstants.getAliases; /** * Defines the entries of the SunRsaSign provider. @@ -38,7 +38,14 @@ public final class SunRsaSignEntries { private void add(Provider p, String type, String algo, String cn, List aliases, HashMap attrs) { - services.add(new Provider.Service(p, type, algo, cn, aliases, attrs)); + services.add(new Provider.Service(p, type, algo, cn, + aliases, attrs)); + } + + private void addA(Provider p, String type, String algo, String cn, + HashMap attrs) { + services.add(new Provider.Service(p, type, algo, cn, + getAliases(algo), attrs)); } // extend LinkedHashSet for consistency with SunEntries @@ -47,13 +54,6 @@ public final class SunRsaSignEntries { services = new LinkedHashSet<>(20, 0.9f); // start populating content using the specified provider - - // common oids - String rsaOid = "1.2.840.113549.1.1"; - List rsaAliases = createAliasesWithOid(rsaOid); - List rsapssAliases = createAliasesWithOid(rsaOid + ".10"); - String sha1withRSAOid2 = "1.3.14.3.2.29"; - // common attribute map HashMap attrs = new HashMap<>(3); attrs.put("SupportedKeyClasses", @@ -62,50 +62,37 @@ public final class SunRsaSignEntries { add(p, "KeyFactory", "RSA", "sun.security.rsa.RSAKeyFactory$Legacy", - rsaAliases, null); + getAliases("PKCS1"), null); add(p, "KeyPairGenerator", "RSA", "sun.security.rsa.RSAKeyPairGenerator$Legacy", - rsaAliases, null); - add(p, "Signature", "MD2withRSA", - "sun.security.rsa.RSASignature$MD2withRSA", - createAliasesWithOid(rsaOid + ".2"), attrs); - add(p, "Signature", "MD5withRSA", - "sun.security.rsa.RSASignature$MD5withRSA", - createAliasesWithOid(rsaOid + ".4"), attrs); - add(p, "Signature", "SHA1withRSA", - "sun.security.rsa.RSASignature$SHA1withRSA", - createAliasesWithOid(rsaOid + ".5", sha1withRSAOid2), attrs); - add(p, "Signature", "SHA224withRSA", - "sun.security.rsa.RSASignature$SHA224withRSA", - createAliasesWithOid(rsaOid + ".14"), attrs); - add(p, "Signature", "SHA256withRSA", - "sun.security.rsa.RSASignature$SHA256withRSA", - createAliasesWithOid(rsaOid + ".11"), attrs); - add(p, "Signature", "SHA384withRSA", - "sun.security.rsa.RSASignature$SHA384withRSA", - createAliasesWithOid(rsaOid + ".12"), attrs); - add(p, "Signature", "SHA512withRSA", - "sun.security.rsa.RSASignature$SHA512withRSA", - createAliasesWithOid(rsaOid + ".13"), attrs); - add(p, "Signature", "SHA512/224withRSA", - "sun.security.rsa.RSASignature$SHA512_224withRSA", - createAliasesWithOid(rsaOid + ".15"), attrs); - add(p, "Signature", "SHA512/256withRSA", - "sun.security.rsa.RSASignature$SHA512_256withRSA", - createAliasesWithOid(rsaOid + ".16"), attrs); + getAliases("PKCS1"), null); + addA(p, "Signature", "MD2withRSA", + "sun.security.rsa.RSASignature$MD2withRSA", attrs); + addA(p, "Signature", "MD5withRSA", + "sun.security.rsa.RSASignature$MD5withRSA", attrs); + addA(p, "Signature", "SHA1withRSA", + "sun.security.rsa.RSASignature$SHA1withRSA", attrs); + addA(p, "Signature", "SHA224withRSA", + "sun.security.rsa.RSASignature$SHA224withRSA", attrs); + addA(p, "Signature", "SHA256withRSA", + "sun.security.rsa.RSASignature$SHA256withRSA", attrs); + addA(p, "Signature", "SHA384withRSA", + "sun.security.rsa.RSASignature$SHA384withRSA", attrs); + addA(p, "Signature", "SHA512withRSA", + "sun.security.rsa.RSASignature$SHA512withRSA", attrs); + addA(p, "Signature", "SHA512/224withRSA", + "sun.security.rsa.RSASignature$SHA512_224withRSA", attrs); + addA(p, "Signature", "SHA512/256withRSA", + "sun.security.rsa.RSASignature$SHA512_256withRSA", attrs); - add(p, "KeyFactory", "RSASSA-PSS", - "sun.security.rsa.RSAKeyFactory$PSS", - rsapssAliases, null); - add(p, "KeyPairGenerator", "RSASSA-PSS", - "sun.security.rsa.RSAKeyPairGenerator$PSS", - rsapssAliases, null); - add(p, "Signature", "RSASSA-PSS", - "sun.security.rsa.RSAPSSSignature", - rsapssAliases, attrs); - add(p, "AlgorithmParameters", "RSASSA-PSS", - "sun.security.rsa.PSSParameters", - rsapssAliases, null); + addA(p, "KeyFactory", "RSASSA-PSS", + "sun.security.rsa.RSAKeyFactory$PSS", attrs); + addA(p, "KeyPairGenerator", "RSASSA-PSS", + "sun.security.rsa.RSAKeyPairGenerator$PSS", attrs); + addA(p, "Signature", "RSASSA-PSS", + "sun.security.rsa.RSAPSSSignature", attrs); + addA(p, "AlgorithmParameters", "RSASSA-PSS", + "sun.security.rsa.PSSParameters", attrs); } public Iterator iterator() { diff --git a/src/java.base/share/classes/sun/security/ssl/SunJSSE.java b/src/java.base/share/classes/sun/security/ssl/SunJSSE.java index 322858a9764..331adc44ca9 100644 --- a/src/java.base/share/classes/sun/security/ssl/SunJSSE.java +++ b/src/java.base/share/classes/sun/security/ssl/SunJSSE.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2019, 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 @@ -28,7 +28,7 @@ package sun.security.ssl; import java.security.*; import java.util.*; import static sun.security.util.SecurityConstants.PROVIDER_VER; -import static sun.security.provider.SunEntries.createAliases; +import static sun.security.util.SecurityProviderConstants.*; /** * The JSSE provider. @@ -74,8 +74,8 @@ public class SunJSSE extends java.security.Provider { } private void ps(String type, String algo, String cn, - List aliases, HashMap attrs) { - putService(new Provider.Service(this, type, algo, cn, aliases, attrs)); + List a, HashMap attrs) { + putService(new Provider.Service(this, type, algo, cn, a, attrs)); } private void doRegister() { @@ -86,18 +86,18 @@ public class SunJSSE extends java.security.Provider { "sun.security.ssl.KeyManagerFactoryImpl$SunX509", null, null); ps("KeyManagerFactory", "NewSunX509", "sun.security.ssl.KeyManagerFactoryImpl$X509", - createAliases("PKIX"), null); + List.of("PKIX"), null); ps("TrustManagerFactory", "SunX509", "sun.security.ssl.TrustManagerFactoryImpl$SimpleFactory", null, null); ps("TrustManagerFactory", "PKIX", "sun.security.ssl.TrustManagerFactoryImpl$PKIXFactory", - createAliases("SunPKIX", "X509", "X.509"), null); + List.of("SunPKIX", "X509", "X.509"), null); ps("SSLContext", "TLSv1", "sun.security.ssl.SSLContextImpl$TLS10Context", - createAliases("SSLv3"), null); + List.of("SSLv3"), null); ps("SSLContext", "TLSv1.1", "sun.security.ssl.SSLContextImpl$TLS11Context", null, null); ps("SSLContext", "TLSv1.2", @@ -106,7 +106,7 @@ public class SunJSSE extends java.security.Provider { "sun.security.ssl.SSLContextImpl$TLS13Context", null, null); ps("SSLContext", "TLS", "sun.security.ssl.SSLContextImpl$TLSContext", - createAliases("SSL"), null); + List.of("SSL"), null); ps("SSLContext", "DTLSv1.0", "sun.security.ssl.SSLContextImpl$DTLS10Context", null, null); diff --git a/src/java.base/share/classes/sun/security/ssl/X509KeyManagerImpl.java b/src/java.base/share/classes/sun/security/ssl/X509KeyManagerImpl.java index 636ff747827..4ab78a45868 100644 --- a/src/java.base/share/classes/sun/security/ssl/X509KeyManagerImpl.java +++ b/src/java.base/share/classes/sun/security/ssl/X509KeyManagerImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -43,6 +43,7 @@ import java.util.concurrent.atomic.AtomicLong; import javax.net.ssl.*; import sun.security.provider.certpath.AlgorithmChecker; import sun.security.validator.Validator; +import sun.security.util.KnownOIDs; /** * The new X509 key manager implementation. The main differences to the @@ -522,14 +523,19 @@ final class X509KeyManagerImpl extends X509ExtendedKeyManager // enum constant for "tls client" check // valid EKU for TLS client: any, tls_client - CLIENT(new HashSet(Arrays.asList(new String[] { - "2.5.29.37.0", "1.3.6.1.5.5.7.3.2" }))), + CLIENT(new HashSet(List.of( + KnownOIDs.anyExtendedKeyUsage.value(), + KnownOIDs.clientAuth.value() + ))), // enum constant for "tls server" check // valid EKU for TLS server: any, tls_server, ns_sgc, ms_sgc - SERVER(new HashSet(Arrays.asList(new String[] { - "2.5.29.37.0", "1.3.6.1.5.5.7.3.1", "2.16.840.1.113730.4.1", - "1.3.6.1.4.1.311.10.3.3" }))); + SERVER(new HashSet(List.of( + KnownOIDs.anyExtendedKeyUsage.value(), + KnownOIDs.serverAuth.value(), + KnownOIDs.NETSCAPE_ExportApproved.value(), + KnownOIDs.MICROSOFT_ExportApproved.value() + ))); // set of valid EKU values for this type final Set validEku; diff --git a/src/java.base/share/classes/sun/security/timestamp/TSRequest.java b/src/java.base/share/classes/sun/security/timestamp/TSRequest.java index 290981dc7e8..619f2be65ed 100644 --- a/src/java.base/share/classes/sun/security/timestamp/TSRequest.java +++ b/src/java.base/share/classes/sun/security/timestamp/TSRequest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, 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 @@ -163,7 +163,7 @@ public class TSRequest { // encode optional elements if (policyId != null) { - request.putOID(new ObjectIdentifier(policyId)); + request.putOID(ObjectIdentifier.of(policyId)); } if (nonce != null) { request.putInteger(nonce); diff --git a/src/java.base/share/classes/sun/security/tools/keytool/Main.java b/src/java.base/share/classes/sun/security/tools/keytool/Main.java index 47f4646ba9a..a6819fe06ac 100644 --- a/src/java.base/share/classes/sun/security/tools/keytool/Main.java +++ b/src/java.base/share/classes/sun/security/tools/keytool/Main.java @@ -82,6 +82,7 @@ import sun.security.pkcs10.PKCS10; import sun.security.pkcs10.PKCS10Attribute; import sun.security.provider.X509Factory; import sun.security.provider.certpath.ssl.SSLServerCertStore; +import sun.security.util.KnownOIDs; import sun.security.util.Password; import sun.security.util.SecurityProperties; import sun.security.util.SecurityProviderConstants; @@ -4125,6 +4126,23 @@ public final class Main { return c.getTime(); } + /** + * Match a command with a command set. The match can be exact, or + * partial, or case-insensitive. + * + * @param s the command provided by user + * @param list the legal command set represented by KnownOIDs enums. + * @return the position of a single match, or -1 if none matched + * @throws Exception if s is ambiguous + */ + private static int oneOf(String s, KnownOIDs... list) throws Exception { + String[] convertedList = new String[list.length]; + for (int i = 0; i < list.length; i++) { + convertedList[i] = list[i].stdName(); + } + return oneOf(s, convertedList); + } + /** * Match a command with a command set. The match can be exact, or * partial, or case-insensitive. @@ -4262,7 +4280,7 @@ public final class Main { case 5: return PKIXExtensions.SubjectInfoAccess_Id; case 6: return PKIXExtensions.AuthInfoAccess_Id; case 8: return PKIXExtensions.CRLDistributionPoints_Id; - default: return new ObjectIdentifier(type); + default: return ObjectIdentifier.of(type); } } @@ -4474,30 +4492,26 @@ public final class Main { case 2: // EKU if(value != null) { Vector v = new Vector<>(); + KnownOIDs[] choices = { + KnownOIDs.anyExtendedKeyUsage, + KnownOIDs.serverAuth, + KnownOIDs.clientAuth, + KnownOIDs.codeSigning, + KnownOIDs.emailProtection, + KnownOIDs.KP_TimeStamping, + KnownOIDs.OCSPSigning + }; for (String s: value.split(",")) { - int p = oneOf(s, - "anyExtendedKeyUsage", - "serverAuth", //1 - "clientAuth", //2 - "codeSigning", //3 - "emailProtection", //4 - "", //5 - "", //6 - "", //7 - "timeStamping", //8 - "OCSPSigning" //9 - ); - if (p < 0) { - try { - v.add(new ObjectIdentifier(s)); - } catch (Exception e) { - throw new Exception(rb.getString( - "Unknown.extendedkeyUsage.type.") + s); - } - } else if (p == 0) { - v.add(new ObjectIdentifier("2.5.29.37.0")); - } else { - v.add(new ObjectIdentifier("1.3.6.1.5.5.7.3." + p)); + int p = oneOf(s, choices); + String o = s; + if (p >= 0) { + o = choices[p].value(); + } + try { + v.add(ObjectIdentifier.of(o)); + } catch (Exception e) { + throw new Exception(rb.getString( + "Unknown.extendedkeyUsage.type.") + s); } } setExt(result, new ExtendedKeyUsageExtension(isCritical, v)); @@ -4552,24 +4566,23 @@ public final class Main { String m = item.substring(0, colonpos); String t = item.substring(colonpos+1, colonpos2); String v = item.substring(colonpos2+1); - int p = oneOf(m, - "", - "ocsp", //1 - "caIssuers", //2 - "timeStamping", //3 - "", - "caRepository" //5 - ); + KnownOIDs[] choices = { + KnownOIDs.OCSP, + KnownOIDs.caIssuers, + KnownOIDs.AD_TimeStamping, + KnownOIDs.caRepository + }; + int p = oneOf(m, choices); ObjectIdentifier oid; - if (p < 0) { + if (p >= 0) { + oid = ObjectIdentifier.of(choices[p]); + } else { try { - oid = new ObjectIdentifier(m); + oid = ObjectIdentifier.of(m); } catch (Exception e) { throw new Exception(rb.getString( "Unknown.AccessDescription.type.") + m); } - } else { - oid = new ObjectIdentifier("1.3.6.1.5.5.7.48." + p); } accessDescriptions.add(new AccessDescription( oid, createGeneralName(t, v, exttype))); @@ -4606,7 +4619,7 @@ public final class Main { } break; case -1: - ObjectIdentifier oid = new ObjectIdentifier(name); + ObjectIdentifier oid = ObjectIdentifier.of(name); byte[] data = null; if (value != null) { data = new byte[value.length() / 2 + 1]; diff --git a/src/java.base/share/classes/sun/security/util/ConstraintsParameters.java b/src/java.base/share/classes/sun/security/util/ConstraintsParameters.java index 62afa22ac08..1d13ed1841a 100644 --- a/src/java.base/share/classes/sun/security/util/ConstraintsParameters.java +++ b/src/java.base/share/classes/sun/security/util/ConstraintsParameters.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, 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 @@ -153,7 +153,7 @@ public class ConstraintsParameters { public static String[] getNamedCurveFromKey(Key key) { if (key instanceof ECKey) { NamedCurve nc = CurveDB.lookup(((ECKey)key).getParams()); - return (nc == null ? EMPTYLIST : CurveDB.getNamesByOID(nc.getObjectId())); + return (nc == null ? EMPTYLIST : nc.getNameAndAliases()); } else if (key instanceof XECKey) { String[] s = { ((NamedParameterSpec)((XECKey)key).getParams()).getName() diff --git a/src/java.base/share/classes/sun/security/util/CurveDB.java b/src/java.base/share/classes/sun/security/util/CurveDB.java index 649726463e7..4cf268fa8ae 100644 --- a/src/java.base/share/classes/sun/security/util/CurveDB.java +++ b/src/java.base/share/classes/sun/security/util/CurveDB.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2019, 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 @@ -30,7 +30,6 @@ import java.math.BigInteger; import java.security.spec.*; import java.util.*; -import java.util.regex.Pattern; /** * Repository for well-known Elliptic Curve parameters. It is used by both @@ -54,8 +53,6 @@ public class CurveDB { private static Collection specCollection; - public static final String SPLIT_PATTERN = ",|\\[|\\]"; - // Used by SunECEntries public static CollectiongetSupportedCurves() { return specCollection; @@ -117,9 +114,8 @@ public class CurveDB { return new BigInteger(s, 16); } - private static void add(String name, String soid, int type, String sfield, - String a, String b, String x, String y, String n, int h, - Pattern nameSplitPattern) { + private static void add(KnownOIDs o, int type, String sfield, + String a, String b, String x, String y, String n, int h) { BigInteger p = bi(sfield); ECField field; if ((type == P) || (type == PD)) { @@ -133,16 +129,16 @@ public class CurveDB { EllipticCurve curve = new EllipticCurve(field, bi(a), bi(b)); ECPoint g = new ECPoint(bi(x), bi(y)); - NamedCurve params = new NamedCurve(name, soid, curve, g, bi(n), h); - if (oidMap.put(soid, params) != null) { - throw new RuntimeException("Duplication oid: " + soid); + String oid = o.value(); + NamedCurve params = new NamedCurve(o, curve, g, bi(n), h); + if (oidMap.put(oid, params) != null) { + throw new RuntimeException("Duplication oid: " + oid); } - String[] commonNames = nameSplitPattern.split(name); - for (String commonName : commonNames) { - if (nameMap.put(commonName.trim().toLowerCase(Locale.ENGLISH), - params) != null) { - throw new RuntimeException("Duplication name: " + commonName); + for (String cn : params.getNameAndAliases()) { + if (nameMap.put(cn.toLowerCase(Locale.ENGLISH), + params) != null) { + throw new RuntimeException("Duplication name: " + cn); } } @@ -154,445 +150,424 @@ public class CurveDB { } } - private static class Holder { - private static final Pattern nameSplitPattern = Pattern.compile( - SPLIT_PATTERN); - } - - // Return all the names the EC curve could be using. - static String[] getNamesByOID(String oid) { - NamedCurve nc = oidMap.get(oid); - if (nc == null) { - return new String[0]; - } - String[] list = Holder.nameSplitPattern.split(nc.getName()); - int i = 0; - do { - list[i] = list[i].trim(); - } while (++i < list.length); - return list; - } - static { - Pattern nameSplitPattern = Holder.nameSplitPattern; - /* SEC2 prime curves */ - add("secp112r1", "1.3.132.0.6", P, + add(KnownOIDs.secp112r1, P, "DB7C2ABF62E35E668076BEAD208B", "DB7C2ABF62E35E668076BEAD2088", "659EF8BA043916EEDE8911702B22", "09487239995A5EE76B55F9C2F098", "A89CE5AF8724C0A23E0E0FF77500", "DB7C2ABF62E35E7628DFAC6561C5", - 1, nameSplitPattern); + 1); - add("secp112r2", "1.3.132.0.7", P, + add(KnownOIDs.secp112r2, P, "DB7C2ABF62E35E668076BEAD208B", "6127C24C05F38A0AAAF65C0EF02C", "51DEF1815DB5ED74FCC34C85D709", "4BA30AB5E892B4E1649DD0928643", "adcd46f5882e3747def36e956e97", "36DF0AAFD8B8D7597CA10520D04B", - 4, nameSplitPattern); + 4); - add("secp128r1", "1.3.132.0.28", P, + add(KnownOIDs.secp128r1, P, "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC", "E87579C11079F43DD824993C2CEE5ED3", "161FF7528B899B2D0C28607CA52C5B86", "CF5AC8395BAFEB13C02DA292DDED7A83", "FFFFFFFE0000000075A30D1B9038A115", - 1, nameSplitPattern); + 1); - add("secp128r2", "1.3.132.0.29", P, + add(KnownOIDs.secp128r2, P, "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", "D6031998D1B3BBFEBF59CC9BBFF9AEE1", "5EEEFCA380D02919DC2C6558BB6D8A5D", "7B6AA5D85E572983E6FB32A7CDEBC140", "27B6916A894D3AEE7106FE805FC34B44", "3FFFFFFF7FFFFFFFBE0024720613B5A3", - 4, nameSplitPattern); + 4); - add("secp160k1", "1.3.132.0.9", P, + add(KnownOIDs.secp160k1, P, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", "0000000000000000000000000000000000000000", "0000000000000000000000000000000000000007", "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB", "938CF935318FDCED6BC28286531733C3F03C4FEE", "0100000000000000000001B8FA16DFAB9ACA16B6B3", - 1, nameSplitPattern); + 1); - add("secp160r1", "1.3.132.0.8", P, + add(KnownOIDs.secp160r1, P, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", "4A96B5688EF573284664698968C38BB913CBFC82", "23A628553168947D59DCC912042351377AC5FB32", "0100000000000000000001F4C8F927AED3CA752257", - 1, nameSplitPattern); + 1); - add("secp160r2", "1.3.132.0.30", P, + add(KnownOIDs.secp160r2, P, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70", "B4E134D3FB59EB8BAB57274904664D5AF50388BA", "52DCB034293A117E1F4FF11B30F7199D3144CE6D", "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E", "0100000000000000000000351EE786A818F3A1A16B", - 1, nameSplitPattern); + 1); - add("secp192k1", "1.3.132.0.31", P, + add(KnownOIDs.secp192k1, P, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", "000000000000000000000000000000000000000000000000", "000000000000000000000000000000000000000000000003", "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D", "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D", "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", - 1, nameSplitPattern); + 1); - add("secp192r1 [NIST P-192, X9.62 prime192v1]", "1.2.840.10045.3.1.1", PD, + add(KnownOIDs.secp192r1, PD, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811", "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", - 1, nameSplitPattern); + 1); - add("secp224k1", "1.3.132.0.32", P, + add(KnownOIDs.secp224k1, P, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", "00000000000000000000000000000000000000000000000000000000", "00000000000000000000000000000000000000000000000000000005", "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C", "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5", "010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7", - 1, nameSplitPattern); + 1); - add("secp224r1 [NIST P-224]", "1.3.132.0.33", PD, + add(KnownOIDs.secp224r1, PD, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", - 1, nameSplitPattern); + 1); - add("secp256k1", "1.3.132.0.10", P, + add(KnownOIDs.secp256k1, P, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000007", "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", - 1, nameSplitPattern); + 1); - add("secp256r1 [NIST P-256, X9.62 prime256v1]", "1.2.840.10045.3.1.7", PD, + add(KnownOIDs.secp256r1, PD, "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", - 1, nameSplitPattern); + 1); - add("secp384r1 [NIST P-384]", "1.3.132.0.34", PD, + add(KnownOIDs.secp384r1, PD, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", - 1, nameSplitPattern); + 1); - add("secp521r1 [NIST P-521]", "1.3.132.0.35", PD, + add(KnownOIDs.secp521r1, PD, "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66", "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", - 1, nameSplitPattern); + 1); /* ANSI X9.62 prime curves */ - add("X9.62 prime192v2", "1.2.840.10045.3.1.2", P, + add(KnownOIDs.prime192v2, P, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", "CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953", "EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A", "6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15", "FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31", - 1, nameSplitPattern); + 1); - add("X9.62 prime192v3", "1.2.840.10045.3.1.3", P, + add(KnownOIDs.prime192v3, P, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", "22123DC2395A05CAA7423DAECCC94760A7D462256BD56916", "7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896", "38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0", "FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13", - 1, nameSplitPattern); + 1); - add("X9.62 prime239v1", "1.2.840.10045.3.1.4", P, + add(KnownOIDs.prime239v1, P, "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", "6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A", "0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF", "7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE", "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B", - 1, nameSplitPattern); + 1); - add("X9.62 prime239v2", "1.2.840.10045.3.1.5", P, + add(KnownOIDs.prime239v2, P, "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", "617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C", "38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7", "5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA", "7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063", - 1, nameSplitPattern); + 1); - add("X9.62 prime239v3", "1.2.840.10045.3.1.6", P, + add(KnownOIDs.prime239v3, P, "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", "255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E", "6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A", "1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3", "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551", - 1, nameSplitPattern); + 1); /* SEC2 binary curves */ - add("sect113r1", "1.3.132.0.4", B, + add(KnownOIDs.sect113r1, B, "020000000000000000000000000201", "003088250CA6E7C7FE649CE85820F7", "00E8BEE4D3E2260744188BE0E9C723", "009D73616F35F4AB1407D73562C10F", "00A52830277958EE84D1315ED31886", "0100000000000000D9CCEC8A39E56F", - 2, nameSplitPattern); + 2); - add("sect113r2", "1.3.132.0.5", B, + add(KnownOIDs.sect113r2, B, "020000000000000000000000000201", "00689918DBEC7E5A0DD6DFC0AA55C7", "0095E9A9EC9B297BD4BF36E059184F", "01A57A6A7B26CA5EF52FCDB8164797", "00B3ADC94ED1FE674C06E695BABA1D", "010000000000000108789B2496AF93", - 2, nameSplitPattern); + 2); - add("sect131r1", "1.3.132.0.22", B, + add(KnownOIDs.sect131r1, B, "080000000000000000000000000000010D", "07A11B09A76B562144418FF3FF8C2570B8", "0217C05610884B63B9C6C7291678F9D341", "0081BAF91FDF9833C40F9C181343638399", "078C6E7EA38C001F73C8134B1B4EF9E150", "0400000000000000023123953A9464B54D", - 2, nameSplitPattern); + 2); - add("sect131r2", "1.3.132.0.23", B, + add(KnownOIDs.sect131r2, B, "080000000000000000000000000000010D", "03E5A88919D7CAFCBF415F07C2176573B2", "04B8266A46C55657AC734CE38F018F2192", "0356DCD8F2F95031AD652D23951BB366A8", "0648F06D867940A5366D9E265DE9EB240F", "0400000000000000016954A233049BA98F", - 2, nameSplitPattern); + 2); - add("sect163k1 [NIST K-163]", "1.3.132.0.1", BD, + add(KnownOIDs.sect163k1, BD, "0800000000000000000000000000000000000000C9", "000000000000000000000000000000000000000001", "000000000000000000000000000000000000000001", "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8", "0289070FB05D38FF58321F2E800536D538CCDAA3D9", "04000000000000000000020108A2E0CC0D99F8A5EF", - 2, nameSplitPattern); + 2); - add("sect163r1", "1.3.132.0.2", B, + add(KnownOIDs.sect163r1, B, "0800000000000000000000000000000000000000C9", "07B6882CAAEFA84F9554FF8428BD88E246D2782AE2", "0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9", "0369979697AB43897789566789567F787A7876A654", "00435EDB42EFAFB2989D51FEFCE3C80988F41FF883", "03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B", - 2, nameSplitPattern); + 2); - add("sect163r2 [NIST B-163]", "1.3.132.0.15", BD, + add(KnownOIDs.sect163r2, BD, "0800000000000000000000000000000000000000C9", "000000000000000000000000000000000000000001", "020A601907B8C953CA1481EB10512F78744A3205FD", "03F0EBA16286A2D57EA0991168D4994637E8343E36", "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1", "040000000000000000000292FE77E70C12A4234C33", - 2, nameSplitPattern); + 2); - add("sect193r1", "1.3.132.0.24", B, + add(KnownOIDs.sect193r1, B, "02000000000000000000000000000000000000000000008001", "0017858FEB7A98975169E171F77B4087DE098AC8A911DF7B01", "00FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814", "01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1", "0025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05", "01000000000000000000000000C7F34A778F443ACC920EBA49", - 2, nameSplitPattern); + 2); - add("sect193r2", "1.3.132.0.25", B, + add(KnownOIDs.sect193r2, B, "02000000000000000000000000000000000000000000008001", "0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B", "00C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE", "00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F", "01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C", "010000000000000000000000015AAB561B005413CCD4EE99D5", - 2, nameSplitPattern); + 2); - add("sect233k1 [NIST K-233]", "1.3.132.0.26", BD, + add(KnownOIDs.sect233k1, BD, "020000000000000000000000000000000000000004000000000000000001", "000000000000000000000000000000000000000000000000000000000000", "000000000000000000000000000000000000000000000000000000000001", "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126", "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3", "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF", - 4, nameSplitPattern); + 4); - add("sect233r1 [NIST B-233]", "1.3.132.0.27", B, + add(KnownOIDs.sect233r1, B, "020000000000000000000000000000000000000004000000000000000001", "000000000000000000000000000000000000000000000000000000000001", "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD", "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B", "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052", "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7", - 2, nameSplitPattern); + 2); - add("sect239k1", "1.3.132.0.3", B, + add(KnownOIDs.sect239k1, B, "800000000000000000004000000000000000000000000000000000000001", "000000000000000000000000000000000000000000000000000000000000", "000000000000000000000000000000000000000000000000000000000001", "29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC", "76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA", "2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5", - 4, nameSplitPattern); + 4); - add("sect283k1 [NIST K-283]", "1.3.132.0.16", BD, + add(KnownOIDs.sect283k1, BD, "0800000000000000000000000000000000000000000000000000000000000000000010A1", "000000000000000000000000000000000000000000000000000000000000000000000000", "000000000000000000000000000000000000000000000000000000000000000000000001", "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836", "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259", "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61", - 4, nameSplitPattern); + 4); - add("sect283r1 [NIST B-283]", "1.3.132.0.17", B, + add(KnownOIDs.sect283r1, B, "0800000000000000000000000000000000000000000000000000000000000000000010A1", "000000000000000000000000000000000000000000000000000000000000000000000001", "027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5", "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053", "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4", "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307", - 2, nameSplitPattern); + 2); - add("sect409k1 [NIST K-409]", "1.3.132.0.36", BD, + add(KnownOIDs.sect409k1, BD, "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001", "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746", "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B", "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF", - 4, nameSplitPattern); + 4); - add("sect409r1 [NIST B-409]", "1.3.132.0.37", B, + add(KnownOIDs.sect409r1, B, "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001", "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F", "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7", "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706", "010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173", - 2, nameSplitPattern); + 2); - add("sect571k1 [NIST K-571]", "1.3.132.0.38", BD, + add(KnownOIDs.sect571k1, BD, "080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425", "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972", "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3", "020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001", - 4, nameSplitPattern); + 4); - add("sect571r1 [NIST B-571]", "1.3.132.0.39", B, + add(KnownOIDs.sect571r1, B, "080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425", "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", "02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A", "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19", "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B", "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47", - 2, nameSplitPattern); + 2); /* ANSI X9.62 binary curves */ - add("X9.62 c2tnb191v1", "1.2.840.10045.3.0.5", B, + add(KnownOIDs.c2tnb191v1, B, "800000000000000000000000000000000000000000000201", "2866537B676752636A68F56554E12640276B649EF7526267", "2E45EF571F00786F67B0081B9495A3D95462F5DE0AA185EC", "36B3DAF8A23206F9C4F299D7B21A9C369137F2C84AE1AA0D", "765BE73433B3F95E332932E70EA245CA2418EA0EF98018FB", "40000000000000000000000004A20E90C39067C893BBB9A5", - 2, nameSplitPattern); + 2); - add("X9.62 c2tnb191v2", "1.2.840.10045.3.0.6", B, + add(KnownOIDs.c2tnb191v2, B, "800000000000000000000000000000000000000000000201", "401028774D7777C7B7666D1366EA432071274F89FF01E718", "0620048D28BCBD03B6249C99182B7C8CD19700C362C46A01", "3809B2B7CC1B28CC5A87926AAD83FD28789E81E2C9E3BF10", "17434386626D14F3DBF01760D9213A3E1CF37AEC437D668A", "20000000000000000000000050508CB89F652824E06B8173", - 4, nameSplitPattern); + 4); - add("X9.62 c2tnb191v3", "1.2.840.10045.3.0.7", B, + add(KnownOIDs.c2tnb191v3, B, "800000000000000000000000000000000000000000000201", "6C01074756099122221056911C77D77E77A777E7E7E77FCB", "71FE1AF926CF847989EFEF8DB459F66394D90F32AD3F15E8", "375D4CE24FDE434489DE8746E71786015009E66E38A926DD", "545A39176196575D985999366E6AD34CE0A77CD7127B06BE", "155555555555555555555555610C0B196812BFB6288A3EA3", - 6, nameSplitPattern); + 6); - add("X9.62 c2tnb239v1", "1.2.840.10045.3.0.11", B, + add(KnownOIDs.c2tnb239v1, B, "800000000000000000000000000000000000000000000000001000000001", "32010857077C5431123A46B808906756F543423E8D27877578125778AC76", "790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16", "57927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D", "61D8EE5077C33FECF6F1A16B268DE469C3C7744EA9A971649FC7A9616305", "2000000000000000000000000000000F4D42FFE1492A4993F1CAD666E447", - 4, nameSplitPattern); + 4); - add("X9.62 c2tnb239v2", "1.2.840.10045.3.0.12", B, + add(KnownOIDs.c2tnb239v2, B, "800000000000000000000000000000000000000000000000001000000001", "4230017757A767FAE42398569B746325D45313AF0766266479B75654E65F", "5037EA654196CFF0CD82B2C14A2FCF2E3FF8775285B545722F03EACDB74B", "28F9D04E900069C8DC47A08534FE76D2B900B7D7EF31F5709F200C4CA205", "5667334C45AFF3B5A03BAD9DD75E2C71A99362567D5453F7FA6E227EC833", "1555555555555555555555555555553C6F2885259C31E3FCDF154624522D", - 6, nameSplitPattern); + 6); - add("X9.62 c2tnb239v3", "1.2.840.10045.3.0.13", B, + add(KnownOIDs.c2tnb239v3, B, "800000000000000000000000000000000000000000000000001000000001", "01238774666A67766D6676F778E676B66999176666E687666D8766C66A9F", "6A941977BA9F6A435199ACFC51067ED587F519C5ECB541B8E44111DE1D40", "70F6E9D04D289C4E89913CE3530BFDE903977D42B146D539BF1BDE4E9C92", "2E5A0EAF6E5E1305B9004DCE5C0ED7FE59A35608F33837C816D80B79F461", "0CCCCCCCCCCCCCCCCCCCCCCCCCCCCCAC4912D2D9DF903EF9888B8A0E4CFF", - 0xA, nameSplitPattern); + 0xA); - add("X9.62 c2tnb359v1", "1.2.840.10045.3.0.18", B, + add(KnownOIDs.c2tnb359v1, B, "800000000000000000000000000000000000000000000000000000000000000000000000100000000000000001", "5667676A654B20754F356EA92017D946567C46675556F19556A04616B567D223A5E05656FB549016A96656A557", "2472E2D0197C49363F1FE7F5B6DB075D52B6947D135D8CA445805D39BC345626089687742B6329E70680231988", "3C258EF3047767E7EDE0F1FDAA79DAEE3841366A132E163ACED4ED2401DF9C6BDCDE98E8E707C07A2239B1B097", "53D7E08529547048121E9C95F3791DD804963948F34FAE7BF44EA82365DC7868FE57E4AE2DE211305A407104BD", "01AF286BCA1AF286BCA1AF286BCA1AF286BCA1AF286BC9FB8F6B85C556892C20A7EB964FE7719E74F490758D3B", - 0x4C, nameSplitPattern); + 0x4C); - add("X9.62 c2tnb431r1", "1.2.840.10045.3.0.20", B, + add(KnownOIDs.c2tnb431r1, B, "800000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000001", "1A827EF00DD6FC0E234CAF046C6A5D8A85395B236CC4AD2CF32A0CADBDC9DDF620B0EB9906D0957F6C6FEACD615468DF104DE296CD8F", "10D9B4A3D9047D8B154359ABFB1B7F5485B04CEB868237DDC9DEDA982A679A5A919B626D4E50A8DD731B107A9962381FB5D807BF2618", "120FC05D3C67A99DE161D2F4092622FECA701BE4F50F4758714E8A87BBF2A658EF8C21E7C5EFE965361F6C2999C0C247B0DBD70CE6B7", "20D0AF8903A96F8D5FA2C255745D3C451B302C9346D9B7E485E7BCE41F6B591F3E8F6ADDCBB0BC4C2F947A7DE1A89B625D6A598B3760", "0340340340340340340340340340340340340340340340340340340323C313FAB50589703B5EC68D3587FEC60D161CC149C1AD4A91", - 0x2760, nameSplitPattern); + 0x2760); /* ANSI X9.62 binary curves from the 1998 standard but forbidden * in the 2005 version of the standard. @@ -600,77 +575,77 @@ public class CurveDB { * case we need to support them after all. */ /* - add("X9.62 c2pnb163v1", "1.2.840.10045.3.0.1", B, + add(KnownOIDs.c2pnb163v1, B, "080000000000000000000000000000000000000107", "072546B5435234A422E0789675F432C89435DE5242", "00C9517D06D5240D3CFF38C74B20B6CD4D6F9DD4D9", "07AF69989546103D79329FCC3D74880F33BBE803CB", "01EC23211B5966ADEA1D3F87F7EA5848AEF0B7CA9F", "0400000000000000000001E60FC8821CC74DAEAFC1", - 2, nameSplitPattern); + 2); - add("X9.62 c2pnb163v2", "1.2.840.10045.3.0.2", B, + add(KnownOIDs.c2pnb163v2, B, "080000000000000000000000000000000000000107", "0108B39E77C4B108BED981ED0E890E117C511CF072", "0667ACEB38AF4E488C407433FFAE4F1C811638DF20", "0024266E4EB5106D0A964D92C4860E2671DB9B6CC5", "079F684DDF6684C5CD258B3890021B2386DFD19FC5", "03FFFFFFFFFFFFFFFFFFFDF64DE1151ADBB78F10A7", - 2, nameSplitPattern); + 2); - add("X9.62 c2pnb163v3", "1.2.840.10045.3.0.3", B, + add(KnownOIDs.c2pnb163v3, B, "080000000000000000000000000000000000000107", "07A526C63D3E25A256A007699F5447E32AE456B50E", "03F7061798EB99E238FD6F1BF95B48FEEB4854252B", "02F9F87B7C574D0BDECF8A22E6524775F98CDEBDCB", "05B935590C155E17EA48EB3FF3718B893DF59A05D0", "03FFFFFFFFFFFFFFFFFFFE1AEE140F110AFF961309", - 2, nameSplitPattern); + 2); - add("X9.62 c2pnb176w1", "1.2.840.10045.3.0.4", B, + add(KnownOIDs.c2pnb176w1, B, "0100000000000000000000000000000000080000000007", "E4E6DB2995065C407D9D39B8D0967B96704BA8E9C90B", "5DDA470ABE6414DE8EC133AE28E9BBD7FCEC0AE0FFF2", "8D16C2866798B600F9F08BB4A8E860F3298CE04A5798", "6FA4539C2DADDDD6BAB5167D61B436E1D92BB16A562C", "00010092537397ECA4F6145799D62B0A19CE06FE26AD", - 0xFF6E, nameSplitPattern); + 0xFF6E); - add("X9.62 c2pnb208w1", "1.2.840.10045.3.0.10", B, + add(KnownOIDs.c2pnb208w1, B, "010000000000000000000000000000000800000000000000000007", "0000000000000000000000000000000000000000000000000000", "C8619ED45A62E6212E1160349E2BFA844439FAFC2A3FD1638F9E", "89FDFBE4ABE193DF9559ECF07AC0CE78554E2784EB8C1ED1A57A", "0F55B51A06E78E9AC38A035FF520D8B01781BEB1A6BB08617DE3", "000101BAF95C9723C57B6C21DA2EFF2D5ED588BDD5717E212F9D", - 0xFE48, nameSplitPattern); + 0xFE48); - add("X9.62 c2pnb272w1", "1.2.840.10045.3.0.16", B, + add(KnownOIDs.c2pnb272w1, B, "010000000000000000000000000000000000000000000000000000010000000000000B", "91A091F03B5FBA4AB2CCF49C4EDD220FB028712D42BE752B2C40094DBACDB586FB20", "7167EFC92BB2E3CE7C8AAAFF34E12A9C557003D7C73A6FAF003F99F6CC8482E540F7", "6108BABB2CEEBCF787058A056CBE0CFE622D7723A289E08A07AE13EF0D10D171DD8D", "10C7695716851EEF6BA7F6872E6142FBD241B830FF5EFCACECCAB05E02005DDE9D23", "000100FAF51354E0E39E4892DF6E319C72C8161603FA45AA7B998A167B8F1E629521", - 0xFF06, nameSplitPattern); + 0xFF06); - add("X9.62 c2pnb304w1", "1.2.840.10045.3.0.17", B, + add(KnownOIDs.c2pnb304w1, B, "010000000000000000000000000000000000000000000000000000000000000000000000000807", "FD0D693149A118F651E6DCE6802085377E5F882D1B510B44160074C1288078365A0396C8E681", "BDDB97E555A50A908E43B01C798EA5DAA6788F1EA2794EFCF57166B8C14039601E55827340BE", "197B07845E9BE2D96ADB0F5F3C7F2CFFBD7A3EB8B6FEC35C7FD67F26DDF6285A644F740A2614", "E19FBEB76E0DA171517ECF401B50289BF014103288527A9B416A105E80260B549FDC1B92C03B", "000101D556572AABAC800101D556572AABAC8001022D5C91DD173F8FB561DA6899164443051D", - 0xFE2E, nameSplitPattern); + 0xFE2E); - add("X9.62 c2pnb368w1", "1.2.840.10045.3.0.19", B, + add(KnownOIDs.c2pnb368w1, B, "0100000000000000000000000000000000000000000000000000000000000000000000002000000000000000000007", "E0D2EE25095206F5E2A4F9ED229F1F256E79A0E2B455970D8D0D865BD94778C576D62F0AB7519CCD2A1A906AE30D", "FC1217D4320A90452C760A58EDCD30C8DD069B3C34453837A34ED50CB54917E1C2112D84D164F444F8F74786046A", "1085E2755381DCCCE3C1557AFA10C2F0C0C2825646C5B34A394CBCFA8BC16B22E7E789E927BE216F02E1FB136A5F", "7B3EB1BDDCBA62D5D8B2059B525797FC73822C59059C623A45FF3843CEE8F87CD1855ADAA81E2A0750B80FDA2310", "00010090512DA9AF72B08349D98A5DD4C7B0532ECA51CE03E2D10F3B7AC579BD87E909AE40A6F131E9CFCE5BD967", - 0xFF70, nameSplitPattern); + 0xFF70); */ /* @@ -678,68 +653,68 @@ public class CurveDB { * (Twisted curves are not included) */ - add("brainpoolP160r1", "1.3.36.3.3.2.8.1.1.1", P, + add(KnownOIDs.brainpoolP160r1, P, "E95E4A5F737059DC60DFC7AD95B3D8139515620F", "340E7BE2A280EB74E2BE61BADA745D97E8F7C300", "1E589A8595423412134FAA2DBDEC95C8D8675E58", "BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3", "1667CB477A1A8EC338F94741669C976316DA6321", "E95E4A5F737059DC60DF5991D45029409E60FC09", - 1, nameSplitPattern); + 1); - add("brainpoolP192r1", "1.3.36.3.3.2.8.1.1.3", P, + add(KnownOIDs.brainpoolP192r1, P, "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", "6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF", "469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9", "C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6", "14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F", "C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", - 1, nameSplitPattern); + 1); - add("brainpoolP224r1", "1.3.36.3.3.2.8.1.1.5", P, + add(KnownOIDs.brainpoolP224r1, P, "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", "68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43", "2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B", "0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D", "58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD", "D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", - 1, nameSplitPattern); + 1); - add("brainpoolP256r1", "1.3.36.3.3.2.8.1.1.7", P, + add(KnownOIDs.brainpoolP256r1, P, "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", - 1, nameSplitPattern); + 1); - add("brainpoolP320r1", "1.3.36.3.3.2.8.1.1.9", P, + add(KnownOIDs.brainpoolP320r1, P, "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", "3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4", "520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6", "43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E20611", "14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1", "D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", - 1, nameSplitPattern); + 1); - add("brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11", P, + add(KnownOIDs.brainpoolP384r1, P, "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826", "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11", "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E", "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315", "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", - 1, nameSplitPattern); + 1); - add("brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13", P, + add(KnownOIDs.brainpoolP512r1, P, "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA", "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723", "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822", "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892", "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", - 1, nameSplitPattern); + 1); specCollection = Collections.unmodifiableCollection(oidMap.values()); } diff --git a/src/java.base/share/classes/sun/security/util/KnownOIDs.java b/src/java.base/share/classes/sun/security/util/KnownOIDs.java new file mode 100644 index 00000000000..daca0150a00 --- /dev/null +++ b/src/java.base/share/classes/sun/security/util/KnownOIDs.java @@ -0,0 +1,495 @@ +/* + * 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 sun.security.util; + +import java.util.List; +import java.util.Locale; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; + +/** + * This utility class maps algorithm name to the corresponding oid strings. + * NOTE: for 100% backward compatibility, the standard name for the enum + * is determined by existing usage and may be in lowercase/uppercase in + * order to match existing output. + */ +public enum KnownOIDs { + + // X.500 Attributes 2.5.4.* + CommonName("2.5.4.3"), + Surname("2.5.4.4"), + SerialNumber("2.5.4.5"), + CountryName("2.5.4.6"), + LocalityName("2.5.4.7"), + StateName("2.5.4.8"), + StreetAddress("2.5.4.9"), + OrgName("2.5.4.10"), + OrgUnitName("2.5.4.11"), + Title("2.5.4.12"), + GivenName("2.5.4.42"), + Initials("2.5.4.43"), + GenerationQualifier("2.5.4.44"), + DNQualifier("2.5.4.46"), + + // Certificate Extension 2.5.29.* + SubjectDirectoryAttributes("2.5.29.9"), + SubjectKeyID("2.5.29.14"), + KeyUsage("2.5.29.15"), + PrivateKeyUsage("2.5.29.16"), + SubjectAlternativeName("2.5.29.17"), + IssuerAlternativeName("2.5.29.18"), + BasicConstraints("2.5.29.19"), + CRLNumber("2.5.29.20"), + ReasonCode("2.5.29.21"), + HoldInstructionCode("2.5.29.23"), + InvalidityDate("2.5.29.24"), + DeltaCRLIndicator("2.5.29.27"), + IssuingDistributionPoint("2.5.29.28"), + CertificateIssuer("2.5.29.29"), + NameConstraints("2.5.29.30"), + CRLDistributionPoints("2.5.29.31"), + CertificatePolicies("2.5.29.32"), + CE_CERT_POLICIES_ANY("2.5.29.32.0"), + PolicyMappings("2.5.29.33"), + AuthorityKeyID("2.5.29.35"), + PolicyConstraints("2.5.29.36"), + extendedKeyUsage("2.5.29.37"), + anyExtendedKeyUsage("2.5.29.37.0"), + FreshestCRL("2.5.29.46"), + InhibitAnyPolicy("2.5.29.54"), + + // PKIX 1.3.6.1.5.5.7. + AuthInfoAccess("1.3.6.1.5.5.7.1.1"), + SubjectInfoAccess("1.3.6.1.5.5.7.1.11"), + // key usage purposes - PKIX.3.* + serverAuth("1.3.6.1.5.5.7.3.1"), + clientAuth("1.3.6.1.5.5.7.3.2"), + codeSigning("1.3.6.1.5.5.7.3.3"), + emailProtection("1.3.6.1.5.5.7.3.4"), + ipsecEndSystem("1.3.6.1.5.5.7.3.5"), + ipsecTunnel("1.3.6.1.5.5.7.3.6"), + ipsecUser("1.3.6.1.5.5.7.3.7"), + KP_TimeStamping("1.3.6.1.5.5.7.3.8", "timeStamping") { + @Override + boolean registerNames() { return false; } + }, + OCSPSigning("1.3.6.1.5.5.7.3.9"), + // access descriptors - PKIX.48.* + OCSP("1.3.6.1.5.5.7.48.1"), + OCSPBasicResponse("1.3.6.1.5.5.7.48.1.1"), + OCSPNonceExt("1.3.6.1.5.5.7.48.1.2"), + OCSPNoCheck("1.3.6.1.5.5.7.48.1.5"), + caIssuers("1.3.6.1.5.5.7.48.2"), + AD_TimeStamping("1.3.6.1.5.5.7.48.3", "timeStamping") { + @Override + boolean registerNames() { return false; } + }, + caRepository("1.3.6.1.5.5.7.48.5", "caRepository"), + + // NIST -- + // AES 2.16.840.1.101.3.4.1.* + AES("2.16.840.1.101.3.4.1"), + AES_128$ECB$NoPadding("2.16.840.1.101.3.4.1.1", "AES_128/ECB/NoPadding"), + AES_128$CBC$NoPadding("2.16.840.1.101.3.4.1.2", "AES_128/CBC/NoPadding"), + AES_128$OFB$NoPadding("2.16.840.1.101.3.4.1.3", "AES_128/OFB/NoPadding"), + AES_128$CFB$NoPadding("2.16.840.1.101.3.4.1.4", "AES_128/CFB/NoPadding"), + AESWRAP_128("2.16.840.1.101.3.4.1.5"), + AES_128$GCM$NoPadding("2.16.840.1.101.3.4.1.6", "AES_128/GCM/NoPadding"), + AES_192$ECB$NoPadding("2.16.840.1.101.3.4.1.21", "AES_192/ECB/NoPadding"), + AES_192$CBC$NoPadding("2.16.840.1.101.3.4.1.22", "AES_192/CBC/NoPadding"), + AES_192$OFB$NoPadding("2.16.840.1.101.3.4.1.23", "AES_192/OFB/NoPadding"), + AES_192$CFB$NoPadding("2.16.840.1.101.3.4.1.24", "AES_192/CFB/NoPadding"), + AESWRAP_192("2.16.840.1.101.3.4.1.25"), + AES_192$GCM$NoPadding("2.16.840.1.101.3.4.1.26", "AES_192/GCM/NoPadding"), + AES_256$ECB$NoPadding("2.16.840.1.101.3.4.1.41", "AES_256/ECB/NoPadding"), + AES_256$CBC$NoPadding("2.16.840.1.101.3.4.1.42", "AES_256/CBC/NoPadding"), + AES_256$OFB$NoPadding("2.16.840.1.101.3.4.1.43", "AES_256/OFB/NoPadding"), + AES_256$CFB$NoPadding("2.16.840.1.101.3.4.1.44", "AES_256/CFB/NoPadding"), + AESWRAP_256("2.16.840.1.101.3.4.1.45"), + AES_256$GCM$NoPadding("2.16.840.1.101.3.4.1.46", "AES_256/GCM/NoPadding"), + + // hashAlgs 2.16.840.1.101.3.4.2.* + SHA_256("2.16.840.1.101.3.4.2.1", "SHA-256", "SHA256"), + SHA_384("2.16.840.1.101.3.4.2.2", "SHA-384", "SHA384"), + SHA_512("2.16.840.1.101.3.4.2.3", "SHA-512", "SHA512"), + SHA_224("2.16.840.1.101.3.4.2.4", "SHA-224", "SHA224"), + SHA_512$224("2.16.840.1.101.3.4.2.5", "SHA-512/224", "SHA512/224"), + SHA_512$256("2.16.840.1.101.3.4.2.6", "SHA-512/256", "SHA512/256"), + SHA3_224("2.16.840.1.101.3.4.2.7", "SHA3-224"), + SHA3_256("2.16.840.1.101.3.4.2.8", "SHA3-256"), + SHA3_384("2.16.840.1.101.3.4.2.9", "SHA3-384"), + SHA3_512("2.16.840.1.101.3.4.2.10", "SHA3-512"), + SHAKE128("2.16.840.1.101.3.4.2.11"), + SHAKE256("2.16.840.1.101.3.4.2.12"), + HmacSHA3_224("2.16.840.1.101.3.4.2.13", "HmacSHA3-224"), + HmacSHA3_256("2.16.840.1.101.3.4.2.14", "HmacSHA3-256"), + HmacSHA3_384("2.16.840.1.101.3.4.2.15", "HmacSHA3-384"), + HmacSHA3_512("2.16.840.1.101.3.4.2.16", "HmacSHA3-512"), + + // sigAlgs 2.16.840.1.101.3.4.3.* + SHA224withDSA("2.16.840.1.101.3.4.3.1"), + SHA256withDSA("2.16.840.1.101.3.4.3.2"), + SHA384withDSA("2.16.840.1.101.3.4.3.3"), + SHA512withDSA("2.16.840.1.101.3.4.3.4"), + SHA3_224withRSA("2.16.840.1.101.3.4.3.13", "SHA3-224withRSA"), + SHA3_256withRSA("2.16.840.1.101.3.4.3.14", "SHA3-256withRSA"), + SHA3_384withRSA("2.16.840.1.101.3.4.3.15", "SHA3-384withRSA"), + SHA3_512withRSA("2.16.840.1.101.3.4.3.16", "SHA3-512withRSA"), + + // RSASecurity + // PKCS1 1.2.840.113549.1.1.* + PKCS1("1.2.840.113549.1.1", "RSA") { // RSA KeyPairGenerator and KeyFactory + @Override + boolean registerNames() { return false; } + }, + RSA("1.2.840.113549.1.1.1"), // RSA encryption + + MD2withRSA("1.2.840.113549.1.1.2"), + MD5withRSA("1.2.840.113549.1.1.4"), + SHA1withRSA("1.2.840.113549.1.1.5"), + OAEP("1.2.840.113549.1.1.7"), + MGF1("1.2.840.113549.1.1.8"), + PSpecified("1.2.840.113549.1.1.9"), + RSASSA_PSS("1.2.840.113549.1.1.10", "RSASSA-PSS"), + SHA256withRSA("1.2.840.113549.1.1.11"), + SHA384withRSA("1.2.840.113549.1.1.12"), + SHA512withRSA("1.2.840.113549.1.1.13"), + SHA224withRSA("1.2.840.113549.1.1.14"), + SHA512$224withRSA("1.2.840.113549.1.1.15", "SHA512/224withRSA"), + SHA512$256withRSA("1.2.840.113549.1.1.16", "SHA512/256withRSA"), + + // PKCS3 1.2.840.113549.1.3.* + DiffieHellman("1.2.840.113549.1.3.1", "DiffieHellman", "DH"), + + // PKCS5 1.2.840.113549.1.5.* + PBEWithMD5AndDES("1.2.840.113549.1.5.3"), + PBEWithMD5AndRC2("1.2.840.113549.1.5.6"), + PBEWithSHA1AndDES("1.2.840.113549.1.5.10"), + PBEWithSHA1AndRC2("1.2.840.113549.1.5.11"), + PBKDF2WithHmacSHA1("1.2.840.113549.1.5.12"), + PBES2("1.2.840.113549.1.5.13"), + + // PKCS7 1.2.840.113549.1.7.* + PKCS7("1.2.840.113549.1.7"), + Data("1.2.840.113549.1.7.1"), + SignedData("1.2.840.113549.1.7.2"), + JDK_OLD_Data("1.2.840.1113549.1.7.1"), // extra 1 in 4th component + JDK_OLD_SignedData("1.2.840.1113549.1.7.2"), + EnvelopedData("1.2.840.113549.1.7.3"), + SignedAndEnvelopedData("1.2.840.113549.1.7.4"), + DigestedData("1.2.840.113549.1.7.5"), + EncryptedData("1.2.840.113549.1.7.6"), + + // PKCS9 1.2.840.113549.1.9.* + EmailAddress("1.2.840.113549.1.9.1"), + UnstructuredName("1.2.840.113549.1.9.2"), + ContentType("1.2.840.113549.1.9.3"), + MessageDigest("1.2.840.113549.1.9.4"), + SigningTime("1.2.840.113549.1.9.5"), + CounterSignature("1.2.840.113549.1.9.6"), + ChallengePassword("1.2.840.113549.1.9.7"), + UnstructuredAddress("1.2.840.113549.1.9.8"), + ExtendedCertificateAttributes("1.2.840.113549.1.9.9"), + IssuerAndSerialNumber("1.2.840.113549.1.9.10"), + ExtensionRequest("1.2.840.113549.1.9.14"), + SMIMECapability("1.2.840.113549.1.9.15"), + TimeStampTokenInfo("1.2.840.113549.1.9.16.1.4"), + SigningCertificate("1.2.840.113549.1.9.16.2.12"), + SignatureTimestampToken("1.2.840.113549.1.9.16.2.14"), + CHACHA20_POLY1305("1.2.840.113549.1.9.16.3.18", "CHACHA20-POLY1305"), + FriendlyName("1.2.840.113549.1.9.20"), + LocalKeyID("1.2.840.113549.1.9.21"), + CertTypeX509("1.2.840.113549.1.9.22.1"), + + // PKCS12 1.2.840.113549.1.12.* + PBEWithSHA1AndRC4_128("1.2.840.113549.1.12.1.1"), + PBEWithSHA1AndRC4_40("1.2.840.113549.1.12.1.2"), + PBEWithSHA1AndDESede("1.2.840.113549.1.12.1.3"), + PBEWithSHA1AndRC2_128("1.2.840.113549.1.12.1.5"), + PBEWithSHA1AndRC2_40("1.2.840.113549.1.12.1.6"), + PKCS8ShroudedKeyBag("1.2.840.113549.1.12.10.1.2"), + CertBag("1.2.840.113549.1.12.10.1.3"), + SecretBag("1.2.840.113549.1.12.10.1.5"), + + // digestAlgs 1.2.840.113549.2.* + MD2("1.2.840.113549.2.2"), + MD5("1.2.840.113549.2.5"), + HmacSHA1("1.2.840.113549.2.7"), + HmacSHA224("1.2.840.113549.2.8"), + HmacSHA256("1.2.840.113549.2.9"), + HmacSHA384("1.2.840.113549.2.10"), + HmacSHA512("1.2.840.113549.2.11"), + HmacSHA512$224("1.2.840.113549.2.12", "HmacSHA512/224"), + HmacSHA512$256("1.2.840.113549.2.13", "HmacSHA512/256"), + + // encryptionAlgs 1.2.840.113549.3.* + RC2$CBC$PKCS5Padding("1.2.840.113549.3.2", "RC2/CBC/PKCS5Padding"), + ARCFOUR("1.2.840.113549.3.4", "ARCFOUR", "RC4"), + DESede$CBC$NoPadding("1.2.840.113549.3.7", "DESede/CBC/NoPadding"), + RC5$CBC$PKCS5Padding("1.2.840.113549.3.9", "RC5/CBC/PKCS5Padding"), + + // ANSI -- + // X9 1.2.840.10040.4.* + DSA("1.2.840.10040.4.1"), + SHA1withDSA("1.2.840.10040.4.3", "SHA1withDSA", "DSS"), + // X9.62 1.2.840.10045.* + EC("1.2.840.10045.2.1"), + + //c2pnb163v1("1.2.840.10045.3.0.1", "X9.62 c2pnb163v1"), + //c2pnb163v2("1.2.840.10045.3.0.2", "X9.62 c2pnb163v2"), + //c2pnb163v3("1.2.840.10045.3.0.3", "X9.62 c2pnb163v3"), + //c2pnb176w1("1.2.840.10045.3.0.4", "X9.62 c2pnb176w1"), + c2tnb191v1("1.2.840.10045.3.0.5", "X9.62 c2tnb191v1"), + c2tnb191v2("1.2.840.10045.3.0.6", "X9.62 c2tnb191v2"), + c2tnb191v3("1.2.840.10045.3.0.7", "X9.62 c2tnb191v3"), + //c2pnb208w1("1.2.840.10045.3.0.10", "X9.62 c2pnb208w1"), + c2tnb239v1("1.2.840.10045.3.0.11", "X9.62 c2tnb239v1"), + c2tnb239v2("1.2.840.10045.3.0.12", "X9.62 c2tnb239v2"), + c2tnb239v3("1.2.840.10045.3.0.13", "X9.62 c2tnb239v3"), + //c2pnb272w1("1.2.840.10045.3.0.16", "X9.62 c2pnb272w1"), + //c2pnb304w1("1.2.840.10045.3.0.17", "X9.62 c2pnb304w1"), + c2tnb359v1("1.2.840.10045.3.0.18", "X9.62 c2tnb359v1"), + //c2pnb368w1("1.2.840.10045.3.0.19", "X9.62 c2pnb368w1"), + c2tnb431r1("1.2.840.10045.3.0.20", "X9.62 c2tnb431r1"), + + secp192r1("1.2.840.10045.3.1.1", + "secp192r1", "NIST P-192", "X9.62 prime192v1"), + prime192v2("1.2.840.10045.3.1.2", "X9.62 prime192v2"), + prime192v3("1.2.840.10045.3.1.3", "X9.62 prime192v3"), + prime239v1("1.2.840.10045.3.1.4", "X9.62 prime239v1"), + prime239v2("1.2.840.10045.3.1.5", "X9.62 prime239v2"), + prime239v3("1.2.840.10045.3.1.6", "X9.62 prime239v3"), + secp256r1("1.2.840.10045.3.1.7", + "secp256r1", "NIST P-256", "X9.62 prime256v1"), + SHA1withECDSA("1.2.840.10045.4.1"), + SHA224withECDSA("1.2.840.10045.4.3.1"), + SHA256withECDSA("1.2.840.10045.4.3.2"), + SHA384withECDSA("1.2.840.10045.4.3.3"), + SHA512withECDSA("1.2.840.10045.4.3.4"), + SpecifiedSHA2withECDSA("1.2.840.10045.4.3"), + + // X9.42 1.2.840.10046.2.* + X942_DH("1.2.840.10046.2.1", "DiffieHellman") { // unused by JDK providers + @Override + boolean registerNames() { return false; } + }, + + // Teletrust 1.3.36.* + brainpoolP160r1("1.3.36.3.3.2.8.1.1.1"), + brainpoolP192r1("1.3.36.3.3.2.8.1.1.3"), + brainpoolP224r1("1.3.36.3.3.2.8.1.1.5"), + brainpoolP256r1("1.3.36.3.3.2.8.1.1.7"), + brainpoolP320r1("1.3.36.3.3.2.8.1.1.9"), + brainpoolP384r1("1.3.36.3.3.2.8.1.1.11"), + brainpoolP512r1("1.3.36.3.3.2.8.1.1.13"), + + // Certicom 1.3.132.* + sect163k1("1.3.132.0.1", "sect163k1", "NIST K-163"), + sect163r1("1.3.132.0.2"), + sect239k1("1.3.132.0.3"), + sect113r1("1.3.132.0.4"), + sect113r2("1.3.132.0.5"), + secp112r1("1.3.132.0.6"), + secp112r2("1.3.132.0.7"), + secp160r1("1.3.132.0.8"), + secp160k1("1.3.132.0.9"), + secp256k1("1.3.132.0.10"), + sect163r2("1.3.132.0.15", "sect163r2", "NIST B-163"), + sect283k1("1.3.132.0.16", "sect283k1", "NIST K-283"), + sect283r1("1.3.132.0.17", "sect283r1", "NIST B-283"), + + sect131r1("1.3.132.0.22"), + sect131r2("1.3.132.0.23"), + sect193r1("1.3.132.0.24"), + sect193r2("1.3.132.0.25"), + sect233k1("1.3.132.0.26", "sect233k1", "NIST K-233"), + sect233r1("1.3.132.0.27", "sect233r1", "NIST B-233"), + secp128r1("1.3.132.0.28"), + secp128r2("1.3.132.0.29"), + secp160r2("1.3.132.0.30"), + secp192k1("1.3.132.0.31"), + secp224k1("1.3.132.0.32"), + secp224r1("1.3.132.0.33", "secp224r1", "NIST P-224"), + secp384r1("1.3.132.0.34", "secp384r1", "NIST P-384"), + secp521r1("1.3.132.0.35", "secp521r1", "NIST P-521"), + sect409k1("1.3.132.0.36", "sect409k1", "NIST K-409"), + sect409r1("1.3.132.0.37", "sect409r1", "NIST B-409"), + sect571k1("1.3.132.0.38", "sect571k1", "NIST K-571"), + sect571r1("1.3.132.0.39", "sect571r1", "NIST B-571"), + + ECDH("1.3.132.1.12"), + + // OIW secsig 1.3.14.3.* + OIW_DES_CBC("1.3.14.3.2.7", "DES/CBC"), + + OIW_DSA("1.3.14.3.2.12", "DSA") { + @Override + boolean registerNames() { return false; } + }, + + OIW_JDK_SHA1withDSA("1.3.14.3.2.13", "SHA1withDSA") { + @Override + boolean registerNames() { return false; } + }, + + SHA_1("1.3.14.3.2.26", "SHA-1", "SHA", "SHA1"), + + OIW_SHA1withDSA("1.3.14.3.2.27", "SHA1withDSA") { + @Override + boolean registerNames() { return false; } + }, + + OIW_SHA1withRSA("1.3.14.3.2.29", "SHA1withRSA") { + @Override + boolean registerNames() { return false; } + }, + + // Thawte 1.3.101.* + X25519("1.3.101.110"), + X448("1.3.101.111"), + Ed25519("1.3.101.112"), + Ed448("1.3.101.113"), + + // University College London (UCL) 0.9.2342.19200300.* + UCL_UserID("0.9.2342.19200300.100.1.1"), + UCL_DomainComponent("0.9.2342.19200300.100.1.25"), + + // Netscape 2.16.840.1.113730.* + NETSCAPE_CertType("2.16.840.1.113730.1.1"), + NETSCAPE_CertSequence("2.16.840.1.113730.2.5"), + NETSCAPE_ExportApproved("2.16.840.1.113730.4.1"), + + // Oracle 2.16.840.1.113894.* + ORACLE_TrustedKeyUsage("2.16.840.1.113894.746875.1.1"), + + // Miscellaneous oids below which are legacy, and not well known + // Consider removing them in future releases when their usage + // have died out + + ITUX509_RSA("2.5.8.1.1", "RSA") { // unused by JDK providers + // defined in X.509 for RSA keys + @Override // with modulus length as its parameter + boolean registerNames() { return false; } + }, + + SkipIPAddress("1.3.6.1.4.1.42.2.11.2.1"), + JAVASOFT_JDKKeyProtector("1.3.6.1.4.1.42.2.17.1.1"), + JAVASOFT_JCEKeyProtector("1.3.6.1.4.1.42.2.19.1"), + MICROSOFT_ExportApproved("1.3.6.1.4.1.311.10.3.3"); + + private String stdName; + private String oid; + private String[] aliases; + + // find the matching enum using either name or oid string + // return null if no match found + public static KnownOIDs findMatch(String s) { + s = s.toUpperCase(Locale.ENGLISH); + KnownOIDs res = name2enum.get(s); + if (res == null && debug != null) { + debug.println("No KnownOIDs enum found for " + s); + } + return res; + } + + private static final Debug debug = Debug.getInstance("jca"); + //private static final java.io.PrintStream debug = System.out; + private static final ConcurrentHashMap name2enum = + new ConcurrentHashMap<>(); + + static { + if (debug != null) { + debug.println("Setting up name2enum:"); + } + List.of(KnownOIDs.values()).forEach(o -> { + register(o); + }); + } + + private static void register(KnownOIDs o) { + KnownOIDs ov = name2enum.put(o.oid, o); + if (ov != null) { + throw new RuntimeException("ERROR: Duplicate " + o.oid + + " between " + o + " and " + ov); + } else if (debug != null) { + debug.println(o.oid + " => " + o.name()); + } + // only register the stdName and aliases if o.registerNames() + // returns true + if (o.registerNames()) { + String stdNameUpper = o.stdName.toUpperCase(Locale.ENGLISH); + if (Objects.nonNull(name2enum.put(stdNameUpper, o))) { + throw new RuntimeException("ERROR: Duplicate " + + stdNameUpper + " exists already"); + } + if (debug != null) { + debug.println(stdNameUpper + " => " + o.name()); + } + + for (String a : o.aliases) { + String aliasUpper = a.toUpperCase(Locale.ENGLISH); + if (Objects.nonNull(name2enum.put(aliasUpper, o))) { + throw new RuntimeException("ERROR: Duplicate " + + aliasUpper + " exists already"); + } + if (debug != null) { + debug.println(aliasUpper + " => " + o.name()); + } + } + } + } + + private KnownOIDs(String oid) { + this.oid = oid; + this.stdName = name(); // defaults to enum name + this.aliases = new String[0]; + } + + private KnownOIDs(String oid, String stdName, String ... aliases) { + this.oid = oid; + this.stdName = stdName; + this.aliases = aliases; + } + + // returns the oid string associated with this enum + public String value() { + return oid; + } + + // returns the user-friendly standard algorithm name + public String stdName() { + return stdName; + } + + // return the internal aliases + public String[] aliases() { + return aliases; + } + + boolean registerNames() { + return true; + } +} diff --git a/src/java.base/share/classes/sun/security/util/NamedCurve.java b/src/java.base/share/classes/sun/security/util/NamedCurve.java index 0a677aad414..f12aba4f9c7 100644 --- a/src/java.base/share/classes/sun/security/util/NamedCurve.java +++ b/src/java.base/share/classes/sun/security/util/NamedCurve.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2014, 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 @@ -29,7 +29,7 @@ import java.io.IOException; import java.math.BigInteger; import java.security.spec.*; - +import java.util.Arrays; /** * Contains Elliptic Curve parameters. @@ -39,8 +39,8 @@ import java.security.spec.*; */ public final class NamedCurve extends ECParameterSpec { - // friendly name for toString() output - private final String name; + // friendly names with stdName followed by aliases + private final String[] nameAndAliases; // well known OID private final String oid; @@ -48,25 +48,28 @@ public final class NamedCurve extends ECParameterSpec { // encoded form (as NamedCurve identified via OID) private final byte[] encoded; - NamedCurve(String name, String oid, EllipticCurve curve, + NamedCurve(KnownOIDs ko, EllipticCurve curve, ECPoint g, BigInteger n, int h) { super(curve, g, n, h); - this.name = name; - this.oid = oid; + String[] aliases = ko.aliases(); + this.nameAndAliases = new String[aliases.length + 1]; + nameAndAliases[0] = ko.stdName(); + System.arraycopy(aliases, 0, nameAndAliases, 1, aliases.length); + + this.oid = ko.value(); DerOutputStream out = new DerOutputStream(); - try { - out.putOID(new ObjectIdentifier(oid)); + out.putOID(ObjectIdentifier.of(ko)); } catch (IOException e) { throw new RuntimeException("Internal error", e); } - encoded = out.toByteArray(); } - public String getName() { - return name; + // returns the curve's standard name followed by its aliases + public String[] getNameAndAliases() { + return nameAndAliases; } public byte[] getEncoded() { @@ -78,6 +81,17 @@ public final class NamedCurve extends ECParameterSpec { } public String toString() { - return name + " (" + oid + ")"; + StringBuilder sb = new StringBuilder(nameAndAliases[0]); + if (nameAndAliases.length > 1) { + sb.append(" ["); + int j = 1; + while (j < nameAndAliases.length - 1) { + sb.append(nameAndAliases[j++]); + sb.append(','); + } + sb.append(nameAndAliases[j] + "]"); + } + sb.append(" (" + oid + ")"); + return sb.toString(); } } diff --git a/src/java.base/share/classes/sun/security/util/ObjectIdentifier.java b/src/java.base/share/classes/sun/security/util/ObjectIdentifier.java index 224cc12a477..33bd0eea4d6 100644 --- a/src/java.base/share/classes/sun/security/util/ObjectIdentifier.java +++ b/src/java.base/share/classes/sun/security/util/ObjectIdentifier.java @@ -28,6 +28,7 @@ package sun.security.util; import java.io.*; import java.math.BigInteger; import java.util.Arrays; +import java.util.concurrent.ConcurrentHashMap; /** * Represent an ISO Object Identifier. @@ -148,7 +149,7 @@ public final class ObjectIdentifier implements Serializable { * Constructs, from a string. This string should be of the form 1.23.56. * Validity check included. */ - public ObjectIdentifier(String oid) throws IOException { + private ObjectIdentifier(String oid) throws IOException { int ch = '.'; int start = 0; int end = 0; @@ -290,18 +291,42 @@ public final class ObjectIdentifier implements Serializable { System.arraycopy(tmp, 0, encoding, 0, pos); } + // oid cache index'ed by the oid string + private static ConcurrentHashMap oidTable = + new ConcurrentHashMap<>(); + /** - * Returns an ObjectIdentifier instance for the specific string OID. + * Returns an ObjectIdentifier instance for the specific String. * - * Note: Please use legal string OID only. Otherwise, a RuntimeException - * is thrown. + * If the String is not a valid OID string, an IOException is thrown. */ - public static ObjectIdentifier of(String oid) { - try { - return new ObjectIdentifier(oid); - } catch (IOException ioe) { - throw new RuntimeException(ioe); + public static ObjectIdentifier of(String oidStr) throws IOException { + // check cache first + ObjectIdentifier oid = oidTable.get(oidStr); + if (oid == null) { + oid = new ObjectIdentifier(oidStr); + oidTable.put(oidStr, oid); } + return oid; + } + + /** + * Returns an ObjectIdentifier instance for the specific KnownOIDs. + */ + public static ObjectIdentifier of(KnownOIDs o) { + // check cache first + String oidStr = o.value(); + ObjectIdentifier oid = oidTable.get(oidStr); + if (oid == null) { + try { + oid = new ObjectIdentifier(oidStr); + } catch (IOException ioe) { + // should not happen as oid string for KnownOIDs is internal + throw new RuntimeException(ioe); + } + oidTable.put(oidStr, oid); + } + return oid; } /* diff --git a/src/java.base/share/classes/sun/security/util/SecurityProviderConstants.java b/src/java.base/share/classes/sun/security/util/SecurityProviderConstants.java index 2d16d2ed625..e3fe32f1134 100644 --- a/src/java.base/share/classes/sun/security/util/SecurityProviderConstants.java +++ b/src/java.base/share/classes/sun/security/util/SecurityProviderConstants.java @@ -25,8 +25,11 @@ package sun.security.util; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; import java.util.regex.PatternSyntaxException; import java.security.InvalidParameterException; +import java.security.ProviderException; import sun.security.action.GetPropertyAction; /** @@ -34,11 +37,59 @@ import sun.security.action.GetPropertyAction; * the JDK security/crypto providers. */ public final class SecurityProviderConstants { + // Cannot create one of these + private SecurityProviderConstants () {} + private static final Debug debug = Debug.getInstance("jca", "ProviderConfig"); - // Cannot create one of these - private SecurityProviderConstants () { + // cache for provider aliases; key is the standard algorithm name + // value is the associated aliases List + private static final ConcurrentHashMap> aliasesMap; + + // utility method for generating aliases list using the supplied + // 'oid' and 'extraAliases', then store into "aliasesMap" cache under the + // key 'stdName' + private static List store(String stdName, KnownOIDs oid, + String ... extraAliases) { + List value; + if (oid == null && extraAliases.length != 0) { + value = List.of(extraAliases); + } else { + value = new ArrayList<>(); + if (oid != null) { + value.add("OID." + oid.value()); + value.add(oid.value()); + String[] knownAliases = oid.aliases(); + if (knownAliases != null) { + for (String ka : knownAliases) { + value.add(ka); + } + } + } + for (String ea : extraAliases) { + value.add(ea); + } + } + aliasesMap.put(stdName, value); + return value; + } + + // returns an aliases List for the specified algorithm name o + // NOTE: exception is thrown if no aliases nor oid found, so + // only call this method if aliases are expected + public static List getAliases(String o) { + List res = aliasesMap.get(o); + if (res == null) { + KnownOIDs e = KnownOIDs.findMatch(o); + if (e != null) { + return store(o, e); + } + ProviderException pe = + new ProviderException("Cannot find aliases for " + o); + throw pe; + } + return res; } public static final int getDefDSASubprimeSize(int primeSize) { @@ -63,6 +114,7 @@ public final class SecurityProviderConstants { private static final String KEY_LENGTH_PROP = "jdk.security.defaultKeySize"; + static { String keyLengthStr = GetPropertyAction.privilegedGetProperty (KEY_LENGTH_PROP); @@ -137,5 +189,39 @@ public final class SecurityProviderConstants { DEF_DH_KEY_SIZE = dhKeySize; DEF_EC_KEY_SIZE = ecKeySize; DEF_ED_KEY_SIZE = edKeySize; + + // Set up aliases with default mappings + // This is needed when the mapping contains non-oid + // aliases + aliasesMap = new ConcurrentHashMap<>(); + + store("SHA1withDSA", KnownOIDs.SHA1withDSA, + KnownOIDs.OIW_JDK_SHA1withDSA.value(), + KnownOIDs.OIW_SHA1withDSA.value(), + "DSA", "SHA/DSA", "SHA-1/DSA", + "SHA1/DSA", "SHAwithDSA", "DSAWithSHA1"); + + store("DSA", KnownOIDs.DSA, KnownOIDs.OIW_DSA.value()); + + store("SHA1withRSA", KnownOIDs.SHA1withRSA, + KnownOIDs.OIW_SHA1withRSA.value()); + + store("SHA-1", KnownOIDs.SHA_1); + + store("PBEWithMD5AndDES", KnownOIDs.PBEWithMD5AndDES, "PBE"); + + store("DiffieHellman", KnownOIDs.DiffieHellman); + + store("AES", KnownOIDs.AES, "Rijndael"); + + store("EC", KnownOIDs.EC, "EllipticCurve"); + + store("X.509", null, "X509"); + store("NONEwithDSA", null, "RawDSA"); + store("DESede", null, "TripleDES"); + store("ARCFOUR", KnownOIDs.ARCFOUR); + // For backward compatility, refer to PKCS1 mapping for RSA + // KeyPairGenerator and KeyFactory + store("PKCS1", KnownOIDs.PKCS1, KnownOIDs.RSA.value()); } } diff --git a/src/java.base/share/classes/sun/security/validator/EndEntityChecker.java b/src/java.base/share/classes/sun/security/validator/EndEntityChecker.java index d3398cb2e90..03675d0b257 100644 --- a/src/java.base/share/classes/sun/security/validator/EndEntityChecker.java +++ b/src/java.base/share/classes/sun/security/validator/EndEntityChecker.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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,7 +28,7 @@ package sun.security.validator; import java.util.*; import java.security.cert.*; - +import sun.security.util.KnownOIDs; import sun.security.x509.NetscapeCertTypeExtension; /** @@ -71,24 +71,32 @@ class EndEntityChecker { private static final String OID_EXTENDED_KEY_USAGE = SimpleValidator.OID_EXTENDED_KEY_USAGE; - private static final String OID_EKU_TLS_SERVER = "1.3.6.1.5.5.7.3.1"; + private static final String OID_EKU_TLS_SERVER = + KnownOIDs.serverAuth.value(); - private static final String OID_EKU_TLS_CLIENT = "1.3.6.1.5.5.7.3.2"; + private static final String OID_EKU_TLS_CLIENT = + KnownOIDs.clientAuth.value(); - private static final String OID_EKU_CODE_SIGNING = "1.3.6.1.5.5.7.3.3"; + private static final String OID_EKU_CODE_SIGNING = + KnownOIDs.codeSigning.value(); - private static final String OID_EKU_TIME_STAMPING = "1.3.6.1.5.5.7.3.8"; + private static final String OID_EKU_TIME_STAMPING = + KnownOIDs.KP_TimeStamping.value(); - private static final String OID_EKU_ANY_USAGE = "2.5.29.37.0"; + private static final String OID_EKU_ANY_USAGE = + KnownOIDs.anyExtendedKeyUsage.value(); // the Netscape Server-Gated-Cryptography EKU extension OID - private static final String OID_EKU_NS_SGC = "2.16.840.1.113730.4.1"; + private static final String OID_EKU_NS_SGC = + KnownOIDs.NETSCAPE_ExportApproved.value(); // the Microsoft Server-Gated-Cryptography EKU extension OID - private static final String OID_EKU_MS_SGC = "1.3.6.1.4.1.311.10.3.3"; + private static final String OID_EKU_MS_SGC = + KnownOIDs.MICROSOFT_ExportApproved.value(); // the recognized extension OIDs - private static final String OID_SUBJECT_ALT_NAME = "2.5.29.17"; + private static final String OID_SUBJECT_ALT_NAME = + KnownOIDs.SubjectAlternativeName.value(); private static final String NSCT_SSL_CLIENT = NetscapeCertTypeExtension.SSL_CLIENT; diff --git a/src/java.base/share/classes/sun/security/validator/SimpleValidator.java b/src/java.base/share/classes/sun/security/validator/SimpleValidator.java index a90c8c77382..501ea510f9b 100644 --- a/src/java.base/share/classes/sun/security/validator/SimpleValidator.java +++ b/src/java.base/share/classes/sun/security/validator/SimpleValidator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -39,6 +39,7 @@ import sun.security.x509.NetscapeCertTypeExtension; import sun.security.util.DerValue; import sun.security.util.DerInputStream; import sun.security.util.ObjectIdentifier; +import sun.security.util.KnownOIDs; import sun.security.provider.certpath.AlgorithmChecker; import sun.security.provider.certpath.UntrustedChecker; @@ -60,24 +61,28 @@ public final class SimpleValidator extends Validator { // Constants for the OIDs we need - static final String OID_BASIC_CONSTRAINTS = "2.5.29.19"; + static final String OID_BASIC_CONSTRAINTS = + KnownOIDs.BasicConstraints.value(); - static final String OID_NETSCAPE_CERT_TYPE = "2.16.840.1.113730.1.1"; + static final String OID_NETSCAPE_CERT_TYPE = + KnownOIDs.NETSCAPE_CertType.value(); - static final String OID_KEY_USAGE = "2.5.29.15"; + static final String OID_KEY_USAGE = KnownOIDs.KeyUsage.value(); - static final String OID_EXTENDED_KEY_USAGE = "2.5.29.37"; + static final String OID_EXTENDED_KEY_USAGE = + KnownOIDs.extendedKeyUsage.value(); - static final String OID_EKU_ANY_USAGE = "2.5.29.37.0"; + static final String OID_EKU_ANY_USAGE = + KnownOIDs.anyExtendedKeyUsage.value(); static final ObjectIdentifier OBJID_NETSCAPE_CERT_TYPE = - NetscapeCertTypeExtension.NetscapeCertType_Id; + NetscapeCertTypeExtension.NetscapeCertType_Id; private static final String NSCT_SSL_CA = - NetscapeCertTypeExtension.SSL_CA; + NetscapeCertTypeExtension.SSL_CA; private static final String NSCT_CODE_SIGNING_CA = - NetscapeCertTypeExtension.OBJECT_SIGNING_CA; + NetscapeCertTypeExtension.OBJECT_SIGNING_CA; /** * The trusted certificates as: diff --git a/src/java.base/share/classes/sun/security/x509/AVA.java b/src/java.base/share/classes/sun/security/x509/AVA.java index d9f48e93a44..cfbdbae01b5 100644 --- a/src/java.base/share/classes/sun/security/x509/AVA.java +++ b/src/java.base/share/classes/sun/security/x509/AVA.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -1225,7 +1225,7 @@ class AVAKeyword { return ak.oid; } } else { - return new ObjectIdentifier(oidString); + return ObjectIdentifier.of(oidString); } // no keyword found, check if OID string @@ -1243,7 +1243,7 @@ class AVAKeyword { if (number == false) { throw new IOException("Invalid keyword \"" + keyword + "\""); } - return new ObjectIdentifier(keyword); + return ObjectIdentifier.of(keyword); } /** diff --git a/src/java.base/share/classes/sun/security/x509/AccessDescription.java b/src/java.base/share/classes/sun/security/x509/AccessDescription.java index 62389d52f80..c2843a971e7 100644 --- a/src/java.base/share/classes/sun/security/x509/AccessDescription.java +++ b/src/java.base/share/classes/sun/security/x509/AccessDescription.java @@ -42,16 +42,16 @@ public final class AccessDescription { private GeneralName accessLocation; public static final ObjectIdentifier Ad_OCSP_Id = - ObjectIdentifier.of("1.3.6.1.5.5.7.48.1"); + ObjectIdentifier.of(KnownOIDs.OCSP); public static final ObjectIdentifier Ad_CAISSUERS_Id = - ObjectIdentifier.of("1.3.6.1.5.5.7.48.2"); + ObjectIdentifier.of(KnownOIDs.caIssuers); public static final ObjectIdentifier Ad_TIMESTAMPING_Id = - ObjectIdentifier.of("1.3.6.1.5.5.7.48.3"); + ObjectIdentifier.of(KnownOIDs.AD_TimeStamping); public static final ObjectIdentifier Ad_CAREPOSITORY_Id = - ObjectIdentifier.of("1.3.6.1.5.5.7.48.5"); + ObjectIdentifier.of(KnownOIDs.caRepository); public AccessDescription(ObjectIdentifier accessMethod, GeneralName accessLocation) { this.accessMethod = accessMethod; diff --git a/src/java.base/share/classes/sun/security/x509/AlgorithmId.java b/src/java.base/share/classes/sun/security/x509/AlgorithmId.java index 48e4cc19b04..8351bfa8168 100644 --- a/src/java.base/share/classes/sun/security/x509/AlgorithmId.java +++ b/src/java.base/share/classes/sun/security/x509/AlgorithmId.java @@ -33,6 +33,7 @@ import java.security.spec.InvalidParameterSpecException; import java.security.spec.MGF1ParameterSpec; import java.security.spec.PSSParameterSpec; import java.util.*; +import java.util.concurrent.ConcurrentHashMap; import java.security.*; import java.security.interfaces.*; @@ -248,21 +249,31 @@ public class AlgorithmId implements Serializable, DerEncoder { * returns the "full" signature algorithm (Ex: SHA256withECDSA) directly. */ public String getName() { - String algName = nameTable.get(algid); - if (algName != null) { - return algName; - } - if ((params != null) && algid.equals((Object)specifiedWithECDSA_oid)) { - try { - AlgorithmId paramsId = + String oidStr = algid.toString(); + // first check the list of support oids + KnownOIDs o = KnownOIDs.findMatch(oidStr); + if (o == KnownOIDs.SpecifiedSHA2withECDSA) { + if (params != null) { + try { + AlgorithmId paramsId = AlgorithmId.parse(new DerValue(params.toByteArray())); - String paramsName = paramsId.getName(); - algName = makeSigAlg(paramsName, "EC"); - } catch (IOException e) { - // ignore + String paramsName = paramsId.getName(); + return makeSigAlg(paramsName, "EC"); + } catch (IOException e) { + // ignore + } + } + } + if (o != null) { + return o.stdName(); + } else { + String n = aliasOidsTable().get(oidStr); + if (n != null) { + return n; + } else { + return algid.toString(); } } - return (algName == null) ? algid.toString() : algName; } public AlgorithmParameters getParameters() { @@ -280,7 +291,8 @@ public class AlgorithmId implements Serializable, DerEncoder { * @return DER encoded parameters, or null not present. */ public byte[] getEncodedParams() throws IOException { - return (params == null || algid.equals(specifiedWithECDSA_oid)) + return (params == null || + algid.toString().equals(KnownOIDs.SpecifiedSHA2withECDSA.value())) ? null : params.toByteArray(); } @@ -474,505 +486,147 @@ public class AlgorithmId implements Serializable, DerEncoder { * used as a "KeyPairGenerator" algorithm. */ private static ObjectIdentifier algOID(String name) throws IOException { - // See if algname is in printable OID ("dot-dot") notation - if (name.indexOf('.') != -1) { - if (name.startsWith("OID.")) { - return new ObjectIdentifier(name.substring("OID.".length())); - } else { - return new ObjectIdentifier(name); - } + if (name.startsWith("OID.")) { + name = name.substring("OID.".length()); } - // Digesting algorithms - if (name.equalsIgnoreCase("MD5")) { - return AlgorithmId.MD5_oid; - } - if (name.equalsIgnoreCase("MD2")) { - return AlgorithmId.MD2_oid; - } - if (name.equalsIgnoreCase("SHA") || name.equalsIgnoreCase("SHA1") - || name.equalsIgnoreCase("SHA-1")) { - return AlgorithmId.SHA_oid; - } - if (name.equalsIgnoreCase("SHA-256") || - name.equalsIgnoreCase("SHA256")) { - return AlgorithmId.SHA256_oid; - } - if (name.equalsIgnoreCase("SHA-384") || - name.equalsIgnoreCase("SHA384")) { - return AlgorithmId.SHA384_oid; - } - if (name.equalsIgnoreCase("SHA-512") || - name.equalsIgnoreCase("SHA512")) { - return AlgorithmId.SHA512_oid; - } - if (name.equalsIgnoreCase("SHA-224") || - name.equalsIgnoreCase("SHA224")) { - return AlgorithmId.SHA224_oid; - } - if (name.equalsIgnoreCase("SHA-512/224") || - name.equalsIgnoreCase("SHA512/224")) { - return AlgorithmId.SHA512_224_oid; - } - if (name.equalsIgnoreCase("SHA-512/256") || - name.equalsIgnoreCase("SHA512/256")) { - return AlgorithmId.SHA512_256_oid; - } - // Various public key algorithms - if (name.equalsIgnoreCase("RSA")) { - return AlgorithmId.RSAEncryption_oid; - } - if (name.equalsIgnoreCase("RSASSA-PSS")) { - return AlgorithmId.RSASSA_PSS_oid; - } - if (name.equalsIgnoreCase("RSAES-OAEP")) { - return AlgorithmId.RSAES_OAEP_oid; - } - if (name.equalsIgnoreCase("Diffie-Hellman") - || name.equalsIgnoreCase("DH")) { - return AlgorithmId.DH_oid; - } - if (name.equalsIgnoreCase("DSA")) { - return AlgorithmId.DSA_oid; - } - if (name.equalsIgnoreCase("EC")) { - return EC_oid; - } - if (name.equalsIgnoreCase("ECDH")) { - return AlgorithmId.ECDH_oid; + KnownOIDs k = KnownOIDs.findMatch(name); + if (k != null) { + return ObjectIdentifier.of(k); } - // Secret key algorithms - if (name.equalsIgnoreCase("AES")) { - return AlgorithmId.AES_oid; + // unknown algorithm oids + if (name.indexOf(".") == -1) { + // see if there is a matching oid string alias mapping from + // 3rd party providers + name = name.toUpperCase(Locale.ENGLISH); + String oidStr = aliasOidsTable().get(name); + if (oidStr != null) { + return ObjectIdentifier.of(oidStr); + } return null; + } else { + return ObjectIdentifier.of(name); } - - // Common signature types - if (name.equalsIgnoreCase("MD5withRSA") - || name.equalsIgnoreCase("MD5/RSA")) { - return AlgorithmId.md5WithRSAEncryption_oid; - } - if (name.equalsIgnoreCase("MD2withRSA") - || name.equalsIgnoreCase("MD2/RSA")) { - return AlgorithmId.md2WithRSAEncryption_oid; - } - if (name.equalsIgnoreCase("SHAwithDSA") - || name.equalsIgnoreCase("SHA1withDSA") - || name.equalsIgnoreCase("SHA/DSA") - || name.equalsIgnoreCase("SHA1/DSA") - || name.equalsIgnoreCase("DSAWithSHA1") - || name.equalsIgnoreCase("DSS") - || name.equalsIgnoreCase("SHA-1/DSA")) { - return AlgorithmId.sha1WithDSA_oid; - } - if (name.equalsIgnoreCase("SHA224WithDSA")) { - return AlgorithmId.sha224WithDSA_oid; - } - if (name.equalsIgnoreCase("SHA256WithDSA")) { - return AlgorithmId.sha256WithDSA_oid; - } - if (name.equalsIgnoreCase("SHA1WithRSA") - || name.equalsIgnoreCase("SHA1/RSA")) { - return AlgorithmId.sha1WithRSAEncryption_oid; - } - if (name.equalsIgnoreCase("SHA1withECDSA") - || name.equalsIgnoreCase("ECDSA")) { - return AlgorithmId.sha1WithECDSA_oid; - } - if (name.equalsIgnoreCase("SHA224withECDSA")) { - return AlgorithmId.sha224WithECDSA_oid; - } - if (name.equalsIgnoreCase("SHA256withECDSA")) { - return AlgorithmId.sha256WithECDSA_oid; - } - if (name.equalsIgnoreCase("SHA384withECDSA")) { - return AlgorithmId.sha384WithECDSA_oid; - } - if (name.equalsIgnoreCase("SHA512withECDSA")) { - return AlgorithmId.sha512WithECDSA_oid; - } - if (name.equalsIgnoreCase("ED25519")) { - return AlgorithmId.ed25519_oid; - } - if (name.equalsIgnoreCase("ED448")) { - return AlgorithmId.ed448_oid; - } - - return oidTable().get(name.toUpperCase(Locale.ENGLISH)); } - private static volatile Map oidTable; - private static final Map nameTable; + // oid string cache index'ed by algorithm name and oid strings + private static volatile Map aliasOidsTable; - /** Returns the oidTable, lazily initializing it on first access. */ - private static Map oidTable() - throws IOException { - // Double checked locking; safe because oidTable is volatile - Map tab; - if ((tab = oidTable) == null) { + // returns the aliasOidsTable, lazily initializing it on first access. + private static Map aliasOidsTable() { + // Double checked locking; safe because aliasOidsTable is volatile + Map tab = aliasOidsTable; + if (tab == null) { synchronized (AlgorithmId.class) { - if ((tab = oidTable) == null) - oidTable = tab = computeOidTable(); - } - } - return tab; - } - - /** Collects the algorithm names from the installed providers. */ - private static HashMap computeOidTable() - throws IOException { - HashMap tab = new HashMap<>(); - for (Provider provider : Security.getProviders()) { - for (Object key : provider.keySet()) { - String alias = (String)key; - String upperCaseAlias = alias.toUpperCase(Locale.ENGLISH); - int index; - if (upperCaseAlias.startsWith("ALG.ALIAS") && - (index=upperCaseAlias.indexOf("OID.", 0)) != -1) { - index += "OID.".length(); - if (index == alias.length()) { - // invalid alias entry - break; - } - String oidString = alias.substring(index); - String stdAlgName = provider.getProperty(alias); - if (stdAlgName != null) { - stdAlgName = stdAlgName.toUpperCase(Locale.ENGLISH); - } - if (stdAlgName != null && - tab.get(stdAlgName) == null) { - tab.put(stdAlgName, new ObjectIdentifier(oidString)); - } + if ((tab = aliasOidsTable) == null) { + aliasOidsTable = tab = collectOIDAliases(); } } } return tab; } - /*****************************************************************/ + private static boolean isKnownProvider(Provider p) { + String pn = p.getName(); + String mn = p.getClass().getModule().getName(); + if (pn != null && mn != null) { + return ((mn.equals("java.base") && + (pn.equals("SUN") || pn.equals("SunRsaSign") || + pn.equals("SunJCE") || pn.equals("SunJSSE"))) || + (mn.equals("jdk.crypto.ec") && pn.equals("SunEC")) || + (mn.equals("jdk.crypto.mscapi") && pn.equals("SunMSCAPI")) || + (mn.equals("jdk.crypto.cryptoki") && + pn.startsWith("SunPKCS11"))); + } else { + return false; + } + } - /* - * HASHING ALGORITHMS - */ + private static ConcurrentHashMap collectOIDAliases() { + ConcurrentHashMap t = new ConcurrentHashMap<>(); + for (Provider provider : Security.getProviders()) { + // skip providers which are already using SecurityProviderConstants + // and KnownOIDs + if (isKnownProvider(provider)) { + continue; + } + for (Object key : provider.keySet()) { + String alias = (String)key; + String upperCaseAlias = alias.toUpperCase(Locale.ENGLISH); + int index; + if (upperCaseAlias.startsWith("ALG.ALIAS") && + (index = upperCaseAlias.indexOf("OID.", 0)) != -1) { + index += "OID.".length(); + if (index == alias.length()) { + // invalid alias entry + break; + } + String ostr = alias.substring(index); + String stdAlgName = provider.getProperty(alias); + if (stdAlgName != null) { + stdAlgName = stdAlgName.toUpperCase(Locale.ENGLISH); + } + // add the name->oid and oid->name mappings if none exists + if (KnownOIDs.findMatch(stdAlgName) == null) { + // not override earlier entries if it exists + t.putIfAbsent(stdAlgName, ostr); + } + if (KnownOIDs.findMatch(ostr) == null) { + // not override earlier entries if it exists + t.putIfAbsent(ostr, stdAlgName); + } + } + } + } + return t; + } - /** - * Algorithm ID for the MD2 Message Digest Algorthm, from RFC 1319. - * OID = 1.2.840.113549.2.2 - */ public static final ObjectIdentifier MD2_oid = - ObjectIdentifier.of("1.2.840.113549.2.2"); + ObjectIdentifier.of(KnownOIDs.MD2); - /** - * Algorithm ID for the MD5 Message Digest Algorthm, from RFC 1321. - * OID = 1.2.840.113549.2.5 - */ public static final ObjectIdentifier MD5_oid = - ObjectIdentifier.of("1.2.840.113549.2.5"); + ObjectIdentifier.of(KnownOIDs.MD5); - /** - * Algorithm ID for the SHA1 Message Digest Algorithm, from FIPS 180-1. - * This is sometimes called "SHA", though that is often confusing since - * many people refer to FIPS 180 (which has an error) as defining SHA. - * OID = 1.3.14.3.2.26. Old SHA-0 OID: 1.3.14.3.2.18. - */ public static final ObjectIdentifier SHA_oid = - ObjectIdentifier.of("1.3.14.3.2.26"); + ObjectIdentifier.of(KnownOIDs.SHA_1); public static final ObjectIdentifier SHA224_oid = - ObjectIdentifier.of("2.16.840.1.101.3.4.2.4"); + ObjectIdentifier.of(KnownOIDs.SHA_224); public static final ObjectIdentifier SHA256_oid = - ObjectIdentifier.of("2.16.840.1.101.3.4.2.1"); + ObjectIdentifier.of(KnownOIDs.SHA_256); public static final ObjectIdentifier SHA384_oid = - ObjectIdentifier.of("2.16.840.1.101.3.4.2.2"); + ObjectIdentifier.of(KnownOIDs.SHA_384); public static final ObjectIdentifier SHA512_oid = - ObjectIdentifier.of("2.16.840.1.101.3.4.2.3"); + ObjectIdentifier.of(KnownOIDs.SHA_512); public static final ObjectIdentifier SHA512_224_oid = - ObjectIdentifier.of("2.16.840.1.101.3.4.2.5"); + ObjectIdentifier.of(KnownOIDs.SHA_512$224); public static final ObjectIdentifier SHA512_256_oid = - ObjectIdentifier.of("2.16.840.1.101.3.4.2.6"); + ObjectIdentifier.of(KnownOIDs.SHA_512$256); - /* - * COMMON PUBLIC KEY TYPES - */ - /* - * Note the preferred OIDs are named simply with no "OIW" or - * "PKIX" in them, even though they may point to data from these - * specs; e.g. SHA_oid, DH_oid, DSA_oid, SHA1WithDSA_oid... - */ - /** - * Algorithm ID for Diffie Hellman Key agreement, from PKCS #3. - * Parameters include public values P and G, and may optionally specify - * the length of the private key X. Alternatively, algorithm parameters - * may be derived from another source such as a Certificate Authority's - * certificate. - * OID = 1.2.840.113549.1.3.1 - */ - public static final ObjectIdentifier DH_oid = - ObjectIdentifier.of("1.2.840.113549.1.3.1"); - - /** - * Algorithm ID for the Diffie Hellman Key Agreement (DH), from RFC 3279. - * Parameters may include public values P and G. - * OID = 1.2.840.10046.2.1 - */ - public static final ObjectIdentifier DH_PKIX_oid = - ObjectIdentifier.of("1.2.840.10046.2.1"); - - /** - * Algorithm ID for the Digital Signing Algorithm (DSA), from the - * NIST OIW Stable Agreements part 12. - * Parameters may include public values P, Q, and G; or these may be - * derived from - * another source such as a Certificate Authority's certificate. - * OID = 1.3.14.3.2.12 - */ - public static final ObjectIdentifier DSA_OIW_oid = - ObjectIdentifier.of("1.3.14.3.2.12"); - - /** - * Algorithm ID for the Digital Signing Algorithm (DSA), from RFC 3279. - * Parameters may include public values P, Q, and G; or these may be - * derived from another source such as a Certificate Authority's - * certificate. - * OID = 1.2.840.10040.4.1 - */ public static final ObjectIdentifier DSA_oid = - ObjectIdentifier.of("1.2.840.10040.4.1"); - - /** - * Algorithm ID for RSA keys used for any purpose, as defined in X.509. - * The algorithm parameter is a single value, the number of bits in the - * public modulus. - * OID = 2.5.8.1.1 - */ - public static final ObjectIdentifier RSA_oid = - ObjectIdentifier.of("2.5.8.1.1"); + ObjectIdentifier.of(KnownOIDs.DSA); public static final ObjectIdentifier EC_oid = - ObjectIdentifier.of("1.2.840.10045.2.1"); - public static final ObjectIdentifier ECDH_oid = - ObjectIdentifier.of("1.3.132.1.12"); + ObjectIdentifier.of(KnownOIDs.EC); + public static final ObjectIdentifier RSAEncryption_oid = - ObjectIdentifier.of("1.2.840.113549.1.1.1"); - public static final ObjectIdentifier RSAES_OAEP_oid = - ObjectIdentifier.of("1.2.840.113549.1.1.7"); - public static final ObjectIdentifier mgf1_oid = - ObjectIdentifier.of("1.2.840.113549.1.1.8"); + ObjectIdentifier.of(KnownOIDs.RSA); + public static final ObjectIdentifier RSASSA_PSS_oid = - ObjectIdentifier.of("1.2.840.113549.1.1.10"); + ObjectIdentifier.of(KnownOIDs.RSASSA_PSS); - /* - * COMMON SECRET KEY TYPES - */ - public static final ObjectIdentifier AES_oid = - ObjectIdentifier.of("2.16.840.1.101.3.4.1"); - - /* - * COMMON SIGNATURE ALGORITHMS - */ - /** - * Identifies a signing algorithm where an MD2 digest is encrypted - * using an RSA private key; defined in PKCS #1. Use of this - * signing algorithm is discouraged due to MD2 vulnerabilities. - * OID = 1.2.840.113549.1.1.2 - */ - public static final ObjectIdentifier md2WithRSAEncryption_oid = - ObjectIdentifier.of("1.2.840.113549.1.1.2"); - - /** - * Identifies a signing algorithm where an MD5 digest is - * encrypted using an RSA private key; defined in PKCS #1. - * OID = 1.2.840.113549.1.1.4 - */ - public static final ObjectIdentifier md5WithRSAEncryption_oid = - ObjectIdentifier.of("1.2.840.113549.1.1.4"); - - /** - * Identifies a signing algorithm where a SHA1 digest is - * encrypted using an RSA private key; defined by RSA DSI. - * OID = 1.2.840.113549.1.1.5 - */ - public static final ObjectIdentifier sha1WithRSAEncryption_oid = - ObjectIdentifier.of("1.2.840.113549.1.1.5"); - - /** - * Identifies a signing algorithm where a SHA1 digest is - * encrypted using an RSA private key; defined in NIST OIW. - * OID = 1.3.14.3.2.29 - */ - public static final ObjectIdentifier sha1WithRSAEncryption_OIW_oid = - ObjectIdentifier.of("1.3.14.3.2.29"); - - /** - * Identifies a signing algorithm where a SHA224 digest is - * encrypted using an RSA private key; defined by PKCS #1. - * OID = 1.2.840.113549.1.1.14 - */ - public static final ObjectIdentifier sha224WithRSAEncryption_oid = - ObjectIdentifier.of("1.2.840.113549.1.1.14"); - - /** - * Identifies a signing algorithm where a SHA256 digest is - * encrypted using an RSA private key; defined by PKCS #1. - * OID = 1.2.840.113549.1.1.11 - */ - public static final ObjectIdentifier sha256WithRSAEncryption_oid = - ObjectIdentifier.of("1.2.840.113549.1.1.11"); - - /** - * Identifies a signing algorithm where a SHA384 digest is - * encrypted using an RSA private key; defined by PKCS #1. - * OID = 1.2.840.113549.1.1.12 - */ - public static final ObjectIdentifier sha384WithRSAEncryption_oid = - ObjectIdentifier.of("1.2.840.113549.1.1.12"); - - /** - * Identifies a signing algorithm where a SHA512 digest is - * encrypted using an RSA private key; defined by PKCS #1. - * OID = 1.2.840.113549.1.1.13 - */ - public static final ObjectIdentifier sha512WithRSAEncryption_oid = - ObjectIdentifier.of("1.2.840.113549.1.1.13"); - - /** - * Identifies the FIPS 186 "Digital Signature Standard" (DSS), where a - * SHA digest is signed using the Digital Signing Algorithm (DSA). - * This should not be used. - * OID = 1.3.14.3.2.13 - */ - public static final ObjectIdentifier shaWithDSA_OIW_oid = - ObjectIdentifier.of("1.3.14.3.2.13"); - - /** - * Identifies the FIPS 186 "Digital Signature Standard" (DSS), where a - * SHA1 digest is signed using the Digital Signing Algorithm (DSA). - * OID = 1.3.14.3.2.27 - */ - public static final ObjectIdentifier sha1WithDSA_OIW_oid = - ObjectIdentifier.of("1.3.14.3.2.27"); - - /** - * Identifies the FIPS 186 "Digital Signature Standard" (DSS), where a - * SHA1 digest is signed using the Digital Signing Algorithm (DSA). - * OID = 1.2.840.10040.4.3 - */ - public static final ObjectIdentifier sha1WithDSA_oid = - ObjectIdentifier.of("1.2.840.10040.4.3"); - - public static final ObjectIdentifier sha512_224WithRSAEncryption_oid = - ObjectIdentifier.of("1.2.840.113549.1.1.15"); - public static final ObjectIdentifier sha512_256WithRSAEncryption_oid = - ObjectIdentifier.of("1.2.840.113549.1.1.16"); - - public static final ObjectIdentifier sha224WithDSA_oid = - ObjectIdentifier.of("2.16.840.1.101.3.4.3.1"); - public static final ObjectIdentifier sha256WithDSA_oid = - ObjectIdentifier.of("2.16.840.1.101.3.4.3.2"); - - public static final ObjectIdentifier sha1WithECDSA_oid = - ObjectIdentifier.of("1.2.840.10045.4.1"); - public static final ObjectIdentifier sha224WithECDSA_oid = - ObjectIdentifier.of("1.2.840.10045.4.3.1"); - public static final ObjectIdentifier sha256WithECDSA_oid = - ObjectIdentifier.of("1.2.840.10045.4.3.2"); - public static final ObjectIdentifier sha384WithECDSA_oid = - ObjectIdentifier.of("1.2.840.10045.4.3.3"); - public static final ObjectIdentifier sha512WithECDSA_oid = - ObjectIdentifier.of("1.2.840.10045.4.3.4"); - public static final ObjectIdentifier specifiedWithECDSA_oid = - ObjectIdentifier.of("1.2.840.10045.4.3"); - - /** - * Algorithm ID for the PBE encryption algorithms from PKCS#5 and - * PKCS#12. - */ - public static final ObjectIdentifier pbeWithMD5AndDES_oid = - ObjectIdentifier.of("1.2.840.113549.1.5.3"); - public static final ObjectIdentifier pbeWithMD5AndRC2_oid = - ObjectIdentifier.of("1.2.840.113549.1.5.6"); - public static final ObjectIdentifier pbeWithSHA1AndDES_oid = - ObjectIdentifier.of("1.2.840.113549.1.5.10"); - public static final ObjectIdentifier pbeWithSHA1AndRC2_oid = - ObjectIdentifier.of("1.2.840.113549.1.5.11"); - public static final ObjectIdentifier pbeWithSHA1AndRC4_128_oid = - ObjectIdentifier.of("1.2.840.113549.1.12.1.1"); - public static final ObjectIdentifier pbeWithSHA1AndRC4_40_oid = - ObjectIdentifier.of("1.2.840.113549.1.12.1.2"); - public static final ObjectIdentifier pbeWithSHA1AndDESede_oid = - ObjectIdentifier.of("1.2.840.113549.1.12.1.3"); - public static final ObjectIdentifier pbeWithSHA1AndRC2_128_oid = - ObjectIdentifier.of("1.2.840.113549.1.12.1.5"); - public static final ObjectIdentifier pbeWithSHA1AndRC2_40_oid = - ObjectIdentifier.of("1.2.840.113549.1.12.1.6"); + public static final ObjectIdentifier MGF1_oid = + ObjectIdentifier.of(KnownOIDs.MGF1); public static final ObjectIdentifier ed25519_oid = - ObjectIdentifier.of("1.3.101.112"); + ObjectIdentifier.of(KnownOIDs.Ed25519); public static final ObjectIdentifier ed448_oid = - ObjectIdentifier.of("1.3.101.113"); - - static { - nameTable = new HashMap<>(); - nameTable.put(MD5_oid, "MD5"); - nameTable.put(MD2_oid, "MD2"); - nameTable.put(SHA_oid, "SHA-1"); - nameTable.put(SHA224_oid, "SHA-224"); - nameTable.put(SHA256_oid, "SHA-256"); - nameTable.put(SHA384_oid, "SHA-384"); - nameTable.put(SHA512_oid, "SHA-512"); - nameTable.put(SHA512_224_oid, "SHA-512/224"); - nameTable.put(SHA512_256_oid, "SHA-512/256"); - nameTable.put(RSAEncryption_oid, "RSA"); - nameTable.put(RSA_oid, "RSA"); - nameTable.put(DH_oid, "Diffie-Hellman"); - nameTable.put(DH_PKIX_oid, "Diffie-Hellman"); - nameTable.put(DSA_oid, "DSA"); - nameTable.put(DSA_OIW_oid, "DSA"); - nameTable.put(EC_oid, "EC"); - nameTable.put(ECDH_oid, "ECDH"); - nameTable.put(ed25519_oid, "ED25519"); - nameTable.put(ed448_oid, "ED448"); - - nameTable.put(AES_oid, "AES"); - - nameTable.put(sha1WithECDSA_oid, "SHA1withECDSA"); - nameTable.put(sha224WithECDSA_oid, "SHA224withECDSA"); - nameTable.put(sha256WithECDSA_oid, "SHA256withECDSA"); - nameTable.put(sha384WithECDSA_oid, "SHA384withECDSA"); - nameTable.put(sha512WithECDSA_oid, "SHA512withECDSA"); - nameTable.put(md5WithRSAEncryption_oid, "MD5withRSA"); - nameTable.put(md2WithRSAEncryption_oid, "MD2withRSA"); - nameTable.put(sha1WithDSA_oid, "SHA1withDSA"); - nameTable.put(sha1WithDSA_OIW_oid, "SHA1withDSA"); - nameTable.put(shaWithDSA_OIW_oid, "SHA1withDSA"); - nameTable.put(sha224WithDSA_oid, "SHA224withDSA"); - nameTable.put(sha256WithDSA_oid, "SHA256withDSA"); - nameTable.put(sha1WithRSAEncryption_oid, "SHA1withRSA"); - nameTable.put(sha1WithRSAEncryption_OIW_oid, "SHA1withRSA"); - nameTable.put(sha224WithRSAEncryption_oid, "SHA224withRSA"); - nameTable.put(sha256WithRSAEncryption_oid, "SHA256withRSA"); - nameTable.put(sha384WithRSAEncryption_oid, "SHA384withRSA"); - nameTable.put(sha512WithRSAEncryption_oid, "SHA512withRSA"); - nameTable.put(sha512_224WithRSAEncryption_oid, "SHA512/224withRSA"); - nameTable.put(sha512_256WithRSAEncryption_oid, "SHA512/256withRSA"); - nameTable.put(RSASSA_PSS_oid, "RSASSA-PSS"); - nameTable.put(RSAES_OAEP_oid, "RSAES-OAEP"); - - nameTable.put(pbeWithMD5AndDES_oid, "PBEWithMD5AndDES"); - nameTable.put(pbeWithMD5AndRC2_oid, "PBEWithMD5AndRC2"); - nameTable.put(pbeWithSHA1AndDES_oid, "PBEWithSHA1AndDES"); - nameTable.put(pbeWithSHA1AndRC2_oid, "PBEWithSHA1AndRC2"); - nameTable.put(pbeWithSHA1AndRC4_128_oid, "PBEWithSHA1AndRC4_128"); - nameTable.put(pbeWithSHA1AndRC4_40_oid, "PBEWithSHA1AndRC4_40"); - nameTable.put(pbeWithSHA1AndDESede_oid, "PBEWithSHA1AndDESede"); - nameTable.put(pbeWithSHA1AndRC2_128_oid, "PBEWithSHA1AndRC2_128"); - nameTable.put(pbeWithSHA1AndRC2_40_oid, "PBEWithSHA1AndRC2_40"); - } + ObjectIdentifier.of(KnownOIDs.Ed448); /** * Creates a signature algorithm name from a digest algorithm diff --git a/src/java.base/share/classes/sun/security/x509/ExtendedKeyUsageExtension.java b/src/java.base/share/classes/sun/security/x509/ExtendedKeyUsageExtension.java index dfec6526181..55842ed13f5 100644 --- a/src/java.base/share/classes/sun/security/x509/ExtendedKeyUsageExtension.java +++ b/src/java.base/share/classes/sun/security/x509/ExtendedKeyUsageExtension.java @@ -34,9 +34,7 @@ import java.util.List; import java.util.Map; import java.util.Vector; -import sun.security.util.DerValue; -import sun.security.util.DerOutputStream; -import sun.security.util.ObjectIdentifier; +import sun.security.util.*; /** * This class defines the Extended Key Usage Extension, which @@ -94,24 +92,6 @@ implements CertAttrSet { public static final String NAME = "ExtendedKeyUsage"; public static final String USAGES = "usages"; - // OID defined in RFC 5280 Sections 4.2.1.12 - // more from http://www.alvestrand.no/objectid/1.3.6.1.5.5.7.3.html - private static final Map map = - new HashMap(); - - static { - map.put(ObjectIdentifier.of("2.5.29.37.0"), "anyExtendedKeyUsage"); - map.put(ObjectIdentifier.of("1.3.6.1.5.5.7.3.1"), "serverAuth"); - map.put(ObjectIdentifier.of("1.3.6.1.5.5.7.3.2"), "clientAuth"); - map.put(ObjectIdentifier.of("1.3.6.1.5.5.7.3.3"), "codeSigning"); - map.put(ObjectIdentifier.of("1.3.6.1.5.5.7.3.4"), "emailProtection"); - map.put(ObjectIdentifier.of("1.3.6.1.5.5.7.3.5"), "ipsecEndSystem"); - map.put(ObjectIdentifier.of("1.3.6.1.5.5.7.3.6"), "ipsecTunnel"); - map.put(ObjectIdentifier.of("1.3.6.1.5.5.7.3.7"), "ipsecUser"); - map.put(ObjectIdentifier.of("1.3.6.1.5.5.7.3.8"), "timeStamping"); - map.put(ObjectIdentifier.of("1.3.6.1.5.5.7.3.9"), "OCSPSigning"); - }; - /** * Vector of KeyUsages for this object. */ @@ -198,11 +178,12 @@ implements CertAttrSet { usage += "\n "; } - String result = map.get(oid); - if (result != null) { - usage += result; + String res = oid.toString(); + KnownOIDs os = KnownOIDs.findMatch(res); + if (os != null) { + usage += os.stdName(); } else { - usage += oid.toString(); + usage += res; } first = false; } diff --git a/src/java.base/share/classes/sun/security/x509/InhibitAnyPolicyExtension.java b/src/java.base/share/classes/sun/security/x509/InhibitAnyPolicyExtension.java index b21af10cc55..6fa2ae16729 100644 --- a/src/java.base/share/classes/sun/security/x509/InhibitAnyPolicyExtension.java +++ b/src/java.base/share/classes/sun/security/x509/InhibitAnyPolicyExtension.java @@ -29,10 +29,7 @@ import java.io.IOException; import java.io.OutputStream; import java.util.Enumeration; -import sun.security.util.Debug; -import sun.security.util.DerOutputStream; -import sun.security.util.DerValue; -import sun.security.util.ObjectIdentifier; +import sun.security.util.*; /** * This class represents the Inhibit Any-Policy Extension. @@ -76,7 +73,7 @@ implements CertAttrSet { * Object identifier for "any-policy" */ public static ObjectIdentifier AnyPolicy_Id = - ObjectIdentifier.of("2.5.29.32.0"); + ObjectIdentifier.of(KnownOIDs.CE_CERT_POLICIES_ANY); /** * Attribute names. diff --git a/src/java.base/share/classes/sun/security/x509/NetscapeCertTypeExtension.java b/src/java.base/share/classes/sun/security/x509/NetscapeCertTypeExtension.java index c5577bbf2ec..d455f00f8a8 100644 --- a/src/java.base/share/classes/sun/security/x509/NetscapeCertTypeExtension.java +++ b/src/java.base/share/classes/sun/security/x509/NetscapeCertTypeExtension.java @@ -73,7 +73,7 @@ implements CertAttrSet { * Object identifier for the Netscape-Cert-Type extension. */ public static ObjectIdentifier NetscapeCertType_Id = - ObjectIdentifier.of("2.16.840.1.113730.1.1"); + ObjectIdentifier.of(KnownOIDs.NETSCAPE_CertType); private boolean[] bitString; diff --git a/src/java.base/share/classes/sun/security/x509/OIDMap.java b/src/java.base/share/classes/sun/security/x509/OIDMap.java index 472de53e171..54a8d9146c8 100644 --- a/src/java.base/share/classes/sun/security/x509/OIDMap.java +++ b/src/java.base/share/classes/sun/security/x509/OIDMap.java @@ -136,7 +136,7 @@ public class OIDMap { addInternal(POLICY_CONSTRAINTS, PKIXExtensions.PolicyConstraints_Id, "sun.security.x509.PolicyConstraintsExtension"); addInternal(NETSCAPE_CERT, - ObjectIdentifier.of("2.16.840.1.113730.1.1"), + ObjectIdentifier.of(KnownOIDs.NETSCAPE_CertType), "sun.security.x509.NetscapeCertTypeExtension"); addInternal(CERT_POLICIES, PKIXExtensions.CertificatePolicies_Id, "sun.security.x509.CertificatePoliciesExtension"); @@ -227,7 +227,7 @@ public class OIDMap { throws CertificateException { ObjectIdentifier objId; try { - objId = new ObjectIdentifier(oid); + objId = ObjectIdentifier.of(oid); } catch (IOException ioe) { throw new CertificateException ("Invalid Object identifier: " + oid); diff --git a/src/java.base/share/classes/sun/security/x509/OIDName.java b/src/java.base/share/classes/sun/security/x509/OIDName.java index eda3426a985..648d7496435 100644 --- a/src/java.base/share/classes/sun/security/x509/OIDName.java +++ b/src/java.base/share/classes/sun/security/x509/OIDName.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 @@ -69,7 +69,7 @@ public class OIDName implements GeneralNameInterface { */ public OIDName(String name) throws IOException { try { - oid = new ObjectIdentifier(name); + oid = ObjectIdentifier.of(name); } catch (Exception e) { throw new IOException("Unable to create OIDName: " + e); } diff --git a/src/java.base/share/classes/sun/security/x509/PKIXExtensions.java b/src/java.base/share/classes/sun/security/x509/PKIXExtensions.java index af182f57663..754d3d0e726 100644 --- a/src/java.base/share/classes/sun/security/x509/PKIXExtensions.java +++ b/src/java.base/share/classes/sun/security/x509/PKIXExtensions.java @@ -51,112 +51,112 @@ public class PKIXExtensions { * Identifies the particular public key used to sign the certificate. */ public static final ObjectIdentifier AuthorityKey_Id = - ObjectIdentifier.of("2.5.29.35"); + ObjectIdentifier.of(KnownOIDs.AuthorityKeyID); /** * Identifies the particular public key used in an application. */ public static final ObjectIdentifier SubjectKey_Id = - ObjectIdentifier.of("2.5.29.14"); + ObjectIdentifier.of(KnownOIDs.SubjectKeyID); /** * Defines the purpose of the key contained in the certificate. */ public static final ObjectIdentifier KeyUsage_Id = - ObjectIdentifier.of("2.5.29.15"); + ObjectIdentifier.of(KnownOIDs.KeyUsage); /** * Allows the certificate issuer to specify a different validity period * for the private key than the certificate. */ public static final ObjectIdentifier PrivateKeyUsage_Id = - ObjectIdentifier.of("2.5.29.16"); + ObjectIdentifier.of(KnownOIDs.PrivateKeyUsage); /** * Contains the sequence of policy information terms. */ public static final ObjectIdentifier CertificatePolicies_Id = - ObjectIdentifier.of("2.5.29.32"); + ObjectIdentifier.of(KnownOIDs.CertificatePolicies); /** * Lists pairs of object identifiers of policies considered equivalent by * the issuing CA to the subject CA. */ public static final ObjectIdentifier PolicyMappings_Id = - ObjectIdentifier.of("2.5.29.33"); + ObjectIdentifier.of(KnownOIDs.PolicyMappings); /** * Allows additional identities to be bound to the subject of the * certificate. */ public static final ObjectIdentifier SubjectAlternativeName_Id = - ObjectIdentifier.of("2.5.29.17"); + ObjectIdentifier.of(KnownOIDs.SubjectAlternativeName); /** * Allows additional identities to be associated with the certificate * issuer. */ public static final ObjectIdentifier IssuerAlternativeName_Id = - ObjectIdentifier.of("2.5.29.18"); + ObjectIdentifier.of(KnownOIDs.IssuerAlternativeName); /** * Identifies additional directory attributes. * This extension is always non-critical. */ public static final ObjectIdentifier SubjectDirectoryAttributes_Id = - ObjectIdentifier.of("2.5.29.9"); + ObjectIdentifier.of(KnownOIDs.SubjectDirectoryAttributes); /** * Identifies whether the subject of the certificate is a CA and how deep * a certification path may exist through that CA. */ public static final ObjectIdentifier BasicConstraints_Id = - ObjectIdentifier.of("2.5.29.19"); + ObjectIdentifier.of(KnownOIDs.BasicConstraints); /** * Provides for permitted and excluded subtrees that place restrictions * on names that may be included within a certificate issued by a given CA. */ public static final ObjectIdentifier NameConstraints_Id = - ObjectIdentifier.of("2.5.29.30"); + ObjectIdentifier.of(KnownOIDs.NameConstraints); /** * Used to either prohibit policy mapping or limit the set of policies * that can be in subsequent certificates. */ public static final ObjectIdentifier PolicyConstraints_Id = - ObjectIdentifier.of("2.5.29.36"); + ObjectIdentifier.of(KnownOIDs.PolicyConstraints); /** * Identifies how CRL information is obtained. */ public static final ObjectIdentifier CRLDistributionPoints_Id = - ObjectIdentifier.of("2.5.29.31"); + ObjectIdentifier.of(KnownOIDs.CRLDistributionPoints); /** * Conveys a monotonically increasing sequence number for each CRL * issued by a given CA. */ public static final ObjectIdentifier CRLNumber_Id = - ObjectIdentifier.of("2.5.29.20"); + ObjectIdentifier.of(KnownOIDs.CRLNumber); /** * Identifies the CRL distribution point for a particular CRL. */ public static final ObjectIdentifier IssuingDistributionPoint_Id = - ObjectIdentifier.of("2.5.29.28"); + ObjectIdentifier.of(KnownOIDs.IssuingDistributionPoint); /** * Identifies the delta CRL. */ public static final ObjectIdentifier DeltaCRLIndicator_Id = - ObjectIdentifier.of("2.5.29.27"); + ObjectIdentifier.of(KnownOIDs.DeltaCRLIndicator); /** * Identifies the reason for the certificate revocation. */ public static final ObjectIdentifier ReasonCode_Id = - ObjectIdentifier.of("2.5.29.21"); + ObjectIdentifier.of(KnownOIDs.ReasonCode); /** * This extension provides a registered instruction identifier indicating @@ -164,34 +164,34 @@ public class PKIXExtensions { * placed on hold. */ public static final ObjectIdentifier HoldInstructionCode_Id = - ObjectIdentifier.of("2.5.29.23"); + ObjectIdentifier.of(KnownOIDs.HoldInstructionCode); /** * Identifies the date on which it is known or suspected that the private * key was compromised or that the certificate otherwise became invalid. */ public static final ObjectIdentifier InvalidityDate_Id = - ObjectIdentifier.of("2.5.29.24"); + ObjectIdentifier.of(KnownOIDs.InvalidityDate); /** * Identifies one or more purposes for which the certified public key * may be used, in addition to or in place of the basic purposes * indicated in the key usage extension field. */ public static final ObjectIdentifier ExtendedKeyUsage_Id = - ObjectIdentifier.of("2.5.29.37"); + ObjectIdentifier.of(KnownOIDs.extendedKeyUsage); /** * Specifies whether any-policy policy OID is permitted */ public static final ObjectIdentifier InhibitAnyPolicy_Id = - ObjectIdentifier.of("2.5.29.54"); + ObjectIdentifier.of(KnownOIDs.InhibitAnyPolicy); /** * Identifies the certificate issuer associated with an entry in an * indirect CRL. */ public static final ObjectIdentifier CertificateIssuer_Id = - ObjectIdentifier.of("2.5.29.29"); + ObjectIdentifier.of(KnownOIDs.CertificateIssuer); /** * This extension indicates how to access CA information and services for @@ -200,32 +200,32 @@ public class PKIXExtensions { * services. */ public static final ObjectIdentifier AuthInfoAccess_Id = - ObjectIdentifier.of("1.3.6.1.5.5.7.1.1"); + ObjectIdentifier.of(KnownOIDs.AuthInfoAccess); /** * This extension indicates how to access CA information and services for * the subject of the certificate in which the extension appears. */ public static final ObjectIdentifier SubjectInfoAccess_Id = - ObjectIdentifier.of("1.3.6.1.5.5.7.1.11"); + ObjectIdentifier.of(KnownOIDs.SubjectInfoAccess); /** * Identifies how delta CRL information is obtained. */ public static final ObjectIdentifier FreshestCRL_Id = - ObjectIdentifier.of("2.5.29.46"); + ObjectIdentifier.of(KnownOIDs.FreshestCRL); /** * Identifies the OCSP client can trust the responder for the * lifetime of the responder's certificate. */ public static final ObjectIdentifier OCSPNoCheck_Id = - ObjectIdentifier.of("1.3.6.1.5.5.7.48.1.5"); + ObjectIdentifier.of(KnownOIDs.OCSPNoCheck); /** * This extension is used to provide nonce data for OCSP requests * or responses. */ public static final ObjectIdentifier OCSPNonce_Id = - ObjectIdentifier.of("1.3.6.1.5.5.7.48.1.2"); + ObjectIdentifier.of(KnownOIDs.OCSPNonceExt); } diff --git a/src/java.base/share/classes/sun/security/x509/X500Name.java b/src/java.base/share/classes/sun/security/x509/X500Name.java index ed265524151..701ee40b31a 100644 --- a/src/java.base/share/classes/sun/security/x509/X500Name.java +++ b/src/java.base/share/classes/sun/security/x509/X500Name.java @@ -1105,80 +1105,80 @@ public class X500Name implements GeneralNameInterface, Principal { // OID for the "CN=" attribute, denoting a person's common name. public static final ObjectIdentifier commonName_oid = - ObjectIdentifier.of("2.5.4.3"); + ObjectIdentifier.of(KnownOIDs.CommonName); // OID for the "SURNAME=" attribute, denoting a person's surname. public static final ObjectIdentifier SURNAME_OID = - ObjectIdentifier.of("2.5.4.4"); + ObjectIdentifier.of(KnownOIDs.Surname); // OID for the "SERIALNUMBER=" attribute, denoting a serial number for. // a name. Do not confuse with PKCS#9 issuerAndSerialNumber or the // certificate serial number. public static final ObjectIdentifier SERIALNUMBER_OID = - ObjectIdentifier.of("2.5.4.5"); + ObjectIdentifier.of(KnownOIDs.SerialNumber); // OID for the "C=" attribute, denoting a country. public static final ObjectIdentifier countryName_oid = - ObjectIdentifier.of("2.5.4.6"); + ObjectIdentifier.of(KnownOIDs.CountryName); // OID for the "L=" attribute, denoting a locality (such as a city). public static final ObjectIdentifier localityName_oid = - ObjectIdentifier.of("2.5.4.7"); + ObjectIdentifier.of(KnownOIDs.LocalityName); // OID for the "S=" attribute, denoting a state (such as Delaware). public static final ObjectIdentifier stateName_oid = - ObjectIdentifier.of("2.5.4.8"); + ObjectIdentifier.of(KnownOIDs.StateName); // OID for the "STREET=" attribute, denoting a street address. public static final ObjectIdentifier streetAddress_oid = - ObjectIdentifier.of("2.5.4.9"); + ObjectIdentifier.of(KnownOIDs.StreetAddress); // OID for the "O=" attribute, denoting an organization name. public static final ObjectIdentifier orgName_oid = - ObjectIdentifier.of("2.5.4.10"); + ObjectIdentifier.of(KnownOIDs.OrgName); // OID for the "OU=" attribute, denoting an organizational unit name. public static final ObjectIdentifier orgUnitName_oid = - ObjectIdentifier.of("2.5.4.11"); + ObjectIdentifier.of(KnownOIDs.OrgUnitName); // OID for the "T=" attribute, denoting a person's title. public static final ObjectIdentifier title_oid = - ObjectIdentifier.of("2.5.4.12"); + ObjectIdentifier.of(KnownOIDs.Title); // OID for the "GIVENNAME=" attribute, denoting a person's given name. public static final ObjectIdentifier GIVENNAME_OID = - ObjectIdentifier.of("2.5.4.42"); + ObjectIdentifier.of(KnownOIDs.GivenName); // OID for the "INITIALS=" attribute, denoting a person's initials. public static final ObjectIdentifier INITIALS_OID = - ObjectIdentifier.of("2.5.4.43"); + ObjectIdentifier.of(KnownOIDs.Initials); // OID for the "GENERATION=" attribute, denoting Jr., II, etc. public static final ObjectIdentifier GENERATIONQUALIFIER_OID = - ObjectIdentifier.of("2.5.4.44"); + ObjectIdentifier.of(KnownOIDs.GenerationQualifier); // OID for the "DNQUALIFIER=" or "DNQ=" attribute, denoting DN // disambiguating information. public static final ObjectIdentifier DNQUALIFIER_OID = - ObjectIdentifier.of("2.5.4.46"); + ObjectIdentifier.of(KnownOIDs.DNQualifier); // OIDs from other sources which show up in X.500 names we // expect to deal with often. // // OID for "IP=" IP address attributes, used with SKIP. public static final ObjectIdentifier ipAddress_oid = - ObjectIdentifier.of("1.3.6.1.4.1.42.2.11.2.1"); + ObjectIdentifier.of(KnownOIDs.SkipIPAddress); // Domain component OID from RFC 1274, RFC 2247, RFC 5280. // // OID for "DC=" domain component attributes.used with DNSNames in DN // format. public static final ObjectIdentifier DOMAIN_COMPONENT_OID = - ObjectIdentifier.of("0.9.2342.19200300.100.1.25"); + ObjectIdentifier.of(KnownOIDs.UCL_DomainComponent); // OID for "UID=" denoting a user id, defined in RFCs 1274 & 2798. public static final ObjectIdentifier userid_oid = - ObjectIdentifier.of("0.9.2342.19200300.100.1.1"); + ObjectIdentifier.of(KnownOIDs.UCL_UserID); /** * Return constraint type:

    diff --git a/src/java.base/share/classes/sun/security/x509/X509CRLEntryImpl.java b/src/java.base/share/classes/sun/security/x509/X509CRLEntryImpl.java index 54e6016b740..aa6ef1ff348 100644 --- a/src/java.base/share/classes/sun/security/x509/X509CRLEntryImpl.java +++ b/src/java.base/share/classes/sun/security/x509/X509CRLEntryImpl.java @@ -252,7 +252,8 @@ public class X509CRLEntryImpl extends X509CRLEntry */ public static CRLReason getRevocationReason(X509CRLEntry crlEntry) { try { - byte[] ext = crlEntry.getExtensionValue("2.5.29.21"); + byte[] ext = crlEntry.getExtensionValue + (KnownOIDs.ReasonCode.value()); if (ext == null) { return null; } @@ -402,11 +403,11 @@ public class X509CRLEntryImpl extends X509CRLEntry if (extensions == null) return null; try { - String extAlias = OIDMap.getName(new ObjectIdentifier(oid)); + String extAlias = OIDMap.getName(ObjectIdentifier.of(oid)); Extension crlExt = null; if (extAlias == null) { // may be unknown - ObjectIdentifier findOID = new ObjectIdentifier(oid); + ObjectIdentifier findOID = ObjectIdentifier.of(oid); Extension ex = null; ObjectIdentifier inCertOID; for (Enumeration e = extensions.getElements(); diff --git a/src/java.base/share/classes/sun/security/x509/X509CRLImpl.java b/src/java.base/share/classes/sun/security/x509/X509CRLImpl.java index 6e50047f41e..da438f71890 100644 --- a/src/java.base/share/classes/sun/security/x509/X509CRLImpl.java +++ b/src/java.base/share/classes/sun/security/x509/X509CRLImpl.java @@ -1036,11 +1036,11 @@ public class X509CRLImpl extends X509CRL implements DerEncoder { if (extensions == null) return null; try { - String extAlias = OIDMap.getName(new ObjectIdentifier(oid)); + String extAlias = OIDMap.getName(ObjectIdentifier.of(oid)); Extension crlExt = null; if (extAlias == null) { // may be unknown - ObjectIdentifier findOID = new ObjectIdentifier(oid); + ObjectIdentifier findOID = ObjectIdentifier.of(oid); Extension ex = null; ObjectIdentifier inCertOID; for (Enumeration e = extensions.getElements(); diff --git a/src/java.base/share/classes/sun/security/x509/X509CertImpl.java b/src/java.base/share/classes/sun/security/x509/X509CertImpl.java index db6efdc3c4f..fd03ad392f0 100644 --- a/src/java.base/share/classes/sun/security/x509/X509CertImpl.java +++ b/src/java.base/share/classes/sun/security/x509/X509CertImpl.java @@ -128,14 +128,6 @@ public class X509CertImpl extends X509Certificate implements DerEncoder { protected AlgorithmId algId = null; protected byte[] signature = null; - // recognized extension OIDS - private static final String KEY_USAGE_OID = "2.5.29.15"; - private static final String EXTENDED_KEY_USAGE_OID = "2.5.29.37"; - private static final String BASIC_CONSTRAINT_OID = "2.5.29.19"; - private static final String SUBJECT_ALT_NAME_OID = "2.5.29.17"; - private static final String ISSUER_ALT_NAME_OID = "2.5.29.18"; - private static final String AUTH_INFO_ACCESS_OID = "1.3.6.1.5.5.7.1.1"; - // number of standard key usage bits. private static final int NUM_STANDARD_KEY_USAGE = 9; @@ -1423,7 +1415,7 @@ public class X509CertImpl extends X509Certificate implements DerEncoder { */ public byte[] getExtensionValue(String oid) { try { - ObjectIdentifier findOID = new ObjectIdentifier(oid); + ObjectIdentifier findOID = ObjectIdentifier.of(oid); String extAlias = OIDMap.getName(findOID); Extension certExt = null; CertificateExtensions exts = (CertificateExtensions)info.get( @@ -1526,7 +1518,8 @@ public class X509CertImpl extends X509Certificate implements DerEncoder { public static List getExtendedKeyUsage(X509Certificate cert) throws CertificateParsingException { try { - byte[] ext = cert.getExtensionValue(EXTENDED_KEY_USAGE_OID); + byte[] ext = cert.getExtensionValue + (KnownOIDs.extendedKeyUsage.value()); if (ext == null) return null; DerValue val = new DerValue(ext); @@ -1696,7 +1689,8 @@ public class X509CertImpl extends X509Certificate implements DerEncoder { public static Collection> getSubjectAlternativeNames(X509Certificate cert) throws CertificateParsingException { try { - byte[] ext = cert.getExtensionValue(SUBJECT_ALT_NAME_OID); + byte[] ext = cert.getExtensionValue + (KnownOIDs.SubjectAlternativeName.value()); if (ext == null) { return null; } @@ -1759,7 +1753,8 @@ public class X509CertImpl extends X509Certificate implements DerEncoder { public static Collection> getIssuerAlternativeNames(X509Certificate cert) throws CertificateParsingException { try { - byte[] ext = cert.getExtensionValue(ISSUER_ALT_NAME_OID); + byte[] ext = cert.getExtensionValue + (KnownOIDs.IssuerAlternativeName.value()); if (ext == null) { return null; } diff --git a/src/java.security.jgss/share/classes/org/ietf/jgss/Oid.java b/src/java.security.jgss/share/classes/org/ietf/jgss/Oid.java index 25a255faa2e..05794c7927e 100644 --- a/src/java.security.jgss/share/classes/org/ietf/jgss/Oid.java +++ b/src/java.security.jgss/share/classes/org/ietf/jgss/Oid.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2015, 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 @@ -65,7 +65,7 @@ public class Oid { public Oid(String strOid) throws GSSException { try { - oid = new ObjectIdentifier(strOid); + oid = ObjectIdentifier.of(strOid); derEncoding = null; } catch (Exception e) { throw new GSSException(GSSException.FAILURE, diff --git a/src/java.security.jgss/share/classes/sun/security/jgss/GSSContextImpl.java b/src/java.security.jgss/share/classes/sun/security/jgss/GSSContextImpl.java index 9521a33d6e3..e262b545b20 100644 --- a/src/java.security.jgss/share/classes/sun/security/jgss/GSSContextImpl.java +++ b/src/java.security.jgss/share/classes/sun/security/jgss/GSSContextImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2015, 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 @@ -241,7 +241,7 @@ public class GSSContextImpl implements GSSContext { mechCtxt.setChannelBinding(channelBindings); mechCtxt.requestDelegPolicy(reqDelegPolicyState); - objId = new ObjectIdentifier(mechOid.toString()); + objId = ObjectIdentifier.of(mechOid.toString()); currentState = IN_PROGRESS; firstToken = true; diff --git a/src/java.security.jgss/share/classes/sun/security/jgss/GSSNameImpl.java b/src/java.security.jgss/share/classes/sun/security/jgss/GSSNameImpl.java index 27028c770c7..ce7ab129359 100644 --- a/src/java.security.jgss/share/classes/sun/security/jgss/GSSNameImpl.java +++ b/src/java.security.jgss/share/classes/sun/security/jgss/GSSNameImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2019, 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 @@ -403,7 +403,7 @@ public class GSSNameImpl implements GSSName { ObjectIdentifier oid = null; try { - oid = new ObjectIdentifier + oid = ObjectIdentifier.of (mechElement.getMechanism().toString()); } catch (IOException e) { throw new GSSExceptionImpl(GSSException.FAILURE, diff --git a/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5Token.java b/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5Token.java index ef812dab831..72f98f73107 100644 --- a/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5Token.java +++ b/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5Token.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2006, 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 @@ -77,7 +77,7 @@ abstract class Krb5Token extends GSSToken { static { try { - OID = new ObjectIdentifier(Krb5MechFactory. + OID = ObjectIdentifier.of(Krb5MechFactory. GSS_KRB5_MECH_OID.toString()); } catch (IOException ioe) { // should not happen diff --git a/src/java.security.jgss/share/classes/sun/security/jgss/spnego/SpNegoToken.java b/src/java.security.jgss/share/classes/sun/security/jgss/spnego/SpNegoToken.java index 8683520227f..03ffcbe5cd0 100644 --- a/src/java.security.jgss/share/classes/sun/security/jgss/spnego/SpNegoToken.java +++ b/src/java.security.jgss/share/classes/sun/security/jgss/spnego/SpNegoToken.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, 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 @@ -68,7 +68,7 @@ abstract class SpNegoToken extends GSSToken { static { try { - OID = new ObjectIdentifier(SpNegoMechFactory. + OID = ObjectIdentifier.of(SpNegoMechFactory. GSS_SPNEGO_MECH_OID.toString()); } catch (IOException ioe) { // should not happen diff --git a/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/GSSNameElement.java b/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/GSSNameElement.java index d445d90f728..4a65ca68915 100644 --- a/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/GSSNameElement.java +++ b/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/GSSNameElement.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2019, 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 @@ -130,7 +130,7 @@ public class GSSNameElement implements GSSNameSpi { DerOutputStream dout = new DerOutputStream(); Oid mech = cStub.getMech(); try { - dout.putOID(new ObjectIdentifier(mech.toString())); + dout.putOID(ObjectIdentifier.of(mech.toString())); } catch (IOException e) { throw new GSSExceptionImpl(GSSException.FAILURE, e); } diff --git a/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/NativeGSSContext.java b/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/NativeGSSContext.java index da2df01e262..565f7c0917b 100644 --- a/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/NativeGSSContext.java +++ b/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/NativeGSSContext.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2019, 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 @@ -164,7 +164,7 @@ class NativeGSSContext implements GSSContextSpi { SunNativeProvider.debug("Precomputed mechToken length: " + mechTokenLen); GSSHeader gssHeader = new GSSHeader - (new ObjectIdentifier(cStub.getMech().toString()), + (ObjectIdentifier.of(cStub.getMech().toString()), mechTokenLen); ByteArrayOutputStream baos = new ByteArrayOutputStream(600); diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java index b00b738b85e..c4b41f7de6d 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, 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 @@ -45,6 +45,7 @@ import javax.security.auth.callback.TextOutputCallback; import sun.security.util.Debug; import sun.security.util.ResourcesMgr; import static sun.security.util.SecurityConstants.PROVIDER_VER; +import static sun.security.util.SecurityProviderConstants.getAliases; import sun.security.pkcs11.Secmod.*; @@ -405,19 +406,15 @@ public final class SunPKCS11 extends AuthProvider { return System.identityHashCode(this); } - private static String[] s(String ...aliases) { - return aliases; - } - private static final class Descriptor { final String type; final String algorithm; final String className; - final String[] aliases; + final List aliases; final int[] mechanisms; private Descriptor(String type, String algorithm, String className, - String[] aliases, int[] mechanisms) { + List aliases, int[] mechanisms) { this.type = type; this.algorithm = algorithm; this.className = className; @@ -460,10 +457,16 @@ public final class SunPKCS11 extends AuthProvider { } private static void d(String type, String algorithm, String className, - String[] aliases, int[] m) { + List aliases, int[] m) { register(new Descriptor(type, algorithm, className, aliases, m)); } + private static void dA(String type, String algorithm, String className, + int[] m) { + register(new Descriptor(type, algorithm, className, + getAliases(algorithm), m)); + } + private static void register(Descriptor d) { for (int i = 0; i < d.mechanisms.length; i++) { int m = d.mechanisms[i]; @@ -525,51 +528,37 @@ public final class SunPKCS11 extends AuthProvider { m(CKM_MD2)); d(MD, "MD5", P11Digest, m(CKM_MD5)); - d(MD, "SHA1", P11Digest, - s("SHA", "SHA-1", "1.3.14.3.2.26", "OID.1.3.14.3.2.26"), + dA(MD, "SHA-1", P11Digest, m(CKM_SHA_1)); - d(MD, "SHA-224", P11Digest, - s("2.16.840.1.101.3.4.2.4", "OID.2.16.840.1.101.3.4.2.4"), + dA(MD, "SHA-224", P11Digest, m(CKM_SHA224)); - d(MD, "SHA-256", P11Digest, - s("2.16.840.1.101.3.4.2.1", "OID.2.16.840.1.101.3.4.2.1"), + dA(MD, "SHA-256", P11Digest, m(CKM_SHA256)); - d(MD, "SHA-384", P11Digest, - s("2.16.840.1.101.3.4.2.2", "OID.2.16.840.1.101.3.4.2.2"), + dA(MD, "SHA-384", P11Digest, m(CKM_SHA384)); - d(MD, "SHA-512", P11Digest, - s("2.16.840.1.101.3.4.2.3", "OID.2.16.840.1.101.3.4.2.3"), + dA(MD, "SHA-512", P11Digest, m(CKM_SHA512)); - d(MD, "SHA-512/224", P11Digest, - s("2.16.840.1.101.3.4.2.5", "OID.2.16.840.1.101.3.4.2.5"), + dA(MD, "SHA-512/224", P11Digest, m(CKM_SHA512_224)); - d(MD, "SHA-512/256", P11Digest, - s("2.16.840.1.101.3.4.2.6", "OID.2.16.840.1.101.3.4.2.6"), + dA(MD, "SHA-512/256", P11Digest, m(CKM_SHA512_256)); d(MAC, "HmacMD5", P11MAC, m(CKM_MD5_HMAC)); - d(MAC, "HmacSHA1", P11MAC, - s("1.2.840.113549.2.7", "OID.1.2.840.113549.2.7"), + dA(MAC, "HmacSHA1", P11MAC, m(CKM_SHA_1_HMAC)); - d(MAC, "HmacSHA224", P11MAC, - s("1.2.840.113549.2.8", "OID.1.2.840.113549.2.8"), + dA(MAC, "HmacSHA224", P11MAC, m(CKM_SHA224_HMAC)); - d(MAC, "HmacSHA256", P11MAC, - s("1.2.840.113549.2.9", "OID.1.2.840.113549.2.9"), + dA(MAC, "HmacSHA256", P11MAC, m(CKM_SHA256_HMAC)); - d(MAC, "HmacSHA384", P11MAC, - s("1.2.840.113549.2.10", "OID.1.2.840.113549.2.10"), + dA(MAC, "HmacSHA384", P11MAC, m(CKM_SHA384_HMAC)); - d(MAC, "HmacSHA512", P11MAC, - s("1.2.840.113549.2.11", "OID.1.2.840.113549.2.11"), + dA(MAC, "HmacSHA512", P11MAC, m(CKM_SHA512_HMAC)); - d(MAC, "HmacSHA512/224", P11MAC, - s("1.2.840.113549.2.12", "OID.1.2.840.113549.2.12"), + dA(MAC, "HmacSHA512/224", P11MAC, m(CKM_SHA512_224_HMAC)); - d(MAC, "HmacSHA512/256", P11MAC, - s("1.2.840.113549.2.13", "OID.1.2.840.113549.2.13"), + dA(MAC, "HmacSHA512/256", P11MAC, m(CKM_SHA512_256_HMAC)); d(MAC, "SslMacMD5", P11MAC, @@ -578,18 +567,20 @@ public final class SunPKCS11 extends AuthProvider { m(CKM_SSL3_SHA1_MAC)); d(KPG, "RSA", P11KeyPairGenerator, - s("1.2.840.113549.1.1", "OID.1.2.840.113549.1.1"), + getAliases("PKCS1"), m(CKM_RSA_PKCS_KEY_PAIR_GEN)); - d(KPG, "DSA", P11KeyPairGenerator, - s("1.3.14.3.2.12", "1.2.840.10040.4.1", "OID.1.2.840.10040.4.1"), + List dhAlias = List.of("DiffieHellman"); + + dA(KPG, "DSA", P11KeyPairGenerator, m(CKM_DSA_KEY_PAIR_GEN)); - d(KPG, "DH", P11KeyPairGenerator, s("DiffieHellman"), + d(KPG, "DH", P11KeyPairGenerator, + dhAlias, m(CKM_DH_PKCS_KEY_PAIR_GEN)); d(KPG, "EC", P11KeyPairGenerator, m(CKM_EC_KEY_PAIR_GEN)); - d(KG, "ARCFOUR", P11KeyGenerator, s("RC4"), + dA(KG, "ARCFOUR", P11KeyGenerator, m(CKM_RC4_KEY_GEN)); d(KG, "DES", P11KeyGenerator, m(CKM_DES_KEY_GEN)); @@ -603,12 +594,12 @@ public final class SunPKCS11 extends AuthProvider { // register (Secret)KeyFactories if there are any mechanisms // for a particular algorithm that we support d(KF, "RSA", P11RSAKeyFactory, - s("1.2.840.113549.1.1", "OID.1.2.840.113549.1.1"), + getAliases("PKCS1"), m(CKM_RSA_PKCS_KEY_PAIR_GEN, CKM_RSA_PKCS, CKM_RSA_X_509)); - d(KF, "DSA", P11DSAKeyFactory, - s("1.3.14.3.2.12", "1.2.840.10040.4.1", "OID.1.2.840.10040.4.1"), + dA(KF, "DSA", P11DSAKeyFactory, m(CKM_DSA_KEY_PAIR_GEN, CKM_DSA, CKM_DSA_SHA1)); - d(KF, "DH", P11DHKeyFactory, s("DiffieHellman"), + d(KF, "DH", P11DHKeyFactory, + dhAlias, m(CKM_DH_PKCS_KEY_PAIR_GEN, CKM_DH_PKCS_DERIVE)); d(KF, "EC", P11DHKeyFactory, m(CKM_EC_KEY_PAIR_GEN, CKM_ECDH1_DERIVE, @@ -616,8 +607,7 @@ public final class SunPKCS11 extends AuthProvider { // AlgorithmParameters for EC. // Only needed until we have an EC implementation in the SUN provider. - d(AGP, "EC", "sun.security.util.ECParameters", - s("1.2.840.10045.2.1"), + dA(AGP, "EC", "sun.security.util.ECParameters", m(CKM_EC_KEY_PAIR_GEN, CKM_ECDH1_DERIVE, CKM_ECDSA, CKM_ECDSA_SHA1)); @@ -625,25 +615,25 @@ public final class SunPKCS11 extends AuthProvider { d(AGP, "GCM", "sun.security.util.GCMParameters", m(CKM_AES_GCM)); - d(KA, "DH", P11KeyAgreement, s("DiffieHellman"), + d(KA, "DH", P11KeyAgreement, + dhAlias, m(CKM_DH_PKCS_DERIVE)); d(KA, "ECDH", "sun.security.pkcs11.P11ECDHKeyAgreement", m(CKM_ECDH1_DERIVE)); - d(SKF, "ARCFOUR", P11SecretKeyFactory, s("RC4"), + dA(SKF, "ARCFOUR", P11SecretKeyFactory, m(CKM_RC4)); d(SKF, "DES", P11SecretKeyFactory, m(CKM_DES_CBC)); d(SKF, "DESede", P11SecretKeyFactory, m(CKM_DES3_CBC)); - d(SKF, "AES", P11SecretKeyFactory, - s("2.16.840.1.101.3.4.1", "OID.2.16.840.1.101.3.4.1"), + dA(SKF, "AES", P11SecretKeyFactory, m(CKM_AES_CBC)); d(SKF, "Blowfish", P11SecretKeyFactory, m(CKM_BLOWFISH_CBC)); // XXX attributes for Ciphers (supported modes, padding) - d(CIP, "ARCFOUR", P11Cipher, s("RC4"), + dA(CIP, "ARCFOUR", P11Cipher, m(CKM_RC4)); d(CIP, "DES/CBC/NoPadding", P11Cipher, m(CKM_DES_CBC)); @@ -651,7 +641,8 @@ public final class SunPKCS11 extends AuthProvider { m(CKM_DES_CBC_PAD, CKM_DES_CBC)); d(CIP, "DES/ECB/NoPadding", P11Cipher, m(CKM_DES_ECB)); - d(CIP, "DES/ECB/PKCS5Padding", P11Cipher, s("DES"), + d(CIP, "DES/ECB/PKCS5Padding", P11Cipher, + List.of("DES"), m(CKM_DES_ECB)); d(CIP, "DESede/CBC/NoPadding", P11Cipher, @@ -660,47 +651,40 @@ public final class SunPKCS11 extends AuthProvider { m(CKM_DES3_CBC_PAD, CKM_DES3_CBC)); d(CIP, "DESede/ECB/NoPadding", P11Cipher, m(CKM_DES3_ECB)); - d(CIP, "DESede/ECB/PKCS5Padding", P11Cipher, s("DESede"), + d(CIP, "DESede/ECB/PKCS5Padding", P11Cipher, + List.of("DESede"), m(CKM_DES3_ECB)); d(CIP, "AES/CBC/NoPadding", P11Cipher, m(CKM_AES_CBC)); - d(CIP, "AES_128/CBC/NoPadding", P11Cipher, - s("2.16.840.1.101.3.4.1.2", "OID.2.16.840.1.101.3.4.1.2"), + dA(CIP, "AES_128/CBC/NoPadding", P11Cipher, m(CKM_AES_CBC)); - d(CIP, "AES_192/CBC/NoPadding", P11Cipher, - s("2.16.840.1.101.3.4.1.22", "OID.2.16.840.1.101.3.4.1.22"), + dA(CIP, "AES_192/CBC/NoPadding", P11Cipher, m(CKM_AES_CBC)); - d(CIP, "AES_256/CBC/NoPadding", P11Cipher, - s("2.16.840.1.101.3.4.1.42", "OID.2.16.840.1.101.3.4.1.42"), + dA(CIP, "AES_256/CBC/NoPadding", P11Cipher, m(CKM_AES_CBC)); d(CIP, "AES/CBC/PKCS5Padding", P11Cipher, m(CKM_AES_CBC_PAD, CKM_AES_CBC)); d(CIP, "AES/ECB/NoPadding", P11Cipher, m(CKM_AES_ECB)); - d(CIP, "AES_128/ECB/NoPadding", P11Cipher, - s("2.16.840.1.101.3.4.1.1", "OID.2.16.840.1.101.3.4.1.1"), + dA(CIP, "AES_128/ECB/NoPadding", P11Cipher, m(CKM_AES_ECB)); - d(CIP, "AES_192/ECB/NoPadding", P11Cipher, - s("2.16.840.1.101.3.4.1.21", "OID.2.16.840.1.101.3.4.1.21"), + dA(CIP, "AES_192/ECB/NoPadding", P11Cipher, m(CKM_AES_ECB)); - d(CIP, "AES_256/ECB/NoPadding", P11Cipher, - s("2.16.840.1.101.3.4.1.41", "OID.2.16.840.1.101.3.4.1.41"), + dA(CIP, "AES_256/ECB/NoPadding", P11Cipher, m(CKM_AES_ECB)); - d(CIP, "AES/ECB/PKCS5Padding", P11Cipher, s("AES"), + d(CIP, "AES/ECB/PKCS5Padding", P11Cipher, + List.of("AES"), m(CKM_AES_ECB)); d(CIP, "AES/CTR/NoPadding", P11Cipher, m(CKM_AES_CTR)); d(CIP, "AES/GCM/NoPadding", P11AEADCipher, m(CKM_AES_GCM)); - d(CIP, "AES_128/GCM/NoPadding", P11AEADCipher, - s("2.16.840.1.101.3.4.1.6", "OID.2.16.840.1.101.3.4.1.6"), + dA(CIP, "AES_128/GCM/NoPadding", P11AEADCipher, m(CKM_AES_GCM)); - d(CIP, "AES_192/GCM/NoPadding", P11AEADCipher, - s("2.16.840.1.101.3.4.1.26", "OID.2.16.840.1.101.3.4.1.26"), + dA(CIP, "AES_192/GCM/NoPadding", P11AEADCipher, m(CKM_AES_GCM)); - d(CIP, "AES_256/GCM/NoPadding", P11AEADCipher, - s("2.16.840.1.101.3.4.1.46", "OID.2.16.840.1.101.3.4.1.46"), + dA(CIP, "AES_256/GCM/NoPadding", P11AEADCipher, m(CKM_AES_GCM)); d(CIP, "Blowfish/CBC/NoPadding", P11Cipher, @@ -708,52 +692,43 @@ public final class SunPKCS11 extends AuthProvider { d(CIP, "Blowfish/CBC/PKCS5Padding", P11Cipher, m(CKM_BLOWFISH_CBC)); - d(CIP, "RSA/ECB/PKCS1Padding", P11RSACipher, s("RSA"), + d(CIP, "RSA/ECB/PKCS1Padding", P11RSACipher, + List.of("RSA"), m(CKM_RSA_PKCS)); d(CIP, "RSA/ECB/NoPadding", P11RSACipher, m(CKM_RSA_X_509)); - d(SIG, "RawDSA", P11Signature, s("NONEwithDSA"), + d(SIG, "RawDSA", P11Signature, + List.of("NONEwithDSA"), m(CKM_DSA)); - d(SIG, "DSA", P11Signature, - s("SHA1withDSA", "1.3.14.3.2.13", "1.3.14.3.2.27", - "1.2.840.10040.4.3", "OID.1.2.840.10040.4.3"), + dA(SIG, "SHA1withDSA", P11Signature, m(CKM_DSA_SHA1, CKM_DSA)); - d(SIG, "SHA224withDSA", P11Signature, - s("2.16.840.1.101.3.4.3.1", "OID.2.16.840.1.101.3.4.3.1"), + dA(SIG, "SHA224withDSA", P11Signature, m(CKM_DSA_SHA224)); - d(SIG, "SHA256withDSA", P11Signature, - s("2.16.840.1.101.3.4.3.2", "OID.2.16.840.1.101.3.4.3.2"), + dA(SIG, "SHA256withDSA", P11Signature, m(CKM_DSA_SHA256)); - d(SIG, "SHA384withDSA", P11Signature, - s("2.16.840.1.101.3.4.3.3", "OID.2.16.840.1.101.3.4.3.3"), + dA(SIG, "SHA384withDSA", P11Signature, m(CKM_DSA_SHA384)); - d(SIG, "SHA512withDSA", P11Signature, - s("2.16.840.1.101.3.4.3.4", "OID.2.16.840.1.101.3.4.3.4"), + dA(SIG, "SHA512withDSA", P11Signature, m(CKM_DSA_SHA512)); d(SIG, "RawDSAinP1363Format", P11Signature, - s("NONEwithDSAinP1363Format"), + List.of("NONEwithDSAinP1363Format"), m(CKM_DSA)); d(SIG, "DSAinP1363Format", P11Signature, - s("SHA1withDSAinP1363Format"), + List.of("SHA1withDSAinP1363Format"), m(CKM_DSA_SHA1, CKM_DSA)); d(SIG, "NONEwithECDSA", P11Signature, m(CKM_ECDSA)); - d(SIG, "SHA1withECDSA", P11Signature, - s("ECDSA", "1.2.840.10045.4.1", "OID.1.2.840.10045.4.1"), + dA(SIG, "SHA1withECDSA", P11Signature, m(CKM_ECDSA_SHA1, CKM_ECDSA)); - d(SIG, "SHA224withECDSA", P11Signature, - s("1.2.840.10045.4.3.1", "OID.1.2.840.10045.4.3.1"), + dA(SIG, "SHA224withECDSA", P11Signature, m(CKM_ECDSA)); - d(SIG, "SHA256withECDSA", P11Signature, - s("1.2.840.10045.4.3.2", "OID.1.2.840.10045.4.3.2"), + dA(SIG, "SHA256withECDSA", P11Signature, m(CKM_ECDSA)); - d(SIG, "SHA384withECDSA", P11Signature, - s("1.2.840.10045.4.3.3", "OID.1.2.840.10045.4.3.3"), + dA(SIG, "SHA384withECDSA", P11Signature, m(CKM_ECDSA)); - d(SIG, "SHA512withECDSA", P11Signature, - s("1.2.840.10045.4.3.4", "OID.1.2.840.10045.4.3.4"), + dA(SIG, "SHA512withECDSA", P11Signature, m(CKM_ECDSA)); d(SIG, "NONEwithECDSAinP1363Format", P11Signature, m(CKM_ECDSA)); @@ -767,30 +742,21 @@ public final class SunPKCS11 extends AuthProvider { m(CKM_ECDSA)); d(SIG, "SHA512withECDSAinP1363Format", P11Signature, m(CKM_ECDSA)); - d(SIG, "MD2withRSA", P11Signature, - s("1.2.840.113549.1.1.2", "OID.1.2.840.113549.1.1.2"), + dA(SIG, "MD2withRSA", P11Signature, m(CKM_MD2_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509)); - d(SIG, "MD5withRSA", P11Signature, - s("1.2.840.113549.1.1.4", "OID.1.2.840.113549.1.1.4"), + dA(SIG, "MD5withRSA", P11Signature, m(CKM_MD5_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509)); - d(SIG, "SHA1withRSA", P11Signature, - s("1.2.840.113549.1.1.5", "OID.1.2.840.113549.1.1.5", - "1.3.14.3.2.29"), + dA(SIG, "SHA1withRSA", P11Signature, m(CKM_SHA1_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509)); - d(SIG, "SHA224withRSA", P11Signature, - s("1.2.840.113549.1.1.14", "OID.1.2.840.113549.1.1.14"), + dA(SIG, "SHA224withRSA", P11Signature, m(CKM_SHA224_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509)); - d(SIG, "SHA256withRSA", P11Signature, - s("1.2.840.113549.1.1.11", "OID.1.2.840.113549.1.1.11"), + dA(SIG, "SHA256withRSA", P11Signature, m(CKM_SHA256_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509)); - d(SIG, "SHA384withRSA", P11Signature, - s("1.2.840.113549.1.1.12", "OID.1.2.840.113549.1.1.12"), + dA(SIG, "SHA384withRSA", P11Signature, m(CKM_SHA384_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509)); - d(SIG, "SHA512withRSA", P11Signature, - s("1.2.840.113549.1.1.13", "OID.1.2.840.113549.1.1.13"), + dA(SIG, "SHA512withRSA", P11Signature, m(CKM_SHA512_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509)); - d(SIG, "RSASSA-PSS", P11PSSSignature, - s("1.2.840.113549.1.1.10", "OID.1.2.840.113549.1.1.10"), + dA(SIG, "RSASSA-PSS", P11PSSSignature, m(CKM_RSA_PKCS_PSS)); d(SIG, "SHA1withRSASSA-PSS", P11PSSSignature, m(CKM_SHA1_RSA_PKCS_PSS)); @@ -805,7 +771,7 @@ public final class SunPKCS11 extends AuthProvider { d(KG, "SunTlsRsaPremasterSecret", "sun.security.pkcs11.P11TlsRsaPremasterSecretGenerator", - s("SunTls12RsaPremasterSecret"), + List.of("SunTls12RsaPremasterSecret"), m(CKM_SSL3_PRE_MASTER_KEY_GEN, CKM_TLS_PRE_MASTER_KEY_GEN)); d(KG, "SunTlsMasterSecret", "sun.security.pkcs11.P11TlsMasterSecretGenerator", @@ -1048,7 +1014,7 @@ public final class SunPKCS11 extends AuthProvider { if (config.isEnabled(PCKM_KEYSTORE)) { putService(new P11Service(token, KS, "PKCS11", "sun.security.pkcs11.P11KeyStore", - s("PKCS11-" + config.getName()), + List.of("PKCS11-" + config.getName()), PCKM_KEYSTORE)); } return null; @@ -1065,17 +1031,13 @@ public final class SunPKCS11 extends AuthProvider { private final long mechanism; P11Service(Token token, String type, String algorithm, - String className, String[] al, long mechanism) { - super(token.provider, type, algorithm, className, toList(al), + String className, List al, long mechanism) { + super(token.provider, type, algorithm, className, al, type.equals(SR) ? Map.of("ThreadSafe", "true") : null); this.token = token; this.mechanism = mechanism & 0xFFFFFFFFL; } - private static List toList(String[] aliases) { - return (aliases == null) ? null : Arrays.asList(aliases); - } - public Object newInstance(Object param) throws NoSuchAlgorithmException { if (token.isValid() == false) { diff --git a/src/jdk.crypto.ec/share/classes/sun/security/ec/SunEC.java b/src/jdk.crypto.ec/share/classes/sun/security/ec/SunEC.java index e34517c9c2a..d84ffaa815c 100644 --- a/src/jdk.crypto.ec/share/classes/sun/security/ec/SunEC.java +++ b/src/jdk.crypto.ec/share/classes/sun/security/ec/SunEC.java @@ -31,12 +31,10 @@ import java.security.NoSuchAlgorithmException; import java.security.PrivilegedAction; import java.security.Provider; import java.security.ProviderException; -import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; -import java.util.regex.Pattern; import sun.security.ec.ed.EdDSAAlgorithmParameters; import sun.security.ec.ed.EdDSAKeyFactory; @@ -46,6 +44,7 @@ import sun.security.util.CurveDB; import sun.security.util.NamedCurve; import static sun.security.util.SecurityConstants.PROVIDER_VER; +import static sun.security.util.SecurityProviderConstants.*; /** * Provider class for the Elliptic Curve provider. @@ -97,6 +96,13 @@ public final class SunEC extends Provider { return SunEC.disableNative; } + private static class ProviderServiceA extends ProviderService { + ProviderServiceA(Provider p, String type, String algo, String cn, + HashMap attrs) { + super(p, type, algo, cn, getAliases(algo), attrs); + } + } + private static class ProviderService extends Provider.Service { ProviderService(Provider p, String type, String algo, String cn) { @@ -104,9 +110,8 @@ public final class SunEC extends Provider { } ProviderService(Provider p, String type, String algo, String cn, - String[] aliases, HashMap attrs) { - super(p, type, algo, cn, - (aliases == null? null : Arrays.asList(aliases)), attrs); + List aliases, HashMap attrs) { + super(p, type, algo, cn, aliases, attrs); } @Override @@ -232,7 +237,7 @@ public final class SunEC extends Provider { */ putService(new ProviderService(this, "KeyFactory", "EC", "sun.security.ec.ECKeyFactory", - new String[] { "EllipticCurve" }, ATTRS)); + List.of("EllipticCurve"), ATTRS)); /* * Algorithm Parameter engine @@ -240,7 +245,6 @@ public final class SunEC extends Provider { // "AlgorithmParameters.EC SupportedCurves" prop used by unit test boolean firstCurve = true; StringBuilder names = new StringBuilder(); - Pattern nameSplitPattern = Pattern.compile(CurveDB.SPLIT_PATTERN); Collection supportedCurves; if (SunEC.isNativeDisabled()) { @@ -260,10 +264,9 @@ public final class SunEC extends Provider { } names.append("["); - - String[] commonNames = nameSplitPattern.split(namedCurve.getName()); + String[] commonNames = namedCurve.getNameAndAliases(); for (String commonName : commonNames) { - names.append(commonName.trim()); + names.append(commonName); names.append(","); } @@ -274,10 +277,8 @@ public final class SunEC extends Provider { HashMap apAttrs = new HashMap<>(ATTRS); apAttrs.put("SupportedCurves", names.toString()); - putService(new ProviderService(this, "AlgorithmParameters", - "EC", "sun.security.util.ECParameters", - new String[] { "EllipticCurve", "1.2.840.10045.2.1", "OID.1.2.840.10045.2.1" }, - apAttrs)); + putService(new ProviderServiceA(this, "AlgorithmParameters", + "EC", "sun.security.util.ECParameters", apAttrs)); putXDHEntries(); putEdDSAEntries(); @@ -288,25 +289,20 @@ public final class SunEC extends Provider { putService(new ProviderService(this, "Signature", "NONEwithECDSA", "sun.security.ec.ECDSASignature$Raw", null, ATTRS)); - putService(new ProviderService(this, "Signature", + putService(new ProviderServiceA(this, "Signature", "SHA1withECDSA", "sun.security.ec.ECDSASignature$SHA1", - new String[] { "1.2.840.10045.4.1", "OID.1.2.840.10045.4.1" }, ATTRS)); - putService(new ProviderService(this, "Signature", + putService(new ProviderServiceA(this, "Signature", "SHA224withECDSA", "sun.security.ec.ECDSASignature$SHA224", - new String[] { "1.2.840.10045.4.3.1", "OID.1.2.840.10045.4.3.1"}, ATTRS)); - putService(new ProviderService(this, "Signature", + putService(new ProviderServiceA(this, "Signature", "SHA256withECDSA", "sun.security.ec.ECDSASignature$SHA256", - new String[] { "1.2.840.10045.4.3.2", "OID.1.2.840.10045.4.3.2"}, ATTRS)); - putService(new ProviderService(this, "Signature", + putService(new ProviderServiceA(this, "Signature", "SHA384withECDSA", "sun.security.ec.ECDSASignature$SHA384", - new String[] { "1.2.840.10045.4.3.3", "OID.1.2.840.10045.4.3.3" }, ATTRS)); - putService(new ProviderService(this, "Signature", + putService(new ProviderServiceA(this, "Signature", "SHA512withECDSA", "sun.security.ec.ECDSASignature$SHA512", - new String[] { "1.2.840.10045.4.3.4", "OID.1.2.840.10045.4.3.4" }, ATTRS)); putService(new ProviderService(this, "Signature", @@ -333,7 +329,7 @@ public final class SunEC extends Provider { */ putService(new ProviderService(this, "KeyPairGenerator", "EC", "sun.security.ec.ECKeyPairGenerator", - new String[] { "EllipticCurve" }, ATTRS)); + List.of("EllipticCurve"), ATTRS)); /* * Key Agreement engine @@ -350,31 +346,30 @@ public final class SunEC extends Provider { /* XDH does not require native implementation */ putService(new ProviderService(this, "KeyFactory", "XDH", "sun.security.ec.XDHKeyFactory", null, ATTRS)); - putService(new ProviderService(this, "KeyFactory", + putService(new ProviderServiceA(this, "KeyFactory", "X25519", "sun.security.ec.XDHKeyFactory.X25519", - new String[]{"1.3.101.110", "OID.1.3.101.110"}, ATTRS)); - putService(new ProviderService(this, "KeyFactory", + ATTRS)); + putService(new ProviderServiceA(this, "KeyFactory", "X448", "sun.security.ec.XDHKeyFactory.X448", - new String[]{"1.3.101.111", "OID.1.3.101.111"}, ATTRS)); + ATTRS)); putService(new ProviderService(this, "KeyPairGenerator", "XDH", "sun.security.ec.XDHKeyPairGenerator", null, ATTRS)); - putService(new ProviderService(this, "KeyPairGenerator", + putService(new ProviderServiceA(this, "KeyPairGenerator", "X25519", "sun.security.ec.XDHKeyPairGenerator.X25519", - new String[]{"1.3.101.110", "OID.1.3.101.110"}, ATTRS)); - putService(new ProviderService(this, "KeyPairGenerator", + ATTRS)); + putService(new ProviderServiceA(this, "KeyPairGenerator", "X448", "sun.security.ec.XDHKeyPairGenerator.X448", - new String[]{"1.3.101.111", "OID.1.3.101.111"}, ATTRS)); + ATTRS)); putService(new ProviderService(this, "KeyAgreement", "XDH", "sun.security.ec.XDHKeyAgreement", null, ATTRS)); - putService(new ProviderService(this, "KeyAgreement", + putService(new ProviderServiceA(this, "KeyAgreement", "X25519", "sun.security.ec.XDHKeyAgreement.X25519", - new String[]{"1.3.101.110", "OID.1.3.101.110"}, ATTRS)); - putService(new ProviderService(this, "KeyAgreement", + ATTRS)); + putService(new ProviderServiceA(this, "KeyAgreement", "X448", "sun.security.ec.XDHKeyAgreement.X448", - new String[]{"1.3.101.111", "OID.1.3.101.111"}, ATTRS)); - + ATTRS)); } private void putEdDSAEntries() { @@ -385,30 +380,26 @@ public final class SunEC extends Provider { /* EdDSA does not require native implementation */ putService(new ProviderService(this, "KeyFactory", "EdDSA", "sun.security.ec.ed.EdDSAKeyFactory", null, ATTRS)); - putService(new ProviderService(this, "KeyFactory", - "Ed25519", "sun.security.ec.ed.EdDSAKeyFactory.Ed25519", - new String[]{"1.3.101.112", "OID.1.3.101.112"}, ATTRS)); - putService(new ProviderService(this, "KeyFactory", - "Ed448", "sun.security.ec.ed.EdDSAKeyFactory.Ed448", - new String[]{"1.3.101.113", "OID.1.3.101.113"}, ATTRS)); + putService(new ProviderServiceA(this, "KeyFactory", + "Ed25519", "sun.security.ec.ed.EdDSAKeyFactory.Ed25519", ATTRS)); + putService(new ProviderServiceA(this, "KeyFactory", + "Ed448", "sun.security.ec.ed.EdDSAKeyFactory.Ed448", ATTRS)); putService(new ProviderService(this, "KeyPairGenerator", "EdDSA", "sun.security.ec.ed.EdDSAKeyPairGenerator", null, ATTRS)); - putService(new ProviderService(this, "KeyPairGenerator", + putService(new ProviderServiceA(this, "KeyPairGenerator", "Ed25519", "sun.security.ec.ed.EdDSAKeyPairGenerator.Ed25519", - new String[]{"1.3.101.112", "OID.1.3.101.112"}, ATTRS)); - putService(new ProviderService(this, "KeyPairGenerator", + ATTRS)); + putService(new ProviderServiceA(this, "KeyPairGenerator", "Ed448", "sun.security.ec.ed.EdDSAKeyPairGenerator.Ed448", - new String[]{"1.3.101.113", "OID.1.3.101.113"}, ATTRS)); + ATTRS)); putService(new ProviderService(this, "Signature", "EdDSA", "sun.security.ec.ed.EdDSASignature", null, ATTRS)); - putService(new ProviderService(this, "Signature", - "Ed25519", "sun.security.ec.ed.EdDSASignature.Ed25519", - new String[]{"1.3.101.112", "OID.1.3.101.112"}, ATTRS)); - putService(new ProviderService(this, "Signature", - "Ed448", "sun.security.ec.ed.EdDSASignature.Ed448", - new String[]{"1.3.101.113", "OID.1.3.101.113"}, ATTRS)); + putService(new ProviderServiceA(this, "Signature", + "Ed25519", "sun.security.ec.ed.EdDSASignature.Ed25519", ATTRS)); + putService(new ProviderServiceA(this, "Signature", + "Ed448", "sun.security.ec.ed.EdDSASignature.Ed448", ATTRS)); } } diff --git a/src/jdk.crypto.ec/share/classes/sun/security/ec/XECParameters.java b/src/jdk.crypto.ec/share/classes/sun/security/ec/XECParameters.java index b926aaa0064..4ea6b3e97e6 100644 --- a/src/jdk.crypto.ec/share/classes/sun/security/ec/XECParameters.java +++ b/src/jdk.crypto.ec/share/classes/sun/security/ec/XECParameters.java @@ -144,7 +144,7 @@ public class XECParameters { Map byOid, Map byName) throws IOException { - ObjectIdentifier oid = new ObjectIdentifier(objectId); + ObjectIdentifier oid = ObjectIdentifier.of(objectId); XECParameters params = new XECParameters(bits, p, a24, basePoint, logCofactor, oid, name); namedParams.put(name.toLowerCase(), oid, bits, params); diff --git a/src/jdk.crypto.ec/share/classes/sun/security/ec/ed/EdDSAParameters.java b/src/jdk.crypto.ec/share/classes/sun/security/ec/ed/EdDSAParameters.java index a1c5733af75..f9db1a0d0f5 100644 --- a/src/jdk.crypto.ec/share/classes/sun/security/ec/ed/EdDSAParameters.java +++ b/src/jdk.crypto.ec/share/classes/sun/security/ec/ed/EdDSAParameters.java @@ -27,6 +27,7 @@ package sun.security.ec.ed; import sun.security.ec.ParametersMap; import sun.security.provider.SHAKE256; import sun.security.util.ObjectIdentifier; +import sun.security.util.KnownOIDs; import sun.security.util.math.*; import sun.security.util.math.intpoly.*; import sun.security.x509.AlgorithmId; @@ -250,58 +251,47 @@ public class EdDSAParameters { static { // set up Ed25519 - try { - IntegerFieldModuloP ed25519Field = new IntegerPolynomial25519(); - IntegerFieldModuloP ed25519OrderField = new Curve25519OrderField(); - BigInteger biD = new BigInteger("3709570593466943934313808350875" + + IntegerFieldModuloP ed25519Field = new IntegerPolynomial25519(); + IntegerFieldModuloP ed25519OrderField = new Curve25519OrderField(); + BigInteger biD = new BigInteger("3709570593466943934313808350875" + "4565189542113879843219016388785533085940283555"); - ImmutableIntegerModuloP d = ed25519Field.getElement(biD); - BigInteger baseX = new BigInteger("15112221349535400772501151409" + + ImmutableIntegerModuloP d = ed25519Field.getElement(biD); + BigInteger baseX = new BigInteger("15112221349535400772501151409" + "588531511454012693041857206046113283949847762202"); - BigInteger baseY = new BigInteger("46316835694926478169428394003" + + BigInteger baseY = new BigInteger("46316835694926478169428394003" + "475163141307993866256225615783033603165251855960"); - EdECOperations edOps = new Ed25519Operations(d, baseX, baseY); - String name = NamedParameterSpec.ED25519.getName(); - ObjectIdentifier oid = new ObjectIdentifier("1.3.101.112"); - int bits = 255; - DigesterFactory digester = new SHA512DigesterFactory(); - EdDSAParameters params = new EdDSAParameters(name, oid, + EdECOperations edOps = new Ed25519Operations(d, baseX, baseY); + String name = NamedParameterSpec.ED25519.getName(); + ObjectIdentifier oid = ObjectIdentifier.of(KnownOIDs.Ed25519); + int bits = 255; + DigesterFactory digester = new SHA512DigesterFactory(); + EdDSAParameters params = new EdDSAParameters(name, oid, ed25519Field, ed25519OrderField, d, edOps, digester, EdDSAParameters::dom2, 32, bits, 3); - namedParams.put(name, oid, bits, params); - - } catch (IOException ex) { - // Unable to set Ed25519 parameters---it will be disabled - } + namedParams.put(name, oid, bits, params); // set up Ed448 - try { - IntegerFieldModuloP ed448Field = new IntegerPolynomial448(); - IntegerFieldModuloP ed448OrderField = new Curve448OrderField(); - BigInteger biD = ed448Field.getSize().subtract( - new BigInteger("39081")); - ImmutableIntegerModuloP d = ed448Field.getElement(biD); - BigInteger baseX = new BigInteger("224580040295924300187604334" + + IntegerFieldModuloP ed448Field = new IntegerPolynomial448(); + IntegerFieldModuloP ed448OrderField = new Curve448OrderField(); + biD = ed448Field.getSize().subtract(new BigInteger("39081")); + d = ed448Field.getElement(biD); + baseX = new BigInteger("224580040295924300187604334" + "099896036246789641632564134246125461686950415467406032909" + "029192869357953282578032075146446173674602635247710"); - BigInteger baseY = new BigInteger("298819210078481492676017930" + + baseY = new BigInteger("298819210078481492676017930" + "443930673437544040154080242095928241372331506189835876003" + "536878655418784733982303233503462500531545062832660"); - EdECOperations edOps = new Ed448Operations(d, baseX, baseY); - String name = NamedParameterSpec.ED448.getName(); - ObjectIdentifier oid = new ObjectIdentifier("1.3.101.113"); - int bits = 448; - DigesterFactory digester = new SHAKE256DigesterFactory(); - EdDSAParameters params = new EdDSAParameters(name, oid, + edOps = new Ed448Operations(d, baseX, baseY); + name = NamedParameterSpec.ED448.getName(); + oid = ObjectIdentifier.of(KnownOIDs.Ed448); + bits = 448; + digester = new SHAKE256DigesterFactory(); + params = new EdDSAParameters(name, oid, ed448Field, ed448OrderField, d, edOps, digester, EdDSAParameters::dom4, 57, bits, 2); - namedParams.put(name, oid, bits, params); - - } catch (IOException ex) { - // Unable to set Ed448 parameters---it will be disabled - } + namedParams.put(name, oid, bits, params); namedParams.fix(); } diff --git a/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/SunMSCAPI.java b/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/SunMSCAPI.java index 4351d3105aa..b110f50ac07 100644 --- a/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/SunMSCAPI.java +++ b/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/SunMSCAPI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2018, 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 @@ -32,9 +32,10 @@ import java.security.NoSuchAlgorithmException; import java.security.InvalidParameterException; import java.security.ProviderException; import java.util.HashMap; -import java.util.Arrays; +import java.util.List; import static sun.security.util.SecurityConstants.PROVIDER_VER; +import static sun.security.util.SecurityProviderConstants.getAliases; /** * A Cryptographic Service Provider for the Microsoft Crypto API. @@ -56,16 +57,21 @@ public final class SunMSCAPI extends Provider { } }); } + private static class ProviderServiceA extends ProviderService { + ProviderServiceA(Provider p, String type, String algo, String cn, + HashMap attrs) { + super(p, type, algo, cn, getAliases(algo), attrs); + } + } - private static final class ProviderService extends Provider.Service { + private static class ProviderService extends Provider.Service { ProviderService(Provider p, String type, String algo, String cn) { super(p, type, algo, cn, null, null); } ProviderService(Provider p, String type, String algo, String cn, - String[] aliases, HashMap attrs) { - super(p, type, algo, cn, - (aliases == null? null : Arrays.asList(aliases)), attrs); + List aliases, HashMap attrs) { + super(p, type, algo, cn, aliases, attrs); } @Override @@ -176,48 +182,47 @@ public final class SunMSCAPI extends Provider { putService(new ProviderService(p, "Signature", "SHA1withRSA", "sun.security.mscapi.CSignature$SHA1withRSA", null, attrs)); - putService(new ProviderService(p, "Signature", - "SHA256withRSA", "sun.security.mscapi.CSignature$SHA256withRSA", - new String[] { "1.2.840.113549.1.1.11", "OID.1.2.840.113549.1.1.11" }, + putService(new ProviderServiceA(p, "Signature", + "SHA256withRSA", + "sun.security.mscapi.CSignature$SHA256withRSA", attrs)); - putService(new ProviderService(p, "Signature", - "SHA384withRSA", "sun.security.mscapi.CSignature$SHA384withRSA", - new String[] { "1.2.840.113549.1.1.12", "OID.1.2.840.113549.1.1.12" }, + putService(new ProviderServiceA(p, "Signature", + "SHA384withRSA", + "sun.security.mscapi.CSignature$SHA384withRSA", attrs)); - putService(new ProviderService(p, "Signature", - "SHA512withRSA", "sun.security.mscapi.CSignature$SHA512withRSA", - new String[] { "1.2.840.113549.1.1.13", "OID.1.2.840.113549.1.1.13" }, + putService(new ProviderServiceA(p, "Signature", + "SHA512withRSA", + "sun.security.mscapi.CSignature$SHA512withRSA", + attrs)); + putService(new ProviderServiceA(p, "Signature", + "RSASSA-PSS", "sun.security.mscapi.CSignature$PSS", attrs)); - putService(new ProviderService(p, "Signature", - "RSASSA-PSS", "sun.security.mscapi.CSignature$PSS", - new String[] { "1.2.840.113549.1.1.10", "OID.1.2.840.113549.1.1.10" }, - attrs)); putService(new ProviderService(p, "Signature", "MD5withRSA", "sun.security.mscapi.CSignature$MD5withRSA", null, attrs)); putService(new ProviderService(p, "Signature", "MD2withRSA", "sun.security.mscapi.CSignature$MD2withRSA", null, attrs)); - putService(new ProviderService(p, "Signature", - "SHA1withECDSA", "sun.security.mscapi.CSignature$SHA1withECDSA", - new String[] { "1.2.840.10045.4.1", "OID.1.2.840.10045.4.1" }, - attrs)); - putService(new ProviderService(p, "Signature", - "SHA224withECDSA", "sun.security.mscapi.CSignature$SHA224withECDSA", - new String[] { "1.2.840.10045.4.3.1", "OID.1.2.840.10045.4.3.1"}, - attrs)); - putService(new ProviderService(p, "Signature", - "SHA256withECDSA", "sun.security.mscapi.CSignature$SHA256withECDSA", - new String[] { "1.2.840.10045.4.3.2", "OID.1.2.840.10045.4.3.2"}, - attrs)); - putService(new ProviderService(p, "Signature", - "SHA384withECDSA", "sun.security.mscapi.CSignature$SHA384withECDSA", - new String[] { "1.2.840.10045.4.3.3", "OID.1.2.840.10045.4.3.3"}, - attrs)); - putService(new ProviderService(p, "Signature", - "SHA512withECDSA", "sun.security.mscapi.CSignature$SHA512withECDSA", - new String[] { "1.2.840.10045.4.3.4", "OID.1.2.840.10045.4.3.4"}, - attrs)); + putService(new ProviderServiceA(p, "Signature", + "SHA1withECDSA", + "sun.security.mscapi.CSignature$SHA1withECDSA", + attrs)); + putService(new ProviderServiceA(p, "Signature", + "SHA224withECDSA", + "sun.security.mscapi.CSignature$SHA224withECDSA", + attrs)); + putService(new ProviderServiceA(p, "Signature", + "SHA256withECDSA", + "sun.security.mscapi.CSignature$SHA256withECDSA", + attrs)); + putService(new ProviderServiceA(p, "Signature", + "SHA384withECDSA", + "sun.security.mscapi.CSignature$SHA384withECDSA", + attrs)); + putService(new ProviderServiceA(p, "Signature", + "SHA512withECDSA", + "sun.security.mscapi.CSignature$SHA512withECDSA", + attrs)); /* * Key Pair Generator engines */ diff --git a/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/LibMDMech.java b/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/LibMDMech.java index 3b6b3f623f5..05a7af7edcc 100644 --- a/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/LibMDMech.java +++ b/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/LibMDMech.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 @@ -25,6 +25,9 @@ package com.oracle.security.ucrypto; +import java.util.List; +import static sun.security.util.SecurityProviderConstants.getAliases; + /** * Enum for representing the ucrypto mechanisms. * @@ -36,25 +39,30 @@ public enum LibMDMech { { sd("MessageDigest", "MD5", "com.oracle.security.ucrypto.NativeDigestMD$MD5") }), SHA_1(new ServiceDesc[] - { sd("MessageDigest", "SHA", "com.oracle.security.ucrypto.NativeDigestMD$SHA1", - "SHA-1", "SHA1") + { sd("MessageDigest", "SHA-1", "com.oracle.security.ucrypto.NativeDigestMD$SHA1", + getAliases("SHA-1")) }), SHA_256(new ServiceDesc[] { sd("MessageDigest", "SHA-256", "com.oracle.security.ucrypto.NativeDigestMD$SHA256", - "2.16.840.1.101.3.4.2.1", "OID.2.16.840.1.101.3.4.2.1") + getAliases("SHA-256")) }), SHA_384(new ServiceDesc[] { sd("MessageDigest", "SHA-384", "com.oracle.security.ucrypto.NativeDigestMD$SHA384", - "2.16.840.1.101.3.4.2.2", "OID.2.16.840.1.101.3.4.2.2") + getAliases("SHA-384")) }), SHA_512(new ServiceDesc[] { sd("MessageDigest", "SHA-512", "com.oracle.security.ucrypto.NativeDigestMD$SHA512", - "2.16.840.1.101.3.4.2.3", "OID.2.16.840.1.101.3.4.2.3") + getAliases("SHA-512")) }); ServiceDesc[] serviceDescs; - private static ServiceDesc sd(String type, String algo, String cn, String... aliases) { + private static ServiceDesc sd(String type, String algo, String cn) { + return new ServiceDesc(type, algo, cn, null); + } + + private static ServiceDesc sd(String type, String algo, String cn, + List aliases) { return new ServiceDesc(type, algo, cn, aliases); } diff --git a/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/ServiceDesc.java b/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/ServiceDesc.java index aa7eae1e000..8b915626ffb 100644 --- a/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/ServiceDesc.java +++ b/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/ServiceDesc.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 @@ -42,15 +42,11 @@ final class ServiceDesc { this(type, algo, cn, null); } - ServiceDesc(String type, String algo, String cn, String[] aliases) { + ServiceDesc(String type, String algo, String cn, List aliases) { this.type = type; this.algo = algo; this.cn = cn; - if (aliases != null) { - this.aliases = Arrays.asList(aliases); - } else { - this.aliases = null; - } + this.aliases = aliases; } String getType() { return type; diff --git a/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoMech.java b/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoMech.java index 0e1c2849828..b853755a7a2 100644 --- a/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoMech.java +++ b/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoMech.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2016, 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 @@ -25,6 +25,9 @@ package com.oracle.security.ucrypto; +import java.util.List; +import static sun.security.util.SecurityProviderConstants.getAliases; + /** * Enum for representing the ucrypto mechanisms. * @@ -36,23 +39,23 @@ public enum UcryptoMech { CRYPTO_AES_ECB(new ServiceDesc[] { sd("Cipher", "AES/ECB/NoPadding", "com.oracle.security.ucrypto.NativeCipher$AesEcbNoPadding"), sd("Cipher", "AES/ECB/PKCS5Padding", "com.oracle.security.ucrypto.NativeCipherWithJavaPadding$AesEcbPKCS5", - "AES"), - sd("Cipher", "AES_128/ECB/NoPadding", "com.oracle.security.ucrypto.NativeCipher$AesEcbNoPadding", - "2.16.840.1.101.3.4.1.1", "OID.2.16.840.1.101.3.4.1.1"), - sd("Cipher", "AES_192/ECB/NoPadding", "com.oracle.security.ucrypto.NativeCipher$AesEcbNoPadding", - "2.16.840.1.101.3.4.1.21", "OID.2.16.840.1.101.3.4.1.21"), - sd("Cipher", "AES_256/ECB/NoPadding", "com.oracle.security.ucrypto.NativeCipher$AesEcbNoPadding", - "2.16.840.1.101.3.4.1.41", "OID.2.16.840.1.101.3.4.1.41") + List.of("AES")), + sdA("Cipher", "AES_128/ECB/NoPadding", + "com.oracle.security.ucrypto.NativeCipher$AesEcbNoPadding"), + sdA("Cipher", "AES_192/ECB/NoPadding", + "com.oracle.security.ucrypto.NativeCipher$AesEcbNoPadding"), + sdA("Cipher", "AES_256/ECB/NoPadding", + "com.oracle.security.ucrypto.NativeCipher$AesEcbNoPadding") }), CRYPTO_AES_CBC(new ServiceDesc[] { sd("Cipher", "AES/CBC/NoPadding", "com.oracle.security.ucrypto.NativeCipher$AesCbcNoPadding"), sd("Cipher", "AES/CBC/PKCS5Padding", "com.oracle.security.ucrypto.NativeCipherWithJavaPadding$AesCbcPKCS5"), - sd("Cipher", "AES_128/CBC/NoPadding", "com.oracle.security.ucrypto.NativeCipher$AesCbcNoPadding", - "2.16.840.1.101.3.4.1.2", "OID.2.16.840.1.101.3.4.1.2"), - sd("Cipher", "AES_192/CBC/NoPadding", "com.oracle.security.ucrypto.NativeCipher$AesCbcNoPadding", - "2.16.840.1.101.3.4.1.22", "OID.2.16.840.1.101.3.4.1.22"), - sd("Cipher", "AES_256/CBC/NoPadding", "com.oracle.security.ucrypto.NativeCipher$AesCbcNoPadding", - "2.16.840.1.101.3.4.1.42", "OID.2.16.840.1.101.3.4.1.42") + sdA("Cipher", "AES_128/CBC/NoPadding", + "com.oracle.security.ucrypto.NativeCipher$AesCbcNoPadding"), + sdA("Cipher", "AES_192/CBC/NoPadding", + "com.oracle.security.ucrypto.NativeCipher$AesCbcNoPadding"), + sdA("Cipher", "AES_256/CBC/NoPadding", + "com.oracle.security.ucrypto.NativeCipher$AesCbcNoPadding") }), // CRYPTO_AES_CBC_PAD(null), // Support added since S11.1; however we still use CRYPTO_AES_CBC due to known bug CRYPTO_AES_CTR(new ServiceDesc[] @@ -60,12 +63,12 @@ public enum UcryptoMech { // CRYPTO_AES_CCM(null), // Need Java API for CK_AES_CCM_PARAMS CRYPTO_AES_GCM(new ServiceDesc[] { sd("Cipher", "AES/GCM/NoPadding", "com.oracle.security.ucrypto.NativeGCMCipher$AesGcmNoPadding"), - sd("Cipher", "AES_128/GCM/NoPadding", "com.oracle.security.ucrypto.NativeGCMCipher$AesGcmNoPadding", - "2.16.840.1.101.3.4.1.6", "OID.2.16.840.1.101.3.4.1.6"), - sd("Cipher", "AES_192/GCM/NoPadding", "com.oracle.security.ucrypto.NativeGCMCipher$AesGcmNoPadding", - "2.16.840.1.101.3.4.1.26", "OID.2.16.840.1.101.3.4.1.26"), - sd("Cipher", "AES_256/GCM/NoPadding", "com.oracle.security.ucrypto.NativeGCMCipher$AesGcmNoPadding", - "2.16.840.1.101.3.4.1.46", "OID.2.16.840.1.101.3.4.1.46") + sdA("Cipher", "AES_128/GCM/NoPadding", + "com.oracle.security.ucrypto.NativeGCMCipher$AesGcmNoPadding"), + sdA("Cipher", "AES_192/GCM/NoPadding", + "com.oracle.security.ucrypto.NativeGCMCipher$AesGcmNoPadding"), + sdA("Cipher", "AES_256/GCM/NoPadding", + "com.oracle.security.ucrypto.NativeGCMCipher$AesGcmNoPadding") }), // CRYPTO_AES_GMAC(null), // No support from Solaris CRYPTO_AES_CFB128(new ServiceDesc[] @@ -75,76 +78,87 @@ public enum UcryptoMech { CRYPTO_RSA_PKCS(new ServiceDesc[] { sd("Cipher", "RSA/ECB/PKCS1Padding", "com.oracle.security.ucrypto.NativeRSACipher$PKCS1Padding", - "RSA") + List.of("RSA")) }), CRYPTO_RSA_X_509(new ServiceDesc[] { sd("Cipher", "RSA/ECB/NoPadding", "com.oracle.security.ucrypto.NativeRSACipher$NoPadding") }), CRYPTO_MD5_RSA_PKCS(new ServiceDesc[] - { sd("Signature", "MD5withRSA", "com.oracle.security.ucrypto.NativeRSASignature$MD5", - "1.2.840.113549.1.1.4", "OID.1.2.840.113549.1.1.4") + { sdA("Signature", "MD5withRSA", + "com.oracle.security.ucrypto.NativeRSASignature$MD5") }), CRYPTO_SHA1_RSA_PKCS(new ServiceDesc[] - { sd("Signature", "SHA1withRSA", "com.oracle.security.ucrypto.NativeRSASignature$SHA1", - "1.2.840.113549.1.1.5", "OID.1.2.840.113549.1.1.5", - "1.3.14.3.2.29") + { sdA("Signature", "SHA1withRSA", + "com.oracle.security.ucrypto.NativeRSASignature$SHA1") }), CRYPTO_SHA256_RSA_PKCS(new ServiceDesc[] - { sd("Signature", "SHA256withRSA", "com.oracle.security.ucrypto.NativeRSASignature$SHA256", - "1.2.840.113549.1.1.11", "OID.1.2.840.113549.1.1.11") + { sdA("Signature", "SHA256withRSA", + "com.oracle.security.ucrypto.NativeRSASignature$SHA256") }), CRYPTO_SHA384_RSA_PKCS(new ServiceDesc[] - { sd("Signature", "SHA384withRSA", "com.oracle.security.ucrypto.NativeRSASignature$SHA384", - "1.2.840.113549.1.1.12", "OID.1.2.840.113549.1.1.12") + { sdA("Signature", "SHA384withRSA", + "com.oracle.security.ucrypto.NativeRSASignature$SHA384") }), CRYPTO_SHA512_RSA_PKCS(new ServiceDesc[] - { sd("Signature", "SHA512withRSA", "com.oracle.security.ucrypto.NativeRSASignature$SHA512", - "1.2.840.113549.1.1.13", "OID.1.2.840.113549.1.1.13") + { sdA("Signature", "SHA512withRSA", + "com.oracle.security.ucrypto.NativeRSASignature$SHA512") }), CRYPTO_MD5(new ServiceDesc[] - { sd("MessageDigest", "MD5", "com.oracle.security.ucrypto.NativeDigest$MD5") }), + { sd("MessageDigest", "MD5", "com.oracle.security.ucrypto.NativeDigest$MD5") + }), CRYPTO_SHA1(new ServiceDesc[] - { sd("MessageDigest", "SHA", "com.oracle.security.ucrypto.NativeDigest$SHA1", "SHA-1", "SHA1") }), + { sdA("MessageDigest", "SHA-1", + "com.oracle.security.ucrypto.NativeDigest$SHA1") + }), CRYPTO_SHA224(new ServiceDesc[] - { sd("MessageDigest", "SHA-224", "com.oracle.security.ucrypto.NativeDigest$SHA224", - "2.16.840.1.101.3.4.2.4", "OID.2.16.840.1.101.3.4.2.4") - }), + { sdA("MessageDigest", "SHA-224", + "com.oracle.security.ucrypto.NativeDigest$SHA224") + }), CRYPTO_SHA256(new ServiceDesc[] - { sd("MessageDigest", "SHA-256", "com.oracle.security.ucrypto.NativeDigest$SHA256", - "2.16.840.1.101.3.4.2.1", "OID.2.16.840.1.101.3.4.2.1") - }), + { sdA("MessageDigest", "SHA-256", + "com.oracle.security.ucrypto.NativeDigest$SHA256") + }), CRYPTO_SHA384(new ServiceDesc[] - { sd("MessageDigest", "SHA-384", "com.oracle.security.ucrypto.NativeDigest$SHA384", - "2.16.840.1.101.3.4.2.2", "OID.2.16.840.1.101.3.4.2.2") - }), + { sdA("MessageDigest", "SHA-384", + "com.oracle.security.ucrypto.NativeDigest$SHA384") + }), CRYPTO_SHA512(new ServiceDesc[] - { sd("MessageDigest", "SHA-512", "com.oracle.security.ucrypto.NativeDigest$SHA512", - "2.16.840.1.101.3.4.2.3", "OID.2.16.840.1.101.3.4.2.3") - }), + { sdA("MessageDigest", "SHA-512", + "com.oracle.security.ucrypto.NativeDigest$SHA512") + }), CRYPTO_SHA3_224(new ServiceDesc[] - { sd("MessageDigest", "SHA3-224", "com.oracle.security.ucrypto.NativeDigest$SHA3_224", - "2.16.840.1.101.3.4.2.7", "OID.2.16.840.1.101.3.4.2.7") - }), + { sdA("MessageDigest", "SHA3-224", + "com.oracle.security.ucrypto.NativeDigest$SHA3_224") + }), CRYPTO_SHA3_256(new ServiceDesc[] - { sd("MessageDigest", "SHA3-256", "com.oracle.security.ucrypto.NativeDigest$SHA3_256", - "2.16.840.1.101.3.4.2.8", "OID.2.16.840.1.101.3.4.2.8") - }), + { sdA("MessageDigest", "SHA3-256", + "com.oracle.security.ucrypto.NativeDigest$SHA3_256") + }), CRYPTO_SHA3_384(new ServiceDesc[] - { sd("MessageDigest", "SHA3-384", "com.oracle.security.ucrypto.NativeDigest$SHA3_384", - "2.16.840.1.101.3.4.2.9", "OID.2.16.840.1.101.3.4.2.9") - }), + { sdA("MessageDigest", "SHA3-384", + "com.oracle.security.ucrypto.NativeDigest$SHA3_384") + }), CRYPTO_SHA3_512(new ServiceDesc[] - { sd("MessageDigest", "SHA3-512", "com.oracle.security.ucrypto.NativeDigest$SHA3_512", - "2.16.840.1.101.3.4.2.10", "OID.2.16.840.1.101.3.4.2.10") - }); + { sdA("MessageDigest", "SHA3-512", + "com.oracle.security.ucrypto.NativeDigest$SHA3_512") + }); private int mech = 0; private final ServiceDesc[] serviceDescs; - private static ServiceDesc sd(String type, String algo, String cn, String... aliases) { + private static ServiceDesc sd(String type, String algo, String cn) { + return new ServiceDesc(type, algo, cn, null); + } + + private static ServiceDesc sd(String type, String algo, String cn, + List aliases) { return new ServiceDesc(type, algo, cn, aliases); } + private static ServiceDesc sdA(String type, String algo, String cn) { + return new ServiceDesc(type, algo, cn, getAliases(algo)); + } + UcryptoMech(ServiceDesc[] serviceDescs) { this.serviceDescs = serviceDescs; } diff --git a/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoProvider.java b/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoProvider.java index a1a7cc15508..0300547a7c3 100644 --- a/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoProvider.java +++ b/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2016, 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 @@ -32,7 +32,6 @@ import java.util.*; import java.security.*; import static sun.security.util.SecurityConstants.PROVIDER_VER; - /** * OracleUcrypto provider main class. * @@ -134,9 +133,8 @@ public final class UcryptoProvider extends Provider { } } - private static ServiceDesc sd(String type, String algo, String cn, - String... aliases) { - return new ServiceDesc(type, algo, cn, aliases); + private static ServiceDesc sd(String type, String algo, String cn) { + return new ServiceDesc(type, algo, cn, null); } private static final class ProviderService extends Provider.Service { diff --git a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/TimestampedSigner.java b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/TimestampedSigner.java index 0bb144015ea..4cc209d7525 100644 --- a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/TimestampedSigner.java +++ b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/TimestampedSigner.java @@ -48,25 +48,11 @@ import sun.security.x509.*; @SuppressWarnings("removal") public final class TimestampedSigner extends ContentSigner { - /* - * Object identifier for the subject information access X.509 certificate - * extension. - */ - private static final String SUBJECT_INFO_ACCESS_OID = "1.3.6.1.5.5.7.1.11"; - /* * Object identifier for the timestamping access descriptors. */ - private static final ObjectIdentifier AD_TIMESTAMPING_Id; - static { - ObjectIdentifier tmp = null; - try { - tmp = new ObjectIdentifier("1.3.6.1.5.5.7.48.3"); - } catch (IOException e) { - // ignore - } - AD_TIMESTAMPING_Id = tmp; - } + private static final ObjectIdentifier AD_TIMESTAMPING_Id = + ObjectIdentifier.of(KnownOIDs.AD_TimeStamping); /** * Instantiates a content signer that supports timestamped signatures. @@ -155,8 +141,8 @@ public final class TimestampedSigner extends ContentSigner { } // Parse the extensions try { - byte[] extensionValue = - tsaCertificate.getExtensionValue(SUBJECT_INFO_ACCESS_OID); + byte[] extensionValue = tsaCertificate.getExtensionValue + (KnownOIDs.SubjectInfoAccess.value()); if (extensionValue == null) { return null; } diff --git a/test/jdk/java/security/testlibrary/CertificateBuilder.java b/test/jdk/java/security/testlibrary/CertificateBuilder.java index 4ab26d0d12e..b2c39b8ab5b 100644 --- a/test/jdk/java/security/testlibrary/CertificateBuilder.java +++ b/test/jdk/java/security/testlibrary/CertificateBuilder.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 @@ -322,7 +322,7 @@ public class CertificateBuilder { if (!ekuOids.isEmpty()) { Vector oidVector = new Vector<>(); for (String oid : ekuOids) { - oidVector.add(new ObjectIdentifier(oid)); + oidVector.add(ObjectIdentifier.of(oid)); } addExtension(new ExtendedKeyUsageExtension(oidVector)); } diff --git a/test/jdk/java/security/testlibrary/SimpleOCSPServer.java b/test/jdk/java/security/testlibrary/SimpleOCSPServer.java index 6651ba0b3c7..1a29bef0c42 100644 --- a/test/jdk/java/security/testlibrary/SimpleOCSPServer.java +++ b/test/jdk/java/security/testlibrary/SimpleOCSPServer.java @@ -45,11 +45,7 @@ import sun.security.provider.certpath.ResponderId; import sun.security.provider.certpath.CertId; import sun.security.provider.certpath.OCSPResponse; import sun.security.provider.certpath.OCSPResponse.ResponseStatus; -import sun.security.util.Debug; -import sun.security.util.DerInputStream; -import sun.security.util.DerOutputStream; -import sun.security.util.DerValue; -import sun.security.util.ObjectIdentifier; +import sun.security.util.*; /** @@ -59,7 +55,8 @@ import sun.security.util.ObjectIdentifier; public class SimpleOCSPServer { private final Debug debug = Debug.getInstance("oserv"); private static final ObjectIdentifier OCSP_BASIC_RESPONSE_OID = - ObjectIdentifier.of("1.3.6.1.5.5.7.48.1.1"); + ObjectIdentifier.of(KnownOIDs.OCSPBasicResponse); + private static final SimpleDateFormat utcDateFmt = new SimpleDateFormat("MMM dd yyyy, HH:mm:ss z"); diff --git a/test/jdk/sun/security/jgss/spnego/NotPreferredMech.java b/test/jdk/sun/security/jgss/spnego/NotPreferredMech.java index d057e95a695..93a3dec8c91 100644 --- a/test/jdk/sun/security/jgss/spnego/NotPreferredMech.java +++ b/test/jdk/sun/security/jgss/spnego/NotPreferredMech.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 8048194 + * @bug 8048194 8242151 * @modules java.base/sun.security.util * java.security.jgss/sun.security.jgss * java.security.jgss/sun.security.jgss.spnego:+open @@ -57,7 +57,7 @@ public class NotPreferredMech { mechTypeList.write(DerValue.tag_Sequence, mech); // Generates a NegTokenInit mechToken field for 1.2.3.4 mech - GSSHeader h1 = new GSSHeader(new ObjectIdentifier("1.2.3.4"), 1); + GSSHeader h1 = new GSSHeader(ObjectIdentifier.of("1.2.3.4"), 1); ByteArrayOutputStream bout = new ByteArrayOutputStream(); h1.encode(bout); bout.write(new byte[1]); @@ -78,7 +78,7 @@ public class NotPreferredMech { // and wraps it into a GSSToken GSSHeader h = new GSSHeader( - new ObjectIdentifier(GSSUtil.GSS_SPNEGO_MECH_OID.toString()), + ObjectIdentifier.of(GSSUtil.GSS_SPNEGO_MECH_OID.toString()), spnegoToken.length); bout = new ByteArrayOutputStream(); h.encode(bout); diff --git a/test/jdk/sun/security/pkcs/pkcs10/PKCS10AttrEncoding.java b/test/jdk/sun/security/pkcs/pkcs10/PKCS10AttrEncoding.java index d9ecc2bf435..72457f4a4d9 100644 --- a/test/jdk/sun/security/pkcs/pkcs10/PKCS10AttrEncoding.java +++ b/test/jdk/sun/security/pkcs/pkcs10/PKCS10AttrEncoding.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 @@ -23,7 +23,7 @@ /* * @test - * @bug 8048357 + * @bug 8048357 8242151 * @summary test DER encoding of PKCS10 attributes * @modules java.base/sun.security.pkcs * java.base/sun.security.pkcs10 @@ -62,7 +62,7 @@ public class PKCS10AttrEncoding { // initializations int len = ids.length; Object[] values = { - new ObjectIdentifier("1.2.3.4"), + ObjectIdentifier.of("1.2.3.4"), new GregorianCalendar(1970, 1, 25, 8, 56, 7).getTime(), "challenging" }; diff --git a/test/jdk/sun/security/pkcs/pkcs10/PKCS10AttributeReader.java b/test/jdk/sun/security/pkcs/pkcs10/PKCS10AttributeReader.java index aef650c68a5..c4f8c9d0d4b 100644 --- a/test/jdk/sun/security/pkcs/pkcs10/PKCS10AttributeReader.java +++ b/test/jdk/sun/security/pkcs/pkcs10/PKCS10AttributeReader.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 @@ -23,7 +23,7 @@ /* * @test - * @bug 8048357 + * @bug 8048357 8242151 * @summary Read in a file containing a DER encoded PKCS10 certificate request, * flanked with "begin" and "end" lines. * @modules java.base/sun.security.pkcs @@ -86,7 +86,7 @@ public class PKCS10AttributeReader { put(PKCS9Attribute.CHALLENGE_PASSWORD_OID, "GuessWhoAmI"); put(PKCS9Attribute.SIGNING_TIME_OID, new Date(861720610000L)); put(PKCS9Attribute.CONTENT_TYPE_OID, - new ObjectIdentifier("1.9.50.51.52")); + ObjectIdentifier.of("1.9.50.51.52")); } }; diff --git a/test/jdk/sun/security/pkcs/pkcs9/UnknownAttribute.java b/test/jdk/sun/security/pkcs/pkcs9/UnknownAttribute.java index 4ffc96833e8..333550d2ace 100644 --- a/test/jdk/sun/security/pkcs/pkcs9/UnknownAttribute.java +++ b/test/jdk/sun/security/pkcs/pkcs9/UnknownAttribute.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8011867 + * @bug 8011867 8242151 * @summary Accept unknown PKCS #9 attributes * @library /test/lib * @modules java.base/sun.security.pkcs @@ -43,7 +43,7 @@ public class UnknownAttribute { public static void main(String[] args) throws Exception { // Unknown attr PKCS9Attribute p1 = new PKCS9Attribute( - PKCS9Attribute.CHALLENGE_PASSWORD_STR, "t0p5ecr3t"); + PKCS9Attribute.CHALLENGE_PASSWORD_OID, "t0p5ecr3t"); if (!p1.isKnown()) { throw new Exception(); } @@ -65,13 +65,13 @@ public class UnknownAttribute { } // Unknown attr from value try { - new PKCS9Attribute(new ObjectIdentifier("1.2.3"), "hello"); + new PKCS9Attribute(ObjectIdentifier.of("1.2.3"), "hello"); throw new Exception(); } catch (IllegalArgumentException iae) { // Good. Unknown attr must have byte[] value type } PKCS9Attribute p3 = new PKCS9Attribute( - new ObjectIdentifier("1.2.3"), new byte[]{0x31,0x02,0x05,0x00}); + ObjectIdentifier.of("1.2.3"), new byte[]{0x31,0x02,0x05,0x00}); if (p3.isKnown()) { throw new Exception(); } diff --git a/test/jdk/sun/security/pkcs12/PKCS12SameKeyId.java b/test/jdk/sun/security/pkcs12/PKCS12SameKeyId.java index bbdac6c3fc3..de563dc11f8 100644 --- a/test/jdk/sun/security/pkcs12/PKCS12SameKeyId.java +++ b/test/jdk/sun/security/pkcs12/PKCS12SameKeyId.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 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,7 +23,7 @@ /* * @test - * @bug 6958026 + * @bug 6958026 8242151 * @summary Problem with PKCS12 keystore * @modules java.base/sun.security.pkcs * java.base/sun.security.tools.keytool @@ -75,7 +75,7 @@ public class PKCS12SameKeyId { AlgorithmParameters.getInstance("PBEWithSHA1AndDESede"); algParams.init(new PBEParameterSpec("12345678".getBytes(), 1024)); AlgorithmId algid = new AlgorithmId( - new ObjectIdentifier("1.2.840.113549.1.12.1.3"), algParams); + ObjectIdentifier.of("1.2.840.113549.1.12.1.3"), algParams); PBEKeySpec keySpec = new PBEKeySpec(PASSWORD); SecretKeyFactory skFac = SecretKeyFactory.getInstance("PBE"); diff --git a/test/jdk/sun/security/pkcs12/ParamsPreferences.java b/test/jdk/sun/security/pkcs12/ParamsPreferences.java index 6069c64957e..3c87e045120 100644 --- a/test/jdk/sun/security/pkcs12/ParamsPreferences.java +++ b/test/jdk/sun/security/pkcs12/ParamsPreferences.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 @@ -32,14 +32,14 @@ import java.util.List; import static jdk.test.lib.security.DerUtils.*; import static sun.security.pkcs.ContentInfo.DATA_OID; import static sun.security.pkcs.ContentInfo.ENCRYPTED_DATA_OID; -import static sun.security.x509.AlgorithmId.*; +import sun.security.util.ObjectIdentifier; +import sun.security.util.KnownOIDs; /* * @test - * @bug 8076190 + * @bug 8076190 8242151 * @library /test/lib * @modules java.base/sun.security.pkcs - * java.base/sun.security.x509 * java.base/sun.security.util * @summary Checks the preferences order of pkcs12 params */ @@ -50,16 +50,16 @@ public class ParamsPreferences { // with storepass test(c++, "-", "-", - pbeWithSHA1AndRC2_40_oid, 50000, - pbeWithSHA1AndDESede_oid, 50000, - SHA_oid, 100000); + oid(KnownOIDs.PBEWithSHA1AndRC2_40), 50000, + oid(KnownOIDs.PBEWithSHA1AndDESede), 50000, + oid(KnownOIDs.SHA_1), 100000); // password-less with system property test(c++, "keystore.pkcs12.certProtectionAlgorithm", "NONE", "keystore.pkcs12.macAlgorithm", "NONE", "-", "-", null, 0, - pbeWithSHA1AndDESede_oid, 50000, + oid(KnownOIDs.PBEWithSHA1AndDESede), 50000, null, 0); // password-less with security property @@ -68,7 +68,7 @@ public class ParamsPreferences { "keystore.pkcs12.macAlgorithm", "NONE", "-", null, 0, - pbeWithSHA1AndDESede_oid, 50000, + oid(KnownOIDs.PBEWithSHA1AndDESede), 50000, null, 0); // back to with storepass by overriding security property with system property @@ -78,9 +78,9 @@ public class ParamsPreferences { "keystore.pkcs12.certProtectionAlgorithm", "NONE", "keystore.pkcs12.macAlgorithm", "NONE", "-", - pbeWithSHA1AndDESede_oid, 50000, - pbeWithSHA1AndDESede_oid, 50000, - SHA256_oid, 100000); + oid(KnownOIDs.PBEWithSHA1AndDESede), 50000, + oid(KnownOIDs.PBEWithSHA1AndDESede), 50000, + oid(KnownOIDs.SHA_256), 100000); // back to with storepass by using "" to force hardcoded default test(c++, "keystore.pkcs12.certProtectionAlgorithm", "", @@ -91,9 +91,9 @@ public class ParamsPreferences { "keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_40", "keystore.pkcs12.macAlgorithm", "NONE", "-", - pbeWithSHA1AndRC2_40_oid, 50000, - pbeWithSHA1AndDESede_oid, 50000, - SHA_oid, 100000); + oid(KnownOIDs.PBEWithSHA1AndRC2_40), 50000, + oid(KnownOIDs.PBEWithSHA1AndDESede), 50000, + oid(KnownOIDs.SHA_1), 100000); // change everything with system property test(c++, "keystore.pkcs12.certProtectionAlgorithm", "PBEWithSHA1AndDESede", @@ -103,9 +103,9 @@ public class ParamsPreferences { "keystore.pkcs12.macAlgorithm", "HmacPBESHA256", "keystore.pkcs12.macIterationCount", 2000, "-", "-", - pbeWithSHA1AndDESede_oid, 3000, - pbeWithSHA1AndRC2_40_oid, 4000, - SHA256_oid, 2000); + oid(KnownOIDs.PBEWithSHA1AndDESede), 3000, + oid(KnownOIDs.PBEWithSHA1AndRC2_40), 4000, + oid(KnownOIDs.SHA_256), 2000); // change everything with security property test(c++, "-", @@ -116,9 +116,9 @@ public class ParamsPreferences { "keystore.pkcs12.macAlgorithm", "HmacPBESHA256", "keystore.pkcs12.macIterationCount", 2000, "-", - pbeWithSHA1AndDESede_oid, 3000, - pbeWithSHA1AndRC2_40_oid, 4000, - SHA256_oid, 2000); + oid(KnownOIDs.PBEWithSHA1AndDESede), 3000, + oid(KnownOIDs.PBEWithSHA1AndRC2_40), 4000, + oid(KnownOIDs.SHA_256), 2000); // override security property with system property test(c++, "keystore.pkcs12.certProtectionAlgorithm", "PBEWithSHA1AndDESede", @@ -135,9 +135,9 @@ public class ParamsPreferences { "keystore.pkcs12.macAlgorithm", "HmacPBESHA1", "keystore.pkcs12.macIterationCount", 2000, "-", - pbeWithSHA1AndDESede_oid, 13000, - pbeWithSHA1AndRC2_40_oid, 14000, - SHA256_oid, 12000); + oid(KnownOIDs.PBEWithSHA1AndDESede), 13000, + oid(KnownOIDs.PBEWithSHA1AndRC2_40), 14000, + oid(KnownOIDs.SHA_256), 12000); // check keyProtectionAlgorithm old behavior. Preferences of // 4 different settings. @@ -145,25 +145,25 @@ public class ParamsPreferences { test(c++, "-", "keystore.PKCS12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_128", "-", - pbeWithSHA1AndRC2_40_oid, 50000, - pbeWithSHA1AndRC2_128_oid, 50000, - SHA_oid, 100000); + oid(KnownOIDs.PBEWithSHA1AndRC2_40), 50000, + oid(KnownOIDs.PBEWithSHA1AndRC2_128), 50000, + oid(KnownOIDs.SHA_1), 100000); test(c++, "-", "keystore.PKCS12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_128", "keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_40", "-", - pbeWithSHA1AndRC2_40_oid, 50000, - pbeWithSHA1AndRC2_40_oid, 50000, - SHA_oid, 100000); + oid(KnownOIDs.PBEWithSHA1AndRC2_40), 50000, + oid(KnownOIDs.PBEWithSHA1AndRC2_40), 50000, + oid(KnownOIDs.SHA_1), 100000); test(c++, "keystore.PKCS12.keyProtectionAlgorithm", "PBEWithSHA1AndRC4_128", "-", "keystore.PKCS12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_128", "keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_40", "-", - pbeWithSHA1AndRC2_40_oid, 50000, - pbeWithSHA1AndRC4_128_oid, 50000, - SHA_oid, 100000); + oid(KnownOIDs.PBEWithSHA1AndRC2_40), 50000, + oid(KnownOIDs.PBEWithSHA1AndRC4_128), 50000, + oid(KnownOIDs.SHA_1), 100000); test(c++, "keystore.PKCS12.keyProtectionAlgorithm", "PBEWithSHA1AndRC4_128", "keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC4_40", @@ -171,9 +171,13 @@ public class ParamsPreferences { "keystore.PKCS12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_128", "keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_40", "-", - pbeWithSHA1AndRC2_40_oid, 50000, - pbeWithSHA1AndRC4_40_oid, 50000, - SHA_oid, 100000); + oid(KnownOIDs.PBEWithSHA1AndRC2_40), 50000, + oid(KnownOIDs.PBEWithSHA1AndRC4_40), 50000, + oid(KnownOIDs.SHA_1), 100000); + } + + private static ObjectIdentifier oid(KnownOIDs o) { + return ObjectIdentifier.of(o); } /** diff --git a/test/jdk/sun/security/pkcs12/ParamsTest.java b/test/jdk/sun/security/pkcs12/ParamsTest.java index 0969480182b..54910f47cb6 100644 --- a/test/jdk/sun/security/pkcs12/ParamsTest.java +++ b/test/jdk/sun/security/pkcs12/ParamsTest.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 @@ -23,10 +23,9 @@ /* * @test - * @bug 8076190 + * @bug 8076190 8242151 * @library /test/lib * @modules java.base/sun.security.pkcs - * java.base/sun.security.x509 * java.base/sun.security.util * @summary Customizing the generation of a PKCS12 keystore */ @@ -49,7 +48,8 @@ import java.util.Base64; import java.util.Objects; import static jdk.test.lib.security.DerUtils.*; -import static sun.security.x509.AlgorithmId.*; +import sun.security.util.ObjectIdentifier; +import sun.security.util.KnownOIDs; import static sun.security.pkcs.ContentInfo.*; public class ParamsTest { @@ -102,11 +102,11 @@ public class ParamsTest { + "-destkeystore ksnormal -deststorepass changeit"); data = Files.readAllBytes(Path.of("ksnormal")); checkInt(data, "22", 100000); // Mac ic - checkAlg(data, "2000", SHA_oid); // Mac alg - checkAlg(data, "110c010c01000", pbeWithSHA1AndDESede_oid); // key alg + checkAlg(data, "2000", oid(KnownOIDs.SHA_1)); // Mac alg + checkAlg(data, "110c010c01000", oid(KnownOIDs.PBEWithSHA1AndDESede)); // key alg checkInt(data, "110c010c010011", 50000); // key ic checkAlg(data, "110c10", ENCRYPTED_DATA_OID); - checkAlg(data, "110c110110", pbeWithSHA1AndRC2_40_oid); // cert alg + checkAlg(data, "110c110110", oid(KnownOIDs.PBEWithSHA1AndRC2_40)); // cert alg checkInt(data, "110c1101111", 50000); // cert ic check("ksnormal", "a", "changeit", "changeit", true, true, true); @@ -120,13 +120,13 @@ public class ParamsTest { + "-J-Dkeystore.pkcs12.macAlgorithm=NONE"); data = Files.readAllBytes(Path.of("ksnormal")); checkInt(data, "22", 100000); // Mac ic - checkAlg(data, "2000", SHA_oid); // Mac alg - checkAlg(data, "110c010c01000", pbeWithSHA1AndDESede_oid); // key alg + checkAlg(data, "2000", oid(KnownOIDs.SHA_1)); // Mac alg + checkAlg(data, "110c010c01000", oid(KnownOIDs.PBEWithSHA1AndDESede)); // key alg checkInt(data, "110c010c010011", 50000); // key ic - checkAlg(data, "110c010c11000", pbeWithSHA1AndDESede_oid); // new key alg + checkAlg(data, "110c010c11000", oid(KnownOIDs.PBEWithSHA1AndDESede)); // new key alg checkInt(data, "110c010c110011", 50000); // new key ic checkAlg(data, "110c10", ENCRYPTED_DATA_OID); - checkAlg(data, "110c110110", pbeWithSHA1AndRC2_40_oid); // cert alg + checkAlg(data, "110c110110", oid(KnownOIDs.PBEWithSHA1AndRC2_40)); // cert alg checkInt(data, "110c1101111", 50000); // cert ic check("ksnormal", "b", null, "changeit", true, false, true); check("ksnormal", "b", "changeit", "changeit", true, true, true); @@ -139,7 +139,7 @@ public class ParamsTest { + "-J-Dkeystore.pkcs12.macAlgorithm=NONE"); data = Files.readAllBytes(Path.of("ksnopass")); shouldNotExist(data, "2"); // no Mac - checkAlg(data, "110c010c01000", pbeWithSHA1AndRC4_128_oid); + checkAlg(data, "110c010c01000", oid(KnownOIDs.PBEWithSHA1AndRC4_128)); checkInt(data, "110c010c010011", 50000); checkAlg(data, "110c10", DATA_OID); check("ksnopass", "a", null, "changeit", true, true, true); @@ -151,9 +151,9 @@ public class ParamsTest { + "-storepass changeit -alias b -dname CN=B"); data = Files.readAllBytes(Path.of("ksnopass")); shouldNotExist(data, "2"); // no Mac - checkAlg(data, "110c010c01000", pbeWithSHA1AndRC4_128_oid); + checkAlg(data, "110c010c01000", oid(KnownOIDs.PBEWithSHA1AndRC4_128)); checkInt(data, "110c010c010011", 50000); - checkAlg(data, "110c010c11000", pbeWithSHA1AndDESede_oid); + checkAlg(data, "110c010c11000", oid(KnownOIDs.PBEWithSHA1AndDESede)); checkInt(data, "110c010c110011", 50000); checkAlg(data, "110c10", DATA_OID); check("ksnopass", "a", null, "changeit", true, true, true); @@ -166,10 +166,10 @@ public class ParamsTest { + "-J-Dkeystore.pkcs12.keyPbeIterationCount=7777"); data = Files.readAllBytes(Path.of("ksnewic")); checkInt(data, "22", 5555); // Mac ic - checkAlg(data, "2000", SHA_oid); // Mac alg - checkAlg(data, "110c010c01000", pbeWithSHA1AndDESede_oid); // key alg + checkAlg(data, "2000", oid(KnownOIDs.SHA_1)); // Mac alg + checkAlg(data, "110c010c01000", oid(KnownOIDs.PBEWithSHA1AndDESede)); // key alg checkInt(data, "110c010c010011", 7777); // key ic - checkAlg(data, "110c110110", pbeWithSHA1AndRC2_40_oid); // cert alg + checkAlg(data, "110c110110", oid(KnownOIDs.PBEWithSHA1AndRC2_40)); // cert alg checkInt(data, "110c1101111", 6666); // cert ic // keypbe alg cannot be NONE @@ -185,12 +185,12 @@ public class ParamsTest { + "-J-Dkeystore.pkcs12.keyProtectionAlgorithm=PBEWithSHA1AndRC4_128"); data = Files.readAllBytes(Path.of("ksnewic")); checkInt(data, "22", 5555); // Mac ic - checkAlg(data, "2000", SHA_oid); // Mac alg - checkAlg(data, "110c010c01000", pbeWithSHA1AndDESede_oid); // key alg + checkAlg(data, "2000", oid(KnownOIDs.SHA_1)); // Mac alg + checkAlg(data, "110c010c01000", oid(KnownOIDs.PBEWithSHA1AndDESede)); // key alg checkInt(data, "110c010c010011", 7777); // key ic - checkAlg(data, "110c010c11000", pbeWithSHA1AndRC4_128_oid); // new key alg + checkAlg(data, "110c010c11000", oid(KnownOIDs.PBEWithSHA1AndRC4_128)); // new key alg checkInt(data, "110c010c110011", 50000); // new key ic - checkAlg(data, "110c110110", pbeWithSHA1AndRC2_40_oid); // cert alg + checkAlg(data, "110c110110", oid(KnownOIDs.PBEWithSHA1AndRC2_40)); // cert alg checkInt(data, "110c1101111", 6666); // cert ic // Check KeyStore loading multiple keystores @@ -202,13 +202,13 @@ public class ParamsTest { } data = Files.readAllBytes(Path.of("ksnormaldup")); checkInt(data, "22", 100000); // Mac ic - checkAlg(data, "2000", SHA_oid); // Mac alg - checkAlg(data, "110c010c01000", pbeWithSHA1AndDESede_oid); // key alg + checkAlg(data, "2000", oid(KnownOIDs.SHA_1)); // Mac alg + checkAlg(data, "110c010c01000", oid(KnownOIDs.PBEWithSHA1AndDESede)); // key alg checkInt(data, "110c010c010011", 50000); // key ic - checkAlg(data, "110c010c11000", pbeWithSHA1AndDESede_oid); // new key alg + checkAlg(data, "110c010c11000", oid(KnownOIDs.PBEWithSHA1AndDESede)); // new key alg checkInt(data, "110c010c110011", 50000); // new key ic checkAlg(data, "110c10", ENCRYPTED_DATA_OID); - checkAlg(data, "110c110110", pbeWithSHA1AndRC2_40_oid); // cert alg + checkAlg(data, "110c110110", oid(KnownOIDs.PBEWithSHA1AndRC2_40)); // cert alg checkInt(data, "110c1101111", 50000); // cert ic try (FileInputStream fis = new FileInputStream("ksnopass"); @@ -218,9 +218,9 @@ public class ParamsTest { } data = Files.readAllBytes(Path.of("ksnopassdup")); shouldNotExist(data, "2"); // no Mac - checkAlg(data, "110c010c01000", pbeWithSHA1AndRC4_128_oid); + checkAlg(data, "110c010c01000", oid(KnownOIDs.PBEWithSHA1AndRC4_128)); checkInt(data, "110c010c010011", 50000); - checkAlg(data, "110c010c11000", pbeWithSHA1AndDESede_oid); + checkAlg(data, "110c010c11000", oid(KnownOIDs.PBEWithSHA1AndDESede)); checkInt(data, "110c010c110011", 50000); checkAlg(data, "110c10", DATA_OID); @@ -231,12 +231,12 @@ public class ParamsTest { } data = Files.readAllBytes(Path.of("ksnewicdup")); checkInt(data, "22", 5555); // Mac ic - checkAlg(data, "2000", SHA_oid); // Mac alg - checkAlg(data, "110c010c01000", pbeWithSHA1AndDESede_oid); // key alg + checkAlg(data, "2000", oid(KnownOIDs.SHA_1)); // Mac alg + checkAlg(data, "110c010c01000", oid(KnownOIDs.PBEWithSHA1AndDESede)); // key alg checkInt(data, "110c010c010011", 7777); // key ic - checkAlg(data, "110c010c11000", pbeWithSHA1AndRC4_128_oid); // new key alg + checkAlg(data, "110c010c11000", oid(KnownOIDs.PBEWithSHA1AndRC4_128)); // new key alg checkInt(data, "110c010c110011", 50000); // new key ic - checkAlg(data, "110c110110", pbeWithSHA1AndRC2_40_oid); // cert alg + checkAlg(data, "110c110110", oid(KnownOIDs.PBEWithSHA1AndRC2_40)); // cert alg checkInt(data, "110c1101111", 6666); // cert ic // Check keytool behavior @@ -434,6 +434,10 @@ public class ParamsTest { Asserts.assertEQ(expectedKey, actualKey, label + "-key"); } + private static ObjectIdentifier oid(KnownOIDs o) { + return ObjectIdentifier.of(o); + } + static OutputAnalyzer keytool(String s) throws Throwable { return SecurityTools.keytool(s); } diff --git a/test/jdk/sun/security/tools/jarsigner/TimestampCheck.java b/test/jdk/sun/security/tools/jarsigner/TimestampCheck.java index 2f48b511a10..b287aadb774 100644 --- a/test/jdk/sun/security/tools/jarsigner/TimestampCheck.java +++ b/test/jdk/sun/security/tools/jarsigner/TimestampCheck.java @@ -63,6 +63,7 @@ import sun.security.x509.X500Name; /* * @test * @bug 6543842 6543440 6939248 8009636 8024302 8163304 8169911 8180289 8172404 + * 8242151 * @summary checking response of timestamp * @modules java.base/sun.security.pkcs * java.base/sun.security.timestamp @@ -134,7 +135,7 @@ public class TimestampCheck { messageImprint.data.getDerValue()); System.out.println("# AlgorithmId: " + aid); - ObjectIdentifier policyId = new ObjectIdentifier(defaultPolicyId); + ObjectIdentifier policyId = ObjectIdentifier.of(defaultPolicyId); BigInteger nonce = null; while (value.data.available() > 0) { DerValue v = value.data.getDerValue(); @@ -158,7 +159,7 @@ public class TimestampCheck { String alias = path.startsWith("ts") ? path : "ts"; if (path.equals("diffpolicy")) { - policyId = new ObjectIdentifier(defaultPolicyId); + policyId = ObjectIdentifier.of(defaultPolicyId); } DerOutputStream statusInfo = new DerOutputStream(); @@ -230,7 +231,7 @@ public class TimestampCheck { alias, "changeit".toCharArray()))); sig.update(tstInfo.toByteArray()); - ContentInfo contentInfo = new ContentInfo(new ObjectIdentifier( + ContentInfo contentInfo = new ContentInfo(ObjectIdentifier.of( "1.2.840.113549.1.9.16.1.4"), new DerValue(tstInfo2.toByteArray())); diff --git a/test/jdk/sun/security/tools/keytool/KeyToolTest.java b/test/jdk/sun/security/tools/keytool/KeyToolTest.java index eb52b621cdb..473f1b6f64f 100644 --- a/test/jdk/sun/security/tools/keytool/KeyToolTest.java +++ b/test/jdk/sun/security/tools/keytool/KeyToolTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2019, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 6251120 8231950 + * @bug 6251120 8231950 8242151 * @summary Testing keytool * * Run through autotest.sh and manualtest.sh @@ -1602,7 +1602,7 @@ public class KeyToolTest { int pos = 0; System.err.print("x"); Extension ex = ((X509CertImpl)ks.getCertificate(alias)) - .getExtension(new ObjectIdentifier(oid)); + .getExtension(ObjectIdentifier.of(oid)); if (!Arrays.equals(value, ex.getValue())) { throw new RuntimeException("Not same content in " + alias + " for " + oid); @@ -1611,9 +1611,9 @@ public class KeyToolTest { } CheckOid coid = new CheckOid(); assertTrue(((X509CertImpl)ks.getCertificate("oid1")) - .getExtension(new ObjectIdentifier("1.2.3")).isCritical()); + .getExtension(ObjectIdentifier.of("1.2.3")).isCritical()); assertTrue(!((X509CertImpl)ks.getCertificate("oid2")) - .getExtension(new ObjectIdentifier("1.2.3")).isCritical()); + .getExtension(ObjectIdentifier.of("1.2.3")).isCritical()); coid.check(ks, "oid1", "1.2.3", new byte[]{1,2}); coid.check(ks, "oid2", "1.2.3", new byte[]{}); coid.check(ks, "oid12", "1.2.3", new byte[]{}); @@ -1643,14 +1643,14 @@ public class KeyToolTest { assertTrue(a.getAuthorityKeyIdentifierExtension() != null); assertTrue(a.getSubjectKeyIdentifierExtension() != null); assertTrue(a.getKeyUsage() == null); - assertTrue(a.getExtension(new ObjectIdentifier("1.2.3")).isCritical()); - assertTrue(!a.getExtension(new ObjectIdentifier("1.2.4")).isCritical()); - assertTrue(!a.getExtension(new ObjectIdentifier("1.2.5")).isCritical()); + assertTrue(a.getExtension(ObjectIdentifier.of("1.2.3")).isCritical()); + assertTrue(!a.getExtension(ObjectIdentifier.of("1.2.4")).isCritical()); + assertTrue(!a.getExtension(ObjectIdentifier.of("1.2.5")).isCritical()); assertTrue(a.getExtensionValue("1.2.3").length == 3); assertTrue(a.getExtensionValue("1.2.4").length == 4); assertTrue(a.getExtensionValue("1.2.5").length == 5); assertTrue(a.getBasicConstraints() == 2); - assertTrue(!a.getExtension(new ObjectIdentifier("2.3.4")).isCritical()); + assertTrue(!a.getExtension(ObjectIdentifier.of("2.3.4")).isCritical()); assertTrue(a.getExtensionValue("2.3.4").length == 6); // 8073181: keytool -ext honored not working correctly @@ -1660,8 +1660,8 @@ public class KeyToolTest { testOK("", simple+"-importcert -file test2.cert -alias b"); ks = loadStore("x.jks", "changeit", "JKS"); X509CertImpl b = (X509CertImpl)ks.getCertificate("b"); - assertTrue(!b.getExtension(new ObjectIdentifier("1.2.3")).isCritical()); - assertTrue(b.getExtension(new ObjectIdentifier("1.2.4")).isCritical()); + assertTrue(!b.getExtension(ObjectIdentifier.of("1.2.3")).isCritical()); + assertTrue(b.getExtension(ObjectIdentifier.of("1.2.4")).isCritical()); // 8073182: keytool may generate duplicate extensions testOK("", pre+"dup -ext bc=2 -ext 2.5.29.19=30030101FF -ext bc=3"); diff --git a/test/jdk/sun/security/util/Oid/OidEquals.java b/test/jdk/sun/security/util/Oid/OidEquals.java index 5dfd7b2b929..3c408452859 100644 --- a/test/jdk/sun/security/util/Oid/OidEquals.java +++ b/test/jdk/sun/security/util/Oid/OidEquals.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8022444 + * @bug 8022444 8242151 * @summary Test ObjectIdentifier.equals(Object obj) * @modules java.base/sun.security.util */ @@ -32,8 +32,8 @@ import sun.security.util.ObjectIdentifier; public class OidEquals { public static void main(String[] args) throws Exception { - ObjectIdentifier oid1 = new ObjectIdentifier("1.3.6.1.4.1.42.2.17"); - ObjectIdentifier oid2 = new ObjectIdentifier("1.2.3.4"); + ObjectIdentifier oid1 = ObjectIdentifier.of("1.3.6.1.4.1.42.2.17"); + ObjectIdentifier oid2 = ObjectIdentifier.of("1.2.3.4"); assertEquals(oid1, oid1); assertNotEquals(oid1, oid2); diff --git a/test/jdk/sun/security/util/Oid/OidFormat.java b/test/jdk/sun/security/util/Oid/OidFormat.java index c37997d45df..975cf9d021d 100644 --- a/test/jdk/sun/security/util/Oid/OidFormat.java +++ b/test/jdk/sun/security/util/Oid/OidFormat.java @@ -24,9 +24,7 @@ /* * @test * @author Weijun Wang - * @bug 6418422 - * @bug 6418425 - * @bug 6418433 + * @bug 6418422 6418425 6418433 8242151 * @summary ObjectIdentifier should reject 1.2.3.-4 and throw IOException on all format errors * @modules java.base/sun.security.util * java.security.jgss @@ -90,7 +88,7 @@ public class OidFormat { static void testGood(String s) throws Exception { System.err.println("Trying " + s); - ObjectIdentifier oid = new ObjectIdentifier(s); + ObjectIdentifier oid = ObjectIdentifier.of(s); if (!oid.toString().equals(s)) { throw new Exception("equal test fail"); } @@ -106,7 +104,7 @@ public class OidFormat { static void testBad(String s) throws Exception { System.err.println("Trying " + s); try { - new ObjectIdentifier(s); + ObjectIdentifier.of(s); throw new Exception("should be invalid ObjectIdentifier"); } catch (IOException ioe) { System.err.println(ioe); diff --git a/test/jdk/sun/security/util/Oid/S11N.java b/test/jdk/sun/security/util/Oid/S11N.java index b522885d89e..2854b25a15b 100644 --- a/test/jdk/sun/security/util/Oid/S11N.java +++ b/test/jdk/sun/security/util/Oid/S11N.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2015, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 4811968 6908628 8006564 8130696 + * @bug 4811968 6908628 8006564 8130696 8242151 * @modules java.base/sun.security.util * @run main S11N check * @summary Serialization compatibility with old versions (and fixes) @@ -118,7 +118,7 @@ public class S11N { // Gets the serialized form for this java private static byte[] out(String oid) throws Exception { ByteArrayOutputStream bout = new ByteArrayOutputStream(); - new ObjectOutputStream(bout).writeObject(new ObjectIdentifier(oid)); + new ObjectOutputStream(bout).writeObject(ObjectIdentifier.of(oid)); return bout.toByteArray(); } diff --git a/test/jdk/sun/security/x509/AVA/AVAEqualsHashCode.java b/test/jdk/sun/security/x509/AVA/AVAEqualsHashCode.java index 55d114d9410..b0d85f2a11a 100644 --- a/test/jdk/sun/security/x509/AVA/AVAEqualsHashCode.java +++ b/test/jdk/sun/security/x509/AVA/AVAEqualsHashCode.java @@ -24,7 +24,7 @@ /* * @test * @author Gary Ellison - * @bug 4170635 + * @bug 4170635 8242151 * @summary Verify equals()/hashCode() contract honored * @modules java.base/sun.security.util * java.base/sun.security.x509 @@ -44,7 +44,7 @@ public class AVAEqualsHashCode { String name = "CN=eve s. dropper"; X500Name dn = new X500Name(name); DerOutputStream deros = new DerOutputStream(); - ObjectIdentifier oid = new ObjectIdentifier("1.2.840.113549.2.5"); + ObjectIdentifier oid = ObjectIdentifier.of("1.2.840.113549.2.5"); dn.encode(deros); byte[] ba = deros.toByteArray(); diff --git a/test/jdk/sun/security/x509/AlgorithmId/ExtensibleAlgorithmId.java b/test/jdk/sun/security/x509/AlgorithmId/ExtensibleAlgorithmId.java index a9322dc2f51..2830caafd7a 100644 --- a/test/jdk/sun/security/x509/AlgorithmId/ExtensibleAlgorithmId.java +++ b/test/jdk/sun/security/x509/AlgorithmId/ExtensibleAlgorithmId.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,8 +23,9 @@ /* * @test - * @bug 4162868 8130181 + * @bug 4162868 8130181 8242151 * @modules java.base/sun.security.x509 + * @modules java.base/sun.security.util * @run main/othervm ExtensibleAlgorithmId * @summary Algorithm Name-to-OID mapping needs to be made extensible. */ @@ -39,31 +40,43 @@ public class ExtensibleAlgorithmId { public static void main(String[] args) throws Exception { TestProvider p = new TestProvider(); Security.addProvider(p); - AlgorithmId algid = AlgorithmId.getAlgorithmId("XYZ"); - String alias = "Alg.Alias.Signature.OID." + algid.toString(); + AlgorithmId algid = AlgorithmId.getAlgorithmId(TestProvider.ALG_NAME); + String oid = algid.getOID().toString(); + if (!oid.equals(TestProvider.ALG_OID)) { + throw new Exception("Provider alias oid not used, found " + oid); + } + String name = algid.getName(); + if (!name.equalsIgnoreCase(TestProvider.ALG_NAME)) { + throw new Exception("provider alias name not used, found " + name); + } + String alias = "Alg.Alias.Signature.OID." + oid; String stdAlgName = p.getProperty(alias); - if (stdAlgName == null || !stdAlgName.equalsIgnoreCase("XYZ")) { + if (stdAlgName == null || + !stdAlgName.equalsIgnoreCase(TestProvider.ALG_NAME)) { throw new Exception("Wrong OID"); } } -} -class TestProvider extends Provider { + static class TestProvider extends Provider { - public TestProvider() { + static String ALG_OID = "1.2.3.4.5.6.7.8.9.0"; + static String ALG_NAME = "XYZ"; + + public TestProvider() { super("Dummy", "1.0", "XYZ algorithm"); - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { - put("Signature.XYZ", "test.xyz"); - // preferred OID - put("Alg.Alias.Signature.OID.1.2.3.4.5.6.7.8.9.0", - "XYZ"); - put("Alg.Alias.Signature.9.8.7.6.5.4.3.2.1.0", - "XYZ"); - return null; - } - }); + put("Signature." + ALG_NAME, "test.xyz"); + // preferred OID + put("Alg.Alias.Signature.OID." + ALG_OID, + ALG_NAME); + put("Alg.Alias.Signature.9.8.7.6.5.4.3.2.1.0", + ALG_NAME); + return null; + } + }); + } } } diff --git a/test/jdk/sun/security/x509/X509CertImpl/V3Certificate.java b/test/jdk/sun/security/x509/X509CertImpl/V3Certificate.java index 4dc4b921cb4..95741c9f54f 100644 --- a/test/jdk/sun/security/x509/X509CertImpl/V3Certificate.java +++ b/test/jdk/sun/security/x509/X509CertImpl/V3Certificate.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8049237 + * @bug 8049237 8242151 * @modules java.base/sun.security.x509 * java.base/sun.security.util * jdk.crypto.ec @@ -155,7 +155,7 @@ public class V3Certificate { GeneralName ip = new GeneralName(ipInf); GeneralNameInterface oidInf = - new OIDName(new ObjectIdentifier("1.2.3.4")); + new OIDName(ObjectIdentifier.of("1.2.3.4")); GeneralName oid = new GeneralName(oidInf); SubjectAlternativeNameExtension subjectName diff --git a/test/jdk/sun/security/x509/equalNames/AltNamesEqualsTest.java b/test/jdk/sun/security/x509/equalNames/AltNamesEqualsTest.java index 8ffe02e1cec..b4136506727 100644 --- a/test/jdk/sun/security/x509/equalNames/AltNamesEqualsTest.java +++ b/test/jdk/sun/security/x509/equalNames/AltNamesEqualsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2007, 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 @@ -24,7 +24,7 @@ /* * @test * @summary Make sure names that are equal are treated as such. - * @bug 4273559 + * @bug 4273559 8242151 * @author Yassir Elley * @modules java.base/sun.security.util * java.base/sun.security.x509 @@ -114,7 +114,7 @@ public class AltNamesEqualsTest{ throws Exception { OIDName oidName = null; - ObjectIdentifier oid = new ObjectIdentifier(name); + ObjectIdentifier oid = ObjectIdentifier.of(name); oidName = new OIDName(oid); return oidName; } From cc3a8595a4dfab55c411dbceac76a95728f10294 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Lid=C3=A9n?= Date: Tue, 19 May 2020 08:34:13 +0200 Subject: [PATCH 108/143] 8245233: ZGC: Load volatile oops using Atomic::load() Reviewed-by: stefank, kbarrett, smonteith --- src/hotspot/share/gc/z/zBarrier.inline.hpp | 14 +++++++------- src/hotspot/share/gc/z/zReferenceProcessor.cpp | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/hotspot/share/gc/z/zBarrier.inline.hpp b/src/hotspot/share/gc/z/zBarrier.inline.hpp index 9a1905f0b2d..55a7bb5c521 100644 --- a/src/hotspot/share/gc/z/zBarrier.inline.hpp +++ b/src/hotspot/share/gc/z/zBarrier.inline.hpp @@ -228,7 +228,7 @@ inline oop ZBarrier::load_barrier_on_oop(oop o) { } inline oop ZBarrier::load_barrier_on_oop_field(volatile oop* p) { - const oop o = *p; + const oop o = Atomic::load(p); return load_barrier_on_oop_field_preloaded(p, o); } @@ -282,7 +282,7 @@ inline void ZBarrier::load_barrier_on_root_oop_field(oop* p) { // inline oop ZBarrier::weak_load_barrier_on_oop_field(volatile oop* p) { assert(!ZResurrection::is_blocked(), "Should not be called during resurrection blocked phase"); - const oop o = *p; + const oop o = Atomic::load(p); return weak_load_barrier_on_oop_field_preloaded(p, o); } @@ -295,7 +295,7 @@ inline oop ZBarrier::weak_load_barrier_on_weak_oop(oop o) { } inline oop ZBarrier::weak_load_barrier_on_weak_oop_field(volatile oop* p) { - const oop o = *p; + const oop o = Atomic::load(p); return weak_load_barrier_on_weak_oop_field_preloaded(p, o); } @@ -314,7 +314,7 @@ inline oop ZBarrier::weak_load_barrier_on_phantom_oop(oop o) { } inline oop ZBarrier::weak_load_barrier_on_phantom_oop_field(volatile oop* p) { - const oop o = *p; + const oop o = Atomic::load(p); return weak_load_barrier_on_phantom_oop_field_preloaded(p, o); } @@ -349,14 +349,14 @@ inline bool ZBarrier::is_alive_barrier_on_phantom_oop(oop o) { inline void ZBarrier::keep_alive_barrier_on_weak_oop_field(volatile oop* p) { // This operation is only valid when resurrection is blocked. assert(ZResurrection::is_blocked(), "Invalid phase"); - const oop o = *p; + const oop o = Atomic::load(p); barrier(p, o); } inline void ZBarrier::keep_alive_barrier_on_phantom_oop_field(volatile oop* p) { // This operation is only valid when resurrection is blocked. assert(ZResurrection::is_blocked(), "Invalid phase"); - const oop o = *p; + const oop o = Atomic::load(p); barrier(p, o); } @@ -380,7 +380,7 @@ inline void ZBarrier::keep_alive_barrier_on_oop(oop o) { // Mark barrier // inline void ZBarrier::mark_barrier_on_oop_field(volatile oop* p, bool finalizable) { - const oop o = *p; + const oop o = Atomic::load(p); if (finalizable) { barrier(p, o); diff --git a/src/hotspot/share/gc/z/zReferenceProcessor.cpp b/src/hotspot/share/gc/z/zReferenceProcessor.cpp index e1cd3ef0893..1d59fee3408 100644 --- a/src/hotspot/share/gc/z/zReferenceProcessor.cpp +++ b/src/hotspot/share/gc/z/zReferenceProcessor.cpp @@ -70,7 +70,7 @@ static volatile oop* reference_referent_addr(oop reference) { } static oop reference_referent(oop reference) { - return *reference_referent_addr(reference); + return Atomic::load(reference_referent_addr(reference)); } static void reference_set_referent(oop reference, oop referent) { From ce6aadbd2f2a2f35241024a3c5e777ef5738e642 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Lid=C3=A9n?= Date: Tue, 19 May 2020 08:34:14 +0200 Subject: [PATCH 109/143] 8245196: ZGC: No need to disable UseBiasedLocking by default Reviewed-by: tschatzl, kbarrett --- src/hotspot/share/gc/z/zArguments.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/hotspot/share/gc/z/zArguments.cpp b/src/hotspot/share/gc/z/zArguments.cpp index e227bddf7e7..d0ac506130b 100644 --- a/src/hotspot/share/gc/z/zArguments.cpp +++ b/src/hotspot/share/gc/z/zArguments.cpp @@ -52,11 +52,6 @@ void ZArguments::initialize() { FLAG_SET_DEFAULT(UseNUMA, true); } - // Disable biased locking by default - if (FLAG_IS_DEFAULT(UseBiasedLocking)) { - FLAG_SET_DEFAULT(UseBiasedLocking, false); - } - // Select number of parallel threads if (FLAG_IS_DEFAULT(ParallelGCThreads)) { FLAG_SET_DEFAULT(ParallelGCThreads, ZHeuristics::nparallel_workers()); From bcf99aa98ecc3c09b8148b5017169f3029c4b5be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Lid=C3=A9n?= Date: Tue, 19 May 2020 08:34:14 +0200 Subject: [PATCH 110/143] 8245098: Make SafeFetch32/N available earlier Reviewed-by: kbarrett, dholmes --- .../cpu/aarch64/stubGenerator_aarch64.cpp | 15 ++++++++------- src/hotspot/cpu/arm/stubGenerator_arm.cpp | 18 +++++++++--------- src/hotspot/cpu/ppc/stubGenerator_ppc.cpp | 16 ++++++++-------- src/hotspot/cpu/s390/stubGenerator_s390.cpp | 8 ++++---- src/hotspot/cpu/sparc/stubGenerator_sparc.cpp | 16 ++++++++-------- src/hotspot/cpu/x86/stubGenerator_x86_32.cpp | 16 ++++++++-------- src/hotspot/cpu/x86/stubGenerator_x86_64.cpp | 16 ++++++++-------- 7 files changed, 53 insertions(+), 52 deletions(-) diff --git a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp index c872e56ae36..2a67c21cb94 100644 --- a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp @@ -5748,6 +5748,14 @@ class StubGenerator: public StubCodeGenerator { if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dcos)) { StubRoutines::_dcos = generate_dsin_dcos(/* isCos = */ true); } + + // Safefetch stubs. + generate_safefetch("SafeFetch32", sizeof(int), &StubRoutines::_safefetch32_entry, + &StubRoutines::_safefetch32_fault_pc, + &StubRoutines::_safefetch32_continuation_pc); + generate_safefetch("SafeFetchN", sizeof(intptr_t), &StubRoutines::_safefetchN_entry, + &StubRoutines::_safefetchN_fault_pc, + &StubRoutines::_safefetchN_continuation_pc); } void generate_all() { @@ -5851,13 +5859,6 @@ class StubGenerator: public StubCodeGenerator { StubRoutines::_updateBytesAdler32 = generate_updateBytesAdler32(); } - // Safefetch stubs. - generate_safefetch("SafeFetch32", sizeof(int), &StubRoutines::_safefetch32_entry, - &StubRoutines::_safefetch32_fault_pc, - &StubRoutines::_safefetch32_continuation_pc); - generate_safefetch("SafeFetchN", sizeof(intptr_t), &StubRoutines::_safefetchN_entry, - &StubRoutines::_safefetchN_fault_pc, - &StubRoutines::_safefetchN_continuation_pc); StubRoutines::aarch64::set_completed(); } diff --git a/src/hotspot/cpu/arm/stubGenerator_arm.cpp b/src/hotspot/cpu/arm/stubGenerator_arm.cpp index fd82a6d20bb..d90b4cec39a 100644 --- a/src/hotspot/cpu/arm/stubGenerator_arm.cpp +++ b/src/hotspot/cpu/arm/stubGenerator_arm.cpp @@ -3028,6 +3028,15 @@ class StubGenerator: public StubCodeGenerator { StubRoutines::_atomic_cmpxchg_long_entry = generate_atomic_cmpxchg_long(); StubRoutines::_atomic_load_long_entry = generate_atomic_load_long(); StubRoutines::_atomic_store_long_entry = generate_atomic_store_long(); + + // Safefetch stubs. + generate_safefetch("SafeFetch32", sizeof(int), &StubRoutines::_safefetch32_entry, + &StubRoutines::_safefetch32_fault_pc, + &StubRoutines::_safefetch32_continuation_pc); + assert (sizeof(int) == wordSize, "32-bit architecture"); + StubRoutines::_safefetchN_entry = StubRoutines::_safefetch32_entry; + StubRoutines::_safefetchN_fault_pc = StubRoutines::_safefetch32_fault_pc; + StubRoutines::_safefetchN_continuation_pc = StubRoutines::_safefetch32_continuation_pc; } void generate_all() { @@ -3053,15 +3062,6 @@ class StubGenerator: public StubCodeGenerator { // arraycopy stubs used by compilers generate_arraycopy_stubs(); - // Safefetch stubs. - generate_safefetch("SafeFetch32", sizeof(int), &StubRoutines::_safefetch32_entry, - &StubRoutines::_safefetch32_fault_pc, - &StubRoutines::_safefetch32_continuation_pc); - assert (sizeof(int) == wordSize, "32-bit architecture"); - StubRoutines::_safefetchN_entry = StubRoutines::_safefetch32_entry; - StubRoutines::_safefetchN_fault_pc = StubRoutines::_safefetch32_fault_pc; - StubRoutines::_safefetchN_continuation_pc = StubRoutines::_safefetch32_continuation_pc; - #ifdef COMPILE_CRYPTO // generate AES intrinsics code if (UseAESIntrinsics) { diff --git a/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp b/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp index 071ee8ce7fd..b9bbd509434 100644 --- a/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp +++ b/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp @@ -3577,6 +3577,14 @@ class StubGenerator: public StubCodeGenerator { StubRoutines::_crc32c_table_addr = StubRoutines::generate_crc_constants(REVERSE_CRC32C_POLY); StubRoutines::_updateBytesCRC32C = generate_CRC32_updateBytes(true); } + + // Safefetch stubs. + generate_safefetch("SafeFetch32", sizeof(int), &StubRoutines::_safefetch32_entry, + &StubRoutines::_safefetch32_fault_pc, + &StubRoutines::_safefetch32_continuation_pc); + generate_safefetch("SafeFetchN", sizeof(intptr_t), &StubRoutines::_safefetchN_entry, + &StubRoutines::_safefetchN_fault_pc, + &StubRoutines::_safefetchN_continuation_pc); } void generate_all() { @@ -3595,14 +3603,6 @@ class StubGenerator: public StubCodeGenerator { // arraycopy stubs used by compilers generate_arraycopy_stubs(); - // Safefetch stubs. - generate_safefetch("SafeFetch32", sizeof(int), &StubRoutines::_safefetch32_entry, - &StubRoutines::_safefetch32_fault_pc, - &StubRoutines::_safefetch32_continuation_pc); - generate_safefetch("SafeFetchN", sizeof(intptr_t), &StubRoutines::_safefetchN_entry, - &StubRoutines::_safefetchN_fault_pc, - &StubRoutines::_safefetchN_continuation_pc); - #ifdef COMPILER2 if (UseMultiplyToLenIntrinsic) { StubRoutines::_multiplyToLen = generate_multiplyToLen(); diff --git a/src/hotspot/cpu/s390/stubGenerator_s390.cpp b/src/hotspot/cpu/s390/stubGenerator_s390.cpp index f5540d41fe2..0ccc224fc88 100644 --- a/src/hotspot/cpu/s390/stubGenerator_s390.cpp +++ b/src/hotspot/cpu/s390/stubGenerator_s390.cpp @@ -2337,6 +2337,10 @@ class StubGenerator: public StubCodeGenerator { // Comapct string intrinsics: Translate table for string inflate intrinsic. Used by trot instruction. StubRoutines::zarch::_trot_table_addr = (address)StubRoutines::zarch::_trot_table; + + // safefetch stubs + generate_safefetch("SafeFetch32", sizeof(int), &StubRoutines::_safefetch32_entry, &StubRoutines::_safefetch32_fault_pc, &StubRoutines::_safefetch32_continuation_pc); + generate_safefetch("SafeFetchN", sizeof(intptr_t), &StubRoutines::_safefetchN_entry, &StubRoutines::_safefetchN_fault_pc, &StubRoutines::_safefetchN_continuation_pc); } @@ -2356,10 +2360,6 @@ class StubGenerator: public StubCodeGenerator { // Arraycopy stubs used by compilers. generate_arraycopy_stubs(); - // safefetch stubs - generate_safefetch("SafeFetch32", sizeof(int), &StubRoutines::_safefetch32_entry, &StubRoutines::_safefetch32_fault_pc, &StubRoutines::_safefetch32_continuation_pc); - generate_safefetch("SafeFetchN", sizeof(intptr_t), &StubRoutines::_safefetchN_entry, &StubRoutines::_safefetchN_fault_pc, &StubRoutines::_safefetchN_continuation_pc); - // Generate AES intrinsics code. if (UseAESIntrinsics) { StubRoutines::_aescrypt_encryptBlock = generate_AES_encryptBlock("AES_encryptBlock"); diff --git a/src/hotspot/cpu/sparc/stubGenerator_sparc.cpp b/src/hotspot/cpu/sparc/stubGenerator_sparc.cpp index ec377fae0d6..09a9fa32839 100644 --- a/src/hotspot/cpu/sparc/stubGenerator_sparc.cpp +++ b/src/hotspot/cpu/sparc/stubGenerator_sparc.cpp @@ -5744,6 +5744,14 @@ class StubGenerator: public StubCodeGenerator { StubRoutines::_crc32c_table_addr = (address)StubRoutines::Sparc::_crc32c_table; StubRoutines::_updateBytesCRC32C = generate_updateBytesCRC32C(); } + + // Safefetch stubs. + generate_safefetch("SafeFetch32", sizeof(int), &StubRoutines::_safefetch32_entry, + &StubRoutines::_safefetch32_fault_pc, + &StubRoutines::_safefetch32_continuation_pc); + generate_safefetch("SafeFetchN", sizeof(intptr_t), &StubRoutines::_safefetchN_entry, + &StubRoutines::_safefetchN_fault_pc, + &StubRoutines::_safefetchN_continuation_pc); } @@ -5767,14 +5775,6 @@ class StubGenerator: public StubCodeGenerator { // Don't initialize the platform math functions since sparc // doesn't have intrinsics for these operations. - // Safefetch stubs. - generate_safefetch("SafeFetch32", sizeof(int), &StubRoutines::_safefetch32_entry, - &StubRoutines::_safefetch32_fault_pc, - &StubRoutines::_safefetch32_continuation_pc); - generate_safefetch("SafeFetchN", sizeof(intptr_t), &StubRoutines::_safefetchN_entry, - &StubRoutines::_safefetchN_fault_pc, - &StubRoutines::_safefetchN_continuation_pc); - // generate AES intrinsics code if (UseAESIntrinsics) { StubRoutines::_aescrypt_encryptBlock = generate_aescrypt_encryptBlock(); diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_32.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_32.cpp index 9fce7d49200..b04ff9d261b 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_32.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_32.cpp @@ -3870,6 +3870,14 @@ class StubGenerator: public StubCodeGenerator { StubRoutines::_dtan = generate_libmTan(); } } + + // Safefetch stubs. + generate_safefetch("SafeFetch32", sizeof(int), &StubRoutines::_safefetch32_entry, + &StubRoutines::_safefetch32_fault_pc, + &StubRoutines::_safefetch32_continuation_pc); + StubRoutines::_safefetchN_entry = StubRoutines::_safefetch32_entry; + StubRoutines::_safefetchN_fault_pc = StubRoutines::_safefetch32_fault_pc; + StubRoutines::_safefetchN_continuation_pc = StubRoutines::_safefetch32_continuation_pc; } void generate_all() { @@ -3933,14 +3941,6 @@ class StubGenerator: public StubCodeGenerator { StubRoutines::_ghash_processBlocks = generate_ghash_processBlocks(); } - // Safefetch stubs. - generate_safefetch("SafeFetch32", sizeof(int), &StubRoutines::_safefetch32_entry, - &StubRoutines::_safefetch32_fault_pc, - &StubRoutines::_safefetch32_continuation_pc); - StubRoutines::_safefetchN_entry = StubRoutines::_safefetch32_entry; - StubRoutines::_safefetchN_fault_pc = StubRoutines::_safefetch32_fault_pc; - StubRoutines::_safefetchN_continuation_pc = StubRoutines::_safefetch32_continuation_pc; - BarrierSetNMethod* bs_nm = BarrierSet::barrier_set()->barrier_set_nmethod(); if (bs_nm != NULL) { StubRoutines::x86::_method_entry_barrier = generate_method_entry_barrier(); diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp index 4037c6648fb..9de5886755a 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp @@ -6414,6 +6414,14 @@ address generate_avx_ghash_processBlocks() { StubRoutines::_dtan = generate_libmTan(); } } + + // Safefetch stubs. + generate_safefetch("SafeFetch32", sizeof(int), &StubRoutines::_safefetch32_entry, + &StubRoutines::_safefetch32_fault_pc, + &StubRoutines::_safefetch32_continuation_pc); + generate_safefetch("SafeFetchN", sizeof(intptr_t), &StubRoutines::_safefetchN_entry, + &StubRoutines::_safefetchN_fault_pc, + &StubRoutines::_safefetchN_continuation_pc); } void generate_all() { @@ -6533,14 +6541,6 @@ address generate_avx_ghash_processBlocks() { StubRoutines::_base64_encodeBlock = generate_base64_encodeBlock(); } - // Safefetch stubs. - generate_safefetch("SafeFetch32", sizeof(int), &StubRoutines::_safefetch32_entry, - &StubRoutines::_safefetch32_fault_pc, - &StubRoutines::_safefetch32_continuation_pc); - generate_safefetch("SafeFetchN", sizeof(intptr_t), &StubRoutines::_safefetchN_entry, - &StubRoutines::_safefetchN_fault_pc, - &StubRoutines::_safefetchN_continuation_pc); - BarrierSetNMethod* bs_nm = BarrierSet::barrier_set()->barrier_set_nmethod(); if (bs_nm != NULL) { StubRoutines::x86::_method_entry_barrier = generate_method_entry_barrier(); From 8ec7512fecd9c40cc3afcbd9b26cb294e7f79997 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20Lid=C3=A9n?= Date: Tue, 19 May 2020 08:34:14 +0200 Subject: [PATCH 111/143] 8245106: ZGC: Fix incorrect setup when using -XX:+UseTransparentHugePages Reviewed-by: stefank, eosterlund --- .../gc/z/zPhysicalMemoryBacking_linux.cpp | 74 ++++++++++++++++--- .../gc/z/zPhysicalMemoryBacking_linux.hpp | 3 +- src/hotspot/share/gc/z/zPhysicalMemory.cpp | 5 -- 3 files changed, 67 insertions(+), 15 deletions(-) diff --git a/src/hotspot/os/linux/gc/z/zPhysicalMemoryBacking_linux.cpp b/src/hotspot/os/linux/gc/z/zPhysicalMemoryBacking_linux.cpp index fd011b22102..12d9ce15314 100644 --- a/src/hotspot/os/linux/gc/z/zPhysicalMemoryBacking_linux.cpp +++ b/src/hotspot/os/linux/gc/z/zPhysicalMemoryBacking_linux.cpp @@ -33,6 +33,7 @@ #include "logging/log.hpp" #include "runtime/init.hpp" #include "runtime/os.hpp" +#include "runtime/stubRoutines.hpp" #include "utilities/align.hpp" #include "utilities/debug.hpp" #include "utilities/growableArray.hpp" @@ -390,7 +391,7 @@ ZErrno ZPhysicalMemoryBacking::fallocate_compat_ftruncate(size_t size) const { return 0; } -ZErrno ZPhysicalMemoryBacking::fallocate_compat_mmap(size_t offset, size_t length, bool touch) const { +ZErrno ZPhysicalMemoryBacking::fallocate_compat_mmap_hugetlbfs(size_t offset, size_t length, bool touch) const { // On hugetlbfs, mapping a file segment will fail immediately, without // the need to touch the mapped pages first, if there aren't enough huge // pages available to back the mapping. @@ -410,7 +411,8 @@ ZErrno ZPhysicalMemoryBacking::fallocate_compat_mmap(size_t offset, size_t lengt } // Unmap again. From now on, the huge pages that were mapped are allocated - // to this file. There's no risk in getting SIGBUS when touching them. + // to this file. There's no risk of getting a SIGBUS when mapping and + // touching these pages again. if (munmap(addr, length) == -1) { // Failed return errno; @@ -420,6 +422,53 @@ ZErrno ZPhysicalMemoryBacking::fallocate_compat_mmap(size_t offset, size_t lengt return 0; } +static bool safe_touch_mapping(void* addr, size_t length, size_t page_size) { + char* const start = (char*)addr; + char* const end = start + length; + + // Touching a mapping that can't be backed by memory will generate a + // SIGBUS. By using SafeFetch32 any SIGBUS will be safely caught and + // handled. On tmpfs, doing a fetch (rather than a store) is enough + // to cause backing pages to be allocated (there's no zero-page to + // worry about). + for (char *p = start; p < end; p += page_size) { + if (SafeFetch32((int*)p, -1) == -1) { + // Failed + return false; + } + } + + // Success + return true; +} + +ZErrno ZPhysicalMemoryBacking::fallocate_compat_mmap_tmpfs(size_t offset, size_t length) const { + // On tmpfs, we need to touch the mapped pages to figure out + // if there are enough pages available to back the mapping. + void* const addr = mmap(0, length, PROT_READ|PROT_WRITE, MAP_SHARED, _fd, offset); + if (addr == MAP_FAILED) { + // Failed + return errno; + } + + // Advise mapping to use transparent huge pages + os::realign_memory((char*)addr, length, os::large_page_size()); + + // Touch the mapping (safely) to make sure it's backed by memory + const bool backed = safe_touch_mapping(addr, length, _block_size); + + // Unmap again. If successfully touched, the backing memory will + // be allocated to this file. There's no risk of getting a SIGBUS + // when mapping and touching these pages again. + if (munmap(addr, length) == -1) { + // Failed + return errno; + } + + // Success + return backed ? 0 : ENOMEM; +} + ZErrno ZPhysicalMemoryBacking::fallocate_compat_pwrite(size_t offset, size_t length) const { uint8_t data = 0; @@ -438,7 +487,8 @@ ZErrno ZPhysicalMemoryBacking::fallocate_compat_pwrite(size_t offset, size_t len ZErrno ZPhysicalMemoryBacking::fallocate_fill_hole_compat(size_t offset, size_t length) { // fallocate(2) is only supported by tmpfs since Linux 3.5, and by hugetlbfs // since Linux 4.3. When fallocate(2) is not supported we emulate it using - // ftruncate/pwrite (for tmpfs) or ftruncate/mmap/munmap (for hugetlbfs). + // mmap/munmap (for hugetlbfs and tmpfs with transparent huge pages) or pwrite + // (for tmpfs without transparent huge pages and other filesystem types). const size_t end = offset + length; if (end > _size) { @@ -451,8 +501,12 @@ ZErrno ZPhysicalMemoryBacking::fallocate_fill_hole_compat(size_t offset, size_t } // Allocate backing memory - const ZErrno err = is_hugetlbfs() ? fallocate_compat_mmap(offset, length, false /* touch */) - : fallocate_compat_pwrite(offset, length); + const ZErrno err = ZLargePages::is_explicit() + ? fallocate_compat_mmap_hugetlbfs(offset, length, false /* touch */) + : (ZLargePages::is_transparent() + ? fallocate_compat_mmap_tmpfs(offset, length) + : fallocate_compat_pwrite(offset, length)); + if (err) { if (end > _size) { // Restore file size @@ -495,7 +549,9 @@ ZErrno ZPhysicalMemoryBacking::fallocate_fill_hole(size_t offset, size_t length) // Note that allocating huge pages this way will only reserve them, and not // associate them with segments of the file. We must guarantee that we at // some point touch these segments, otherwise we can not punch hole in them. - if (z_fallocate_supported && !is_hugetlbfs()) { + // Also note that we need to use compat mode when using transparent huge pages, + // since we need to use madvise(2) on the mapping before the page is allocated. + if (z_fallocate_supported && !ZLargePages::is_enabled()) { const ZErrno err = fallocate_fill_hole_syscall(offset, length); if (!err) { // Success @@ -516,12 +572,12 @@ ZErrno ZPhysicalMemoryBacking::fallocate_fill_hole(size_t offset, size_t length) } ZErrno ZPhysicalMemoryBacking::fallocate_punch_hole(size_t offset, size_t length) { - if (is_hugetlbfs()) { + if (ZLargePages::is_explicit()) { // We can only punch hole in pages that have been touched. Non-touched // pages are only reserved, and not associated with any specific file // segment. We don't know which pages have been previously touched, so // we always touch them here to guarantee that we can punch hole. - const ZErrno err = fallocate_compat_mmap(offset, length, true /* touch */); + const ZErrno err = fallocate_compat_mmap_hugetlbfs(offset, length, true /* touch */); if (err) { // Failed return err; @@ -582,7 +638,7 @@ bool ZPhysicalMemoryBacking::commit_inner(size_t offset, size_t length) { retry: const ZErrno err = fallocate(false /* punch_hole */, offset, length); if (err) { - if (err == ENOSPC && !is_init_completed() && is_hugetlbfs() && z_fallocate_hugetlbfs_attempts-- > 0) { + if (err == ENOSPC && !is_init_completed() && ZLargePages::is_explicit() && z_fallocate_hugetlbfs_attempts-- > 0) { // If we fail to allocate during initialization, due to lack of space on // the hugetlbfs filesystem, then we wait and retry a few times before // giving up. Otherwise there is a risk that running JVMs back-to-back diff --git a/src/hotspot/os/linux/gc/z/zPhysicalMemoryBacking_linux.hpp b/src/hotspot/os/linux/gc/z/zPhysicalMemoryBacking_linux.hpp index c5f1583a424..06a13897b5d 100644 --- a/src/hotspot/os/linux/gc/z/zPhysicalMemoryBacking_linux.hpp +++ b/src/hotspot/os/linux/gc/z/zPhysicalMemoryBacking_linux.hpp @@ -47,7 +47,8 @@ private: bool tmpfs_supports_transparent_huge_pages() const; ZErrno fallocate_compat_ftruncate(size_t size) const; - ZErrno fallocate_compat_mmap(size_t offset, size_t length, bool reserve_only) const; + ZErrno fallocate_compat_mmap_hugetlbfs(size_t offset, size_t length, bool touch) const; + ZErrno fallocate_compat_mmap_tmpfs(size_t offset, size_t length) const; ZErrno fallocate_compat_pwrite(size_t offset, size_t length) const; ZErrno fallocate_fill_hole_compat(size_t offset, size_t length); ZErrno fallocate_fill_hole_syscall(size_t offset, size_t length); diff --git a/src/hotspot/share/gc/z/zPhysicalMemory.cpp b/src/hotspot/share/gc/z/zPhysicalMemory.cpp index 350d0065063..57f810a0b71 100644 --- a/src/hotspot/share/gc/z/zPhysicalMemory.cpp +++ b/src/hotspot/share/gc/z/zPhysicalMemory.cpp @@ -284,11 +284,6 @@ void ZPhysicalMemoryManager::map_view(const ZPhysicalMemory& pmem, uintptr_t add // fault time. os::numa_make_global((char*)addr, size); } - - // Setup transparent large pages - if (ZLargePages::is_transparent()) { - os::realign_memory((char*)addr, size, os::large_page_size()); - } } void ZPhysicalMemoryManager::unmap_view(const ZPhysicalMemory& pmem, uintptr_t addr) const { From 77826c0a39efebc6ce10b7b3a344f41c18c93553 Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Tue, 19 May 2020 09:12:10 +0200 Subject: [PATCH 112/143] 8245168: jlink should not be treated as a "small" tool Reviewed-by: erikj --- make/autoconf/spec.gmk.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/make/autoconf/spec.gmk.in b/make/autoconf/spec.gmk.in index 6c214cfb932..10a1fc15931 100644 --- a/make/autoconf/spec.gmk.in +++ b/make/autoconf/spec.gmk.in @@ -642,7 +642,7 @@ JAVA_DETACH =@FIXPATH@ @FIXPATH_DETACH_FLAG@ $(JAVA_CMD) $(JAVA_FLAGS_BIG) $(JAV JAVAC=@FIXPATH@ $(JAVAC_CMD) JAVADOC=@FIXPATH@ $(JAVADOC_CMD) JAR=@FIXPATH@ $(JAR_CMD) -JLINK = @FIXPATH@ $(JLINK_CMD) $(JAVA_TOOL_FLAGS_SMALL) +JLINK = @FIXPATH@ $(JLINK_CMD) JMOD = @FIXPATH@ $(JMOD_CMD) $(JAVA_TOOL_FLAGS_SMALL) JARSIGNER=@FIXPATH@ $(JARSIGNER_CMD) JJS=@FIXPATH@ $(JJS_CMD) $(JAVA_TOOL_FLAGS_SMALL) From 13cf783154ef387301d4a19af30d2304419cc4e3 Mon Sep 17 00:00:00 2001 From: Sibabrata Sahoo Date: Tue, 19 May 2020 02:36:17 -0700 Subject: [PATCH 113/143] 8209632: Develop new tests for EdDSA API New Tests for EdDSA Reviewed-by: ascarpino --- test/jdk/sun/security/ec/ed/EdCRLSign.java | 109 ++++++ .../security/ec/ed/EdDSAKeyCompatibility.java | 222 +++++++++++ test/jdk/sun/security/ec/ed/EdDSAKeySize.java | 221 +++++++++++ .../sun/security/ec/ed/EdDSANegativeTest.java | 299 +++++++++++++++ .../sun/security/ec/ed/EdDSAParamSpec.java | 174 +++++++++ .../sun/security/ec/ed/EdDSAReuseTest.java | 133 +++++++ test/jdk/sun/security/ec/ed/EdDSATest.java | 356 ++++++++++++++++++ 7 files changed, 1514 insertions(+) create mode 100644 test/jdk/sun/security/ec/ed/EdCRLSign.java create mode 100644 test/jdk/sun/security/ec/ed/EdDSAKeyCompatibility.java create mode 100644 test/jdk/sun/security/ec/ed/EdDSAKeySize.java create mode 100644 test/jdk/sun/security/ec/ed/EdDSANegativeTest.java create mode 100644 test/jdk/sun/security/ec/ed/EdDSAParamSpec.java create mode 100644 test/jdk/sun/security/ec/ed/EdDSAReuseTest.java create mode 100644 test/jdk/sun/security/ec/ed/EdDSATest.java diff --git a/test/jdk/sun/security/ec/ed/EdCRLSign.java b/test/jdk/sun/security/ec/ed/EdCRLSign.java new file mode 100644 index 00000000000..d2ac5f76bb8 --- /dev/null +++ b/test/jdk/sun/security/ec/ed/EdCRLSign.java @@ -0,0 +1,109 @@ +/* + * 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.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.SecureRandom; +import java.security.spec.NamedParameterSpec; +import java.util.Date; +import sun.security.x509.X500Name; +import sun.security.x509.X509CRLImpl; + +/* + * @test + * @bug 8209632 + * @summary CRL Sign + * @modules java.base/sun.security.x509 + * @run main EdCRLSign + */ +public class EdCRLSign { + + private static final String ED25519 = "Ed25519"; + private static final String ED448 = "Ed448"; + private static final String OIDN25519 = "1.3.101.112"; + private static final String OID25519 = "OID.1.3.101.112"; + private static final String OIDN448 = "1.3.101.113"; + private static final String OID448 = "OID.1.3.101.113"; + private static final String PROVIDER = "SunEC"; + private static final SecureRandom S_RND = new SecureRandom(new byte[]{0x1}); + + public static void main(String[] args) throws Exception { + + for (boolean initWithRandom : new boolean[]{true, false}) { + // Default Parameter + test(PROVIDER, ED25519, null, initWithRandom); + test(PROVIDER, ED448, null, initWithRandom); + + // With named parameter + test(PROVIDER, ED25519, ED25519, initWithRandom); + test(PROVIDER, OIDN25519, ED25519, initWithRandom); + test(PROVIDER, OID25519, ED25519, initWithRandom); + test(PROVIDER, ED448, ED448, initWithRandom); + test(PROVIDER, OIDN448, ED448, initWithRandom); + test(PROVIDER, OID448, ED448, initWithRandom); + + // With size parameter + test(PROVIDER, ED25519, 255, initWithRandom); + test(PROVIDER, OIDN25519, 255, initWithRandom); + test(PROVIDER, OID25519, 255, initWithRandom); + test(PROVIDER, ED448, 448, initWithRandom); + test(PROVIDER, OIDN448, 448, initWithRandom); + test(PROVIDER, OID448, 448, initWithRandom); + } + } + + // Test CRL signature using a KeyPair. + private static void test(String provider, String name, Object param, + boolean initWithRandom) throws Exception { + + System.out.printf("Case Algo:%s, Param:%s, Intitiate with random:%s%n", + name, param, initWithRandom); + KeyPair kp = genKeyPair(provider, name, param, initWithRandom); + X509CRLImpl crl = new X509CRLImpl( + new X500Name("CN=Issuer"), new Date(), new Date()); + crl.sign(kp.getPrivate(), name); + crl.verify(kp.getPublic()); + System.out.println("Passed."); + } + + private static KeyPair genKeyPair(String provider, String name, + Object param, boolean initWithRandom) throws Exception { + + KeyPairGenerator kpg = KeyPairGenerator.getInstance(name, provider); + if (initWithRandom) { + if (param instanceof Integer) { + kpg.initialize((Integer) param, S_RND); + } else if (param instanceof String) { + kpg.initialize(new NamedParameterSpec((String) param), S_RND); + } + } else { + if (param instanceof Integer) { + kpg.initialize((Integer) param); + } else if (param instanceof String) { + kpg.initialize(new NamedParameterSpec((String) param)); + } + } + return kpg.generateKeyPair(); + } + +} diff --git a/test/jdk/sun/security/ec/ed/EdDSAKeyCompatibility.java b/test/jdk/sun/security/ec/ed/EdDSAKeyCompatibility.java new file mode 100644 index 00000000000..4240ec53477 --- /dev/null +++ b/test/jdk/sun/security/ec/ed/EdDSAKeyCompatibility.java @@ -0,0 +1,222 @@ +/* + * 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.ByteArrayInputStream; +import java.io.IOException; +import java.math.BigInteger; +import java.security.InvalidKeyException; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.util.Base64; +import sun.security.util.DerValue; +import java.security.interfaces.EdECPrivateKey; +import java.security.interfaces.EdECPublicKey; +import java.security.spec.EdECPrivateKeySpec; +import java.security.spec.EdECPublicKeySpec; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.NamedParameterSpec; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; + +/* + * @test + * @bug 8209632 + * @summary OpenSSL generated compatibility test with EDDSA Java. + * @modules java.base/sun.security.util + * @run main EdDSAKeyCompatibility + */ +public class EdDSAKeyCompatibility { + + private static final String EDDSA = "EdDSA"; + private static final String ED25519 = "Ed25519"; + private static final String ED448 = "Ed448"; + private static final String PROVIDER = "SunEC"; + + public static void main(String[] args) throws Exception { + + boolean result = true; + result &= validateCert(EDDSA, PROVIDER, ED25519CERT); + result &= validateCert(EDDSA, PROVIDER, ED448CERT); + result &= validateCert(ED25519, PROVIDER, ED25519CERT); + result &= validateCert(ED448, PROVIDER, ED448CERT); + + result &= validatePrivate(ED25519, PROVIDER, ED25519KEY); + result &= validatePrivate(ED448, PROVIDER, ED448KEY); + + if (!result) { + throw new RuntimeException("Some test cases failed"); + } + } + + private static boolean validatePrivate(String algorithm, String provider, + String key) { + + try { + KeyFactory kf = KeyFactory.getInstance(algorithm, provider); + PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec( + Base64.getMimeDecoder().decode(key)); + EdECPrivateKey privKey + = (EdECPrivateKey) kf.generatePrivate(privSpec); + checkPrivKeyFormat(privKey.getEncoded()); + + NamedParameterSpec namedSpec = new NamedParameterSpec(algorithm); + EdECPrivateKeySpec edprivSpec = new EdECPrivateKeySpec( + namedSpec, privKey.getBytes().get()); + EdECPrivateKey privKey1 + = (EdECPrivateKey) kf.generatePrivate(edprivSpec); + checkPrivKeyFormat(privKey1.getEncoded()); + EdECPrivateKey privKey2 = (EdECPrivateKey) kf.translateKey(privKey); + checkPrivKeyFormat(privKey2.getEncoded()); + equals(privKey, privKey1); + equals(privKey, privKey2); + } catch (NoSuchAlgorithmException | InvalidKeySpecException | IOException + | NoSuchProviderException | InvalidKeyException e) { + e.printStackTrace(System.out); + return false; + } + System.out.println("PASSED - validatePrivate"); + return true; + } + + private static boolean validateCert(String algorithm, String provider, + String certificate) { + + try { + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + Certificate cert = cf.generateCertificate( + new ByteArrayInputStream(certificate.getBytes())); + System.out.println(cert); + KeyFactory kf = KeyFactory.getInstance(algorithm, provider); + X509EncodedKeySpec pubSpec = kf.getKeySpec( + cert.getPublicKey(), X509EncodedKeySpec.class); + EdECPublicKey pubKey = (EdECPublicKey) kf.generatePublic(pubSpec); + EdECPublicKeySpec edpubSpec = kf.getKeySpec( + cert.getPublicKey(), EdECPublicKeySpec.class); + EdECPublicKey pubKey1 = (EdECPublicKey) kf.generatePublic(edpubSpec); + EdECPublicKey pubKey2 = (EdECPublicKey) kf.translateKey(pubKey); + equals(pubKey, pubKey1); + equals(pubKey, pubKey2); + equals(pubKey, cert.getPublicKey()); + } catch (CertificateException | NoSuchAlgorithmException + | InvalidKeySpecException | NoSuchProviderException + | InvalidKeyException e) { + e.printStackTrace(System.out); + return false; + } + System.out.println("PASSED - validateCert"); + return true; + } + + private static void checkPrivKeyFormat(byte[] key) throws IOException { + + // key value should be nested octet strings + DerValue val = new DerValue(new ByteArrayInputStream(key)); + BigInteger version = val.data.getBigInteger(); + DerValue algId = val.data.getDerValue(); + byte[] keyValue = val.data.getOctetString(); + val = new DerValue(new ByteArrayInputStream(keyValue)); + if (val.tag != DerValue.tag_OctetString) { + throw new RuntimeException("incorrect format"); + } + } + + private static void equals(Object actual, Object expected) { + if (!actual.equals(expected)) { + throw new RuntimeException(String.format("Actual: %s, Expected: %s", + actual, expected)); + } + } + + // Following EdDSA Certificates/Keys are generated through openssl_1.1.1d + + /* + * Certificate: + * Data: + * Version: 3 (0x2) + * Serial Number: + * 1d:d3:87:b9:e4:c6:9e:4a:5c:78:a8:f0:c7:9b:37:be:1e:31:dd:20 + * Signature Algorithm: ED25519 + * Issuer: C = US, ST = CA, L = SCA, O = test, OU = test, CN = localhost + * Validity + * Not Before: Mar 6 05:55:31 2020 GMT + * Not After : Mar 1 05:55:31 2040 GMT + * Subject: C = US, ST = CA, L = SCA, O = test, OU = test, CN = localhost + * Subject Public Key Info: + * Public Key Algorithm: ED25519 + */ + private static final String ED25519KEY + = "MC4CAQAwBQYDK2VwBCIEIP8xGaQTMh+I+59I66AaN+B4qnY1oWGjPwbSY4r+D08f"; + + private static final String ED25519CERT + = "-----BEGIN CERTIFICATE-----\n" + + "MIIByTCCAXugAwIBAgIUHdOHueTGnkpceKjwx5s3vh4x3SAwBQYDK2VwMFoxCzAJ\n" + + "BgNVBAYTAlVTMQswCQYDVQQIDAJDQTEMMAoGA1UEBwwDU0NBMQ0wCwYDVQQKDAR0\n" + + "ZXN0MQ0wCwYDVQQLDAR0ZXN0MRIwEAYDVQQDDAlsb2NhbGhvc3QwHhcNMjAwMzA2\n" + + "MDU1NTMxWhcNNDAwMzAxMDU1NTMxWjBaMQswCQYDVQQGEwJVUzELMAkGA1UECAwC\n" + + "Q0ExDDAKBgNVBAcMA1NDQTENMAsGA1UECgwEdGVzdDENMAsGA1UECwwEdGVzdDES\n" + + "MBAGA1UEAwwJbG9jYWxob3N0MCowBQYDK2VwAyEAdqQ4Nduhbl+ShGeKdOryVMKy\n" + + "1t1LjyjPyCBC+gSk0eCjUzBRMB0GA1UdDgQWBBS01/VQEzwkFNRW/esQxaB6+uId\n" + + "8jAfBgNVHSMEGDAWgBS01/VQEzwkFNRW/esQxaB6+uId8jAPBgNVHRMBAf8EBTAD\n" + + "AQH/MAUGAytlcANBAEJkLuNfyVws7HKqHL7oDqQkp5DSwh+bGjrr2p4zSvs5PZ8o\n" + + "jRXWV0SMt/MB+90ubMD5tL7H7J6DR5PUFBIwGwc=\n" + + "-----END CERTIFICATE-----"; + + /* + * Certificate: + * Data: + * Version: 3 (0x2) + * Serial Number: + * 42:eb:8c:a2:a0:6f:8e:5a:a5:f8:7c:72:c1:f1:8b:7e:44:1b:37:80 + * Signature Algorithm: ED448 + * Issuer: C = US, ST = CA, L = SCA, O = test, OU = test, CN = localhost + * Validity + * Not Before: Mar 6 05:57:42 2020 GMT + * Not After : Mar 1 05:57:42 2040 GMT + * Subject: C = US, ST = CA, L = SCA, O = test, OU = test, CN = localhost + * Subject Public Key Info: + * Public Key Algorithm: ED448 + */ + private static final String ED448KEY + = "MEcCAQAwBQYDK2VxBDsEOdG4lrYO0xBaf3aJWYMZ8XAxitA1zV4/ghG8wPBag8HQ" + + "XN+3OmS8wR1KfeGQysHQr3JHco3Mwiaz8w=="; + + private static final String ED448CERT + = "-----BEGIN CERTIFICATE-----\n" + + "MIICFDCCAZSgAwIBAgIUQuuMoqBvjlql+HxywfGLfkQbN4AwBQYDK2VxMFoxCzAJ\n" + + "BgNVBAYTAlVTMQswCQYDVQQIDAJDQTEMMAoGA1UEBwwDU0NBMQ0wCwYDVQQKDAR0\n" + + "ZXN0MQ0wCwYDVQQLDAR0ZXN0MRIwEAYDVQQDDAlsb2NhbGhvc3QwHhcNMjAwMzA2\n" + + "MDU1NzQyWhcNNDAwMzAxMDU1NzQyWjBaMQswCQYDVQQGEwJVUzELMAkGA1UECAwC\n" + + "Q0ExDDAKBgNVBAcMA1NDQTENMAsGA1UECgwEdGVzdDENMAsGA1UECwwEdGVzdDES\n" + + "MBAGA1UEAwwJbG9jYWxob3N0MEMwBQYDK2VxAzoAfKlXpT0ymcvz2Gp+8HLzBpaz\n" + + "5mQqMaDbGmcq8gSIdeEUtVmv4OplE+4GSnrbJnEn99LQdbanL/MAo1MwUTAdBgNV\n" + + "HQ4EFgQUXkm9LVUkB0f/1MiPFjQPHGJ8THIwHwYDVR0jBBgwFoAUXkm9LVUkB0f/\n" + + "1MiPFjQPHGJ8THIwDwYDVR0TAQH/BAUwAwEB/zAFBgMrZXEDcwDvE3LKCg1bTjHi\n" + + "MI1EiMqZN3PJYVBsztecBXm3ELDlT+F0Z1H2vjaROkJc8PdpUOxyed1xDjwq3IB/\n" + + "nYYJNVyt6Dy3d12kl77ev+YMD83OuqM6F5O6MdDUxYQu9u3NasZAU5FQ6zklWWpI\n" + + "8jCPtOvcAQA=\n" + + "-----END CERTIFICATE-----"; +} diff --git a/test/jdk/sun/security/ec/ed/EdDSAKeySize.java b/test/jdk/sun/security/ec/ed/EdDSAKeySize.java new file mode 100644 index 00000000000..f415e651742 --- /dev/null +++ b/test/jdk/sun/security/ec/ed/EdDSAKeySize.java @@ -0,0 +1,221 @@ +/* + * 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 static javax.crypto.Cipher.PRIVATE_KEY; +import static javax.crypto.Cipher.PUBLIC_KEY; +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.SecureRandom; +import java.security.interfaces.EdECPrivateKey; +import java.security.interfaces.EdECPublicKey; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.security.spec.EdECPrivateKeySpec; +import java.security.spec.EdECPublicKeySpec; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.NamedParameterSpec; +import java.util.Arrays; +import jdk.test.lib.Convert; + +/* + * @test + * @bug 8209632 + * @summary Verify KeyLength for EDDSA, ED25519, ED448. + * @library /test/lib + * @build jdk.test.lib.Convert + * @run main EdDSAKeySize + */ +public class EdDSAKeySize { + + private static final String EDDSA = "EDDSA"; + private static final String ED25519 = "ED25519"; + private static final String ED448 = "ED448"; + private static final String OIDN25519 = "1.3.101.112"; + private static final String OID25519 = "OID.1.3.101.112"; + private static final String OIDN448 = "1.3.101.113"; + private static final String OID448 = "OID.1.3.101.113"; + private static final String PROVIDER = "SunEC"; + private static final SecureRandom RND = new SecureRandom(new byte[]{0x1}); + + public static void main(String[] args) throws Exception { + + for (boolean initWithRandom : new boolean[]{true, false}) { + + // As per rfc8032 the generated keysize for ED25519 is + // 32 octets(256 bits) and ED448 is 57 octets(456 bits). + // Case with default parameter + testKeyAttributes(PROVIDER, EDDSA, initWithRandom, null, 256); + testKeyAttributes(PROVIDER, ED25519, initWithRandom, null, 256); + testKeyAttributes(PROVIDER, ED448, initWithRandom, null, 456); + + // With named parameter + testKeyAttributes(PROVIDER, EDDSA, initWithRandom, ED25519, 256); + testKeyAttributes(PROVIDER, ED25519, initWithRandom, ED25519, 256); + testKeyAttributes(PROVIDER, OIDN25519, initWithRandom, ED25519, 256); + testKeyAttributes(PROVIDER, OID25519, initWithRandom, ED25519, 256); + testKeyAttributes(PROVIDER, ED448, initWithRandom, ED448, 456); + testKeyAttributes(PROVIDER, OIDN448, initWithRandom, ED448, 456); + testKeyAttributes(PROVIDER, OID448, initWithRandom, ED448, 456); + + // With size parameter + testKeyAttributes(PROVIDER, EDDSA, initWithRandom, 255, 256); + testKeyAttributes(PROVIDER, ED25519, initWithRandom, 255, 256); + testKeyAttributes(PROVIDER, OIDN25519, initWithRandom, 255, 256); + testKeyAttributes(PROVIDER, OID25519, initWithRandom, 255, 256); + testKeyAttributes(PROVIDER, ED448, initWithRandom, 448, 456); + testKeyAttributes(PROVIDER, OIDN448, initWithRandom, 448, 456); + testKeyAttributes(PROVIDER, OID448, initWithRandom, 448, 456); + } + } + + /** + * Test standard Key attributes. + */ + private static void testKeyAttributes(String provider, String name, + boolean initWithRandom, Object param, int keySize) throws Exception { + + System.out.printf("Case name: %s, param: %s, Expected keysize: %s, " + + "Initiate with random: %s%n", name, param, keySize, + initWithRandom); + KeyPairGenerator kpg = KeyPairGenerator.getInstance(name, provider); + if (initWithRandom) { + if (param instanceof Integer) { + kpg.initialize((Integer) param, RND); + } else if (param instanceof String) { + kpg.initialize(new NamedParameterSpec((String) param), RND); + } + } else { + if (param instanceof Integer) { + kpg.initialize((Integer) param); + } else if (param instanceof String) { + kpg.initialize(new NamedParameterSpec((String) param)); + } + } + KeyPair kp = kpg.generateKeyPair(); + NamedParameterSpec namedSpec = getNamedParamSpec(name); + + // Verify original PrivateKey with it's different representation + Key[] privs = manipulateKey(provider, name, PRIVATE_KEY, + kp.getPrivate(), namedSpec); + Arrays.stream(privs).forEach( + priv -> testPrivateKey((EdECPrivateKey) kp.getPrivate(), + (EdECPrivateKey) priv, keySize)); + + // Verify original PublicKey with it's different representation + Key[] pubs = manipulateKey(provider, name, PUBLIC_KEY, + kp.getPublic(), namedSpec); + Arrays.stream(pubs).forEach( + pub -> testPublicKey((EdECPublicKey) kp.getPublic(), + (EdECPublicKey) pub)); + System.out.println("Passed."); + } + + private static NamedParameterSpec getNamedParamSpec(String algo) { + NamedParameterSpec namedSpec = switch (algo) { + case EDDSA + , OIDN25519, OID25519 -> new NamedParameterSpec(ED25519); + case OIDN448 + , OID448 -> new NamedParameterSpec(ED448); + default-> + new NamedParameterSpec(algo); + }; + return namedSpec; + } + + private static Key[] manipulateKey(String provider, String algo, int type, + Key key, NamedParameterSpec namedSpec) + throws NoSuchAlgorithmException, InvalidKeySpecException, + NoSuchProviderException, InvalidKeyException { + + KeyFactory kf = KeyFactory.getInstance(algo, provider); + switch (type) { + case PUBLIC_KEY: + return new Key[]{ + kf.generatePublic(new X509EncodedKeySpec(key.getEncoded())), + kf.generatePublic(kf.getKeySpec( + key, EdECPublicKeySpec.class)), + kf.generatePublic(new EdECPublicKeySpec(namedSpec, + ((EdECPublicKey) key).getPoint())), + kf.translateKey(key) + }; + case PRIVATE_KEY: + return new Key[]{ + kf.generatePrivate(new PKCS8EncodedKeySpec(key.getEncoded())), + kf.generatePrivate( + kf.getKeySpec(key, EdECPrivateKeySpec.class)), + kf.generatePrivate(new EdECPrivateKeySpec(namedSpec, + ((EdECPrivateKey) key).getBytes().get())), + kf.translateKey(key) + }; + } + throw new RuntimeException("We shouldn't reach here"); + } + + /** + * Basic PrivateKey Test cases + */ + private static void testPrivateKey(EdECPrivateKey orig, + EdECPrivateKey generated, int size) { + + equals(orig.getBytes().get().length * 8, size); + equals(generated.getBytes().get().length * 8, size); + equals(orig.getBytes().get(), generated.getBytes().get()); + equals(orig.getFormat(), generated.getFormat()); + equals(orig.getEncoded(), generated.getEncoded()); + equals(((NamedParameterSpec) orig.getParams()).getName(), + ((NamedParameterSpec) generated.getParams()).getName()); + } + + /** + * Basic PublicKey Test cases + */ + private static void testPublicKey(EdECPublicKey orig, + EdECPublicKey generated) { + + equals(orig.getPoint().getY(), generated.getPoint().getY()); + equals(orig.getPoint().isXOdd(), generated.getPoint().isXOdd()); + equals(orig.getFormat(), generated.getFormat()); + equals(orig.getEncoded(), generated.getEncoded()); + equals(((NamedParameterSpec) orig.getParams()).getName(), + ((NamedParameterSpec) generated.getParams()).getName()); + } + + private static void equals(Object actual, Object expected) { + if (!actual.equals(expected)) { + throw new RuntimeException(String.format("Actual: %s, Expected: %s", + actual, expected)); + } + } + + private static void equals(byte[] actual, byte[] expected) { + if (!Arrays.equals(actual, expected)) { + throw new RuntimeException(String.format("Actual array: %s, " + + "Expected array:%s", Convert.byteArrayToHexString(actual), + Convert.byteArrayToHexString(expected))); + } + } +} diff --git a/test/jdk/sun/security/ec/ed/EdDSANegativeTest.java b/test/jdk/sun/security/ec/ed/EdDSANegativeTest.java new file mode 100644 index 00000000000..88645827d3d --- /dev/null +++ b/test/jdk/sun/security/ec/ed/EdDSANegativeTest.java @@ -0,0 +1,299 @@ +/* + * 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.security.InvalidKeyException; +import java.security.InvalidParameterException; +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.Signature; +import java.security.interfaces.EdECPrivateKey; +import java.security.interfaces.EdECPublicKey; +import java.security.spec.EdDSAParameterSpec; +import java.util.Arrays; +import jdk.test.lib.Convert; + +/* + * @test + * @bug 8209632 + * @summary Negative cases for EDDSA. + * @library /test/lib + * @build jdk.test.lib.Convert + * @run main EdDSANegativeTest + */ +public class EdDSANegativeTest { + + private static final String EDDSA = "EdDSA"; + private static final String ED25519 = "Ed25519"; + private static final String ED448 = "Ed448"; + private static final String PROVIDER = "SunEC"; + private static final String OTHER = "other"; + private static final byte[] MSG = "TEST".getBytes(); + + public static void main(String[] args) throws Exception { + byName(); + byParam(); + byInvalidKey(); + byInvalidKeyType(); + } + + private static void byName() throws Exception { + + for (String name : new String[]{null, "", "EDDSA", "eddsa", "EDdsa", + EDDSA, ED25519, "ed25519", "ED25519", ED448, "eD448", "ED448", + "ed448", OTHER}) { + try { + KeyPair kp = genKeyPair(name); + KeyFactory kf = KeyFactory.getInstance(name, PROVIDER); + EdECPrivateKey edPri + = (EdECPrivateKey) kf.translateKey(kp.getPrivate()); + EdECPublicKey edPub + = (EdECPublicKey) kf.translateKey(kp.getPublic()); + Signature sig = Signature.getInstance(name, PROVIDER); + byte[] computedSig = sign(sig, edPri, MSG); + if (!verify(sig, edPub, MSG, computedSig)) { + throw new RuntimeException("Signature verification failed"); + } + if (name == null || "".equals(name)) { + throw new RuntimeException( + "Should not reach here for algo: " + name); + } + System.out.println("Passed: byName: " + name); + } catch (NullPointerException e) { + if (name != null) { + throw new RuntimeException( + "Unknown issue with algo name: " + name, e); + } + } catch (NoSuchAlgorithmException e) { + if (!("".equals(name) || OTHER.equals(name))) { + throw new RuntimeException( + "Unknown issue with algo name: " + name, e); + } + } + } + } + + private static void byParam() throws Exception { + testParam(EDDSA); + testParam(ED25519); + testParam(ED448); + } + + private static void byInvalidKey() throws Exception { + testInvalidKey(EDDSA); + testInvalidKey(ED25519); + testInvalidKey(ED448); + } + + private static void byInvalidKeyType() throws Exception { + testInvalidKeyType(EDDSA); + testInvalidKeyType(ED25519); + testInvalidKeyType(ED448); + } + + /** + * Test Signature. + */ + private static void testParam(String name) throws Exception { + + KeyPair kp = genKeyPair(name); + Signature sig = Signature.getInstance(name, PROVIDER); + // Set initial paramter to generate a signature + EdDSAParameterSpec initParam + = new EdDSAParameterSpec(true, "testContext".getBytes()); + sig.setParameter(initParam); + byte[] computedSig = sign(sig, kp.getPrivate(), MSG); + // Signature should not get verified other than same parameter + // which is set through the signature instance. + for (boolean preHash : new boolean[]{true, false}) { + // Test case with prehash as parameter without context set. + verify(sig, kp.getPublic(), MSG, new EdDSAParameterSpec(preHash), + initParam, computedSig); + // Test Case with Context combined of different sizes. + // As per rfc8032, value of context is maximum of 255 octet + for (byte[] context : new byte[][]{{}, "other".getBytes(), + new byte[255], new byte[500]}) { + System.out.printf("Testing signature for name: %s, algorithm " + + "spec: (prehash:%s, context:%s)%n", name, preHash, + Convert.byteArrayToHexString(context)); + try { + verify(sig, kp.getPublic(), MSG, + new EdDSAParameterSpec(preHash, context), + initParam, computedSig); + } catch (InvalidParameterException e) { + if (context.length <= 255) { + throw new RuntimeException("Should not throw exception " + + "when context size <= 255 octet: " + + context.length); + } + } + } + } + } + + private static void testInvalidKey(String name) throws Exception { + KeyPair kp = genKeyPair(name); + KeyPair kp1 = genKeyPair(name); + Signature sig = Signature.getInstance(name, PROVIDER); + byte[] computedSig = sign(sig, kp.getPrivate(), MSG); + if (verify(sig, kp1.getPublic(), MSG, computedSig)) { + throw new RuntimeException("Signature verification failed " + + "for unpaired key."); + } + System.out.println("Passed: testInvalidKey: " + name); + } + + private static void testInvalidKeyType(String name) throws Exception { + + KeyFactory kf = KeyFactory.getInstance(name, PROVIDER); + try { + kf.translateKey(new InvalidPrivateKey()); + } catch (InvalidKeyException e) { + // Expected exception and not to be handled + } + try { + kf.translateKey(new InvalidPublicKey()); + } catch (InvalidKeyException e) { + // Expected exception and not to be handled + } + System.out.println("Passed: testInvalidKeyType: " + name); + } + + private static KeyPair genKeyPair(String name) throws Exception { + KeyPairGenerator kpg = KeyPairGenerator.getInstance(name, PROVIDER); + return kpg.generateKeyPair(); + } + + private static byte[] sign(Signature sig, PrivateKey priKey, byte[] msg) + throws Exception { + sig.initSign(priKey); + sig.update(msg); + return sig.sign(); + } + + private static boolean verify(Signature sig, PublicKey pubKey, byte[] msg, + byte[] sign) throws Exception { + sig.initVerify(pubKey); + sig.update(msg); + return sig.verify(sign); + } + + private static void verify(Signature sig, PublicKey pubKey, byte[] msg, + EdDSAParameterSpec params, EdDSAParameterSpec initParam, + byte[] computedSig) throws Exception { + + sig.setParameter(params); + if (verify(sig, pubKey, msg, computedSig)) { + byte[] context = params.getContext().isPresent() + ? params.getContext().get() : null; + byte[] initContext = initParam.getContext().isPresent() + ? initParam.getContext().get() : null; + boolean preHash = params.isPrehash(); + boolean initPreHash = initParam.isPrehash(); + // The signature should not get verified with other parameters + // set through signature instance. + if (!(equals(context, initContext) && equals(preHash, initPreHash))) { + throw new RuntimeException(String.format("Signature verification" + + " success with different param context(actual:%s, " + + "expected:%s), Prehash(actual:%s, expected:%s)", + Convert.byteArrayToHexString(context), + Convert.byteArrayToHexString(initContext), + preHash, initPreHash)); + } else { + System.out.println("Atleast a case matched"); + } + } + } + + private static boolean equals(Object actual, Object expected) { + if (actual == expected) { + return true; + } + if (actual == null || expected == null) { + return false; + } + boolean equals = actual.equals(expected); + if (!equals) { + throw new RuntimeException(String.format("Actual: %s, Expected: %s", + actual, expected)); + } + return equals; + } + + private static boolean equals(byte[] actual, byte[] expected) { + if (actual == expected) { + return true; + } + if (actual == null || expected == null) { + return false; + } + boolean equals = Arrays.equals(actual, expected); + if (!equals) { + throw new RuntimeException(String.format("Actual array: %s, " + + "Expected array:%s", Convert.byteArrayToHexString(actual), + Convert.byteArrayToHexString(expected))); + } + return equals; + } + + private static class InvalidPrivateKey implements PrivateKey { + + @Override + public String getAlgorithm() { + return "test"; + } + + @Override + public String getFormat() { + return "test"; + } + + @Override + public byte[] getEncoded() { + return "test".getBytes(); + } + + } + + private static class InvalidPublicKey implements PublicKey { + + @Override + public String getAlgorithm() { + return "test"; + } + + @Override + public String getFormat() { + return "test"; + } + + @Override + public byte[] getEncoded() { + return "test".getBytes(); + } + + } +} diff --git a/test/jdk/sun/security/ec/ed/EdDSAParamSpec.java b/test/jdk/sun/security/ec/ed/EdDSAParamSpec.java new file mode 100644 index 00000000000..1ef6b029877 --- /dev/null +++ b/test/jdk/sun/security/ec/ed/EdDSAParamSpec.java @@ -0,0 +1,174 @@ +/* + * 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.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.Signature; +import java.security.spec.EdDSAParameterSpec; +import java.util.Arrays; +import jdk.test.lib.Convert; + +/* + * @test + * @bug 8209632 + * @summary Test EdDSAParameterSpec. + * @library /test/lib + * @build jdk.test.lib.Convert + * @run main EdDSAParamSpec + */ +public class EdDSAParamSpec { + + private static final String EDDSA = "EdDSA"; + private static final String ED25519 = "Ed25519"; + private static final String ED448 = "Ed448"; + private static final String PROVIDER = "SunEC"; + private static final byte[] MSG = "TEST".getBytes(); + private static final SecureRandom RND = new SecureRandom(new byte[]{0x1}); + + public static void main(String[] args) throws Exception { + + testParam(PROVIDER, EDDSA); + testParam(PROVIDER, ED25519); + testParam(PROVIDER, ED448); + } + + /** + * Test Signature. + */ + private static void testParam(String provider, String name) + throws Exception { + + KeyPair kp = genKeyPair(provider, name); + Signature sig = Signature.getInstance(name, provider); + EdDSAParameterSpec initParam + = new EdDSAParameterSpec(true, "testContext".getBytes()); + sig.setParameter(initParam); + byte[] origSign = sign(sig, kp.getPrivate(), MSG); + for (boolean preHash : new boolean[]{true, false}) { + System.out.printf("Testing signature for name: %s," + + " algorithm spec: (prehash:%s)%n", name, preHash); + verifyPublic(sig, kp.getPublic(), MSG, + new EdDSAParameterSpec(preHash), initParam, origSign); + // Test Case with Context size combined. + // As per rfc8032, value of context is maximum of 255 octet + byte[] maxCtx = new byte[255]; + RND.nextBytes(maxCtx); + for (byte[] context : new byte[][]{"others".getBytes(), maxCtx}) { + System.out.printf("Testing signature for name: %s," + + " algorithm spec: (prehash:%s, context:%s)%n", + name, preHash, Convert.byteArrayToHexString(context)); + EdDSAParameterSpec params + = new EdDSAParameterSpec(preHash, context); + verifyPublic(sig, kp.getPublic(), MSG, params, initParam, + origSign); + } + } + System.out.println("Passed."); + } + + private static KeyPair genKeyPair(String provider, String name) + throws Exception { + + KeyPairGenerator kpg = KeyPairGenerator.getInstance(name, provider); + return kpg.generateKeyPair(); + } + + private static byte[] sign(Signature sig, PrivateKey priKey, byte[] msg) + throws Exception { + + sig.initSign(priKey); + sig.update(msg); + return sig.sign(); + } + + private static boolean verify(Signature sig, PublicKey pubKey, byte[] msg, + byte[] sign) throws Exception { + + sig.initVerify(pubKey); + sig.update(msg); + return sig.verify(sign); + } + + private static void verifyPublic(Signature sig, PublicKey pubKey, + byte[] msg, EdDSAParameterSpec params, EdDSAParameterSpec initParam, + byte[] origSign) throws Exception { + + sig.setParameter(params); + if (verify(sig, pubKey, msg, origSign)) { + byte[] context = params.getContext().isPresent() + ? params.getContext().get() : null; + byte[] initContext = initParam.getContext().isPresent() + ? initParam.getContext().get() : null; + boolean preHash = params.isPrehash(); + boolean initPreHash = initParam.isPrehash(); + // The signature should not get verified other than same parameter + // which is set through the signature instance. + if (!(equals(context, initContext) && equals(preHash, initPreHash))) { + throw new RuntimeException(String.format("Signature verification" + + " success with different param context(actual:%s, " + + "expected:%s), Prehash(actual:%s, expected:%s)", + Convert.byteArrayToHexString(context), + Convert.byteArrayToHexString(initContext), + preHash, initPreHash)); + } else { + System.out.println("Atleast a case matched"); + } + } + } + + private static boolean equals(Object actual, Object expected) { + + if (actual == expected) { + return true; + } + if (actual == null || expected == null) { + return false; + } + boolean equals = actual.equals(expected); + if (!equals) { + throw new RuntimeException(String.format("Actual: %s, Expected: %s", + actual, expected)); + } + return equals; + } + + private static boolean equals(byte[] actual, byte[] expected) { + + if (actual == expected) { + return true; + } + if (actual == null || expected == null) { + return false; + } + boolean equals = Arrays.equals(actual, expected); + if (!equals) { + throw new RuntimeException(String.format("Actual array: %s, " + + "Expected array:%s", Convert.byteArrayToHexString(actual), + Convert.byteArrayToHexString(expected))); + } + return equals; + } + +} diff --git a/test/jdk/sun/security/ec/ed/EdDSAReuseTest.java b/test/jdk/sun/security/ec/ed/EdDSAReuseTest.java new file mode 100644 index 00000000000..bebabb8539f --- /dev/null +++ b/test/jdk/sun/security/ec/ed/EdDSAReuseTest.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. + */ + +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.Signature; +import java.security.spec.NamedParameterSpec; +import java.util.ArrayList; +import java.util.List; + +/* + * @test + * @bug 8209632 + * @summary Test behaviour of Signature instance by re-using it multiple times + * in different way. + * @run main EdDSAReuseTest + */ +public class EdDSAReuseTest { + + private static final String EDDSA = "EdDSA"; + private static final String ED25519 = "Ed25519"; + private static final String ED448 = "Ed448"; + private static final String PROVIDER = "SunEC"; + private static final String MSG = "TEST"; + private static final int REUSE = 20; + private static final int ONCE = 1; + private static final int TENTH = 10; + private static final int FIFTH = 5; + + public static void main(String[] args) throws Exception { + + for (boolean initKey : new boolean[]{true, false}) { + // Sign and Verify with data update once + test(PROVIDER, EDDSA, null, initKey, ONCE, ONCE); + test(PROVIDER, ED25519, ED25519, initKey, ONCE, ONCE); + test(PROVIDER, ED448, ED448, initKey, ONCE, ONCE); + + // Sign and Verify with data update 10 times + test(PROVIDER, EDDSA, null, initKey, TENTH, TENTH); + test(PROVIDER, ED25519, ED25519, initKey, TENTH, TENTH); + test(PROVIDER, ED448, ED448, initKey, TENTH, TENTH); + + // Sign and Verify with data update unmatched number of times + test(PROVIDER, EDDSA, null, initKey, TENTH, FIFTH); + test(PROVIDER, ED25519, ED25519, initKey, TENTH, FIFTH); + test(PROVIDER, ED448, ED448, initKey, TENTH, FIFTH); + } + } + + private static void test(String provider, String name, Object param, + boolean initKey, int signUpdate, int verifyUpdate) + throws Exception { + + System.out.printf("Case for signature name: %s, param: %s," + + " initialize signature instance before each operation: %s%n", + name, param, initKey); + KeyPairGenerator kpg = KeyPairGenerator.getInstance(name, provider); + if (param != null) { + kpg.initialize(new NamedParameterSpec((String) param)); + } + KeyPair kp = kpg.generateKeyPair(); + Signature sig = Signature.getInstance(name, provider); + testAPI(sig, kp, initKey, signUpdate, verifyUpdate); + System.out.println("Passed."); + } + + private static void testAPI(Signature sig, KeyPair kp, boolean initKey, + int signUpdate, int verifyUpdate) throws Exception { + + sig.initSign(kp.getPrivate()); + List signatures = new ArrayList<>(); + // Re-use the signature instance 20 times + for (int i = 0; i < REUSE; i++) { + signatures.add(sign(sig, kp.getPrivate(), MSG, initKey, signUpdate)); + } + System.out.printf("Generated signatures %s times%n", signatures.size()); + sig.initVerify(kp.getPublic()); + for (byte[] sign : signatures) { + // Verification will pass when message update matches with + // the same used for sign + if (verify(sig, kp.getPublic(), MSG, sign, initKey, verifyUpdate) + != (signUpdate == verifyUpdate)) { + throw new RuntimeException( + "Verification succed with unmatched message"); + } + } + System.out.printf("Verified signatures %s times%n", signatures.size()); + } + + private static byte[] sign(Signature sig, PrivateKey priKey, String msg, + boolean initKey, int signUpdate) throws Exception { + if (initKey) { + sig.initSign(priKey); + } + for (int update = 0; update < signUpdate; update++) { + sig.update(msg.getBytes()); + } + return sig.sign(); + } + + private static boolean verify(Signature sig, PublicKey pubKey, String msg, + byte[] sign, boolean initKey, int verifyUpdate) throws Exception { + if (initKey) { + sig.initVerify(pubKey); + } + for (int update = 0; update < verifyUpdate; update++) { + sig.update(msg.getBytes()); + } + return sig.verify(sign); + } +} diff --git a/test/jdk/sun/security/ec/ed/EdDSATest.java b/test/jdk/sun/security/ec/ed/EdDSATest.java new file mode 100644 index 00000000000..f61dbd61fe3 --- /dev/null +++ b/test/jdk/sun/security/ec/ed/EdDSATest.java @@ -0,0 +1,356 @@ +/* + * 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 static javax.crypto.Cipher.PRIVATE_KEY; +import static javax.crypto.Cipher.PUBLIC_KEY; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.Signature; +import java.security.interfaces.EdECPrivateKey; +import java.security.interfaces.EdECPublicKey; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.security.spec.EdECPrivateKeySpec; +import java.security.spec.EdECPublicKeySpec; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.NamedParameterSpec; +import java.security.spec.EdDSAParameterSpec; +import java.util.Arrays; +import jdk.test.lib.Convert; + +/* + * @test + * @bug 8209632 + * @summary Test Signature with variation of serialized EDDSA Keys. + * @library /test/lib + * @build jdk.test.lib.Convert + * @run main EdDSATest + */ +public class EdDSATest { + + private static final String EDDSA = "EdDSA"; + private static final String ED25519 = "Ed25519"; + private static final String ED448 = "Ed448"; + private static final String OIDN25519 = "1.3.101.112"; + private static final String OID25519 = "OID.1.3.101.112"; + private static final String OIDN448 = "1.3.101.113"; + private static final String OID448 = "OID.1.3.101.113"; + private static final String PROVIDER = "SunEC"; + private static final byte[] MSG = "TEST".getBytes(); + private static final SecureRandom S_RND = new SecureRandom(new byte[]{0x1}); + + public static void main(String[] args) throws Exception { + + for (boolean random : new boolean[]{true, false}) { + + // Default Parameter + test(PROVIDER, EDDSA, null, random); + test(PROVIDER, ED25519, null, random); + test(PROVIDER, ED448, null, random); + + // With named parameter + test(PROVIDER, EDDSA, ED25519, random); + test(PROVIDER, ED25519, ED25519, random); + test(PROVIDER, OIDN25519, ED25519, random); + test(PROVIDER, OID25519, ED25519, random); + test(PROVIDER, ED448, ED448, random); + test(PROVIDER, OIDN448, ED448, random); + test(PROVIDER, OID448, ED448, random); + + // With size parameter + test(PROVIDER, EDDSA, 255, random); + test(PROVIDER, ED25519, 255, random); + test(PROVIDER, OIDN25519, 255, random); + test(PROVIDER, OID25519, 255, random); + test(PROVIDER, ED448, 448, random); + test(PROVIDER, OIDN448, 448, random); + test(PROVIDER, OID448, 448, random); + } + } + + // Test signature using a KeyPair and the corresponding transformed one. + private static void test(String provider, String name, Object param, + boolean random) throws Exception { + + System.out.printf("Case Algo:%s, Param:%s, Intitiate with random:%s%n", + name, param, random); + KeyPair origkp = genKeyPair(provider, name, param, random); + testSignature(provider, name, origkp, origkp); + NamedParameterSpec namedSpec = namedParamSpec(name); + // Test all possible transformed private/public keys + for (Key priKey : manipulateKey(provider, name, PRIVATE_KEY, + origkp.getPrivate(), namedSpec)) { + for (Key pubKey : manipulateKey(provider, name, PUBLIC_KEY, + origkp.getPublic(), namedSpec)) { + EdECPrivateKey pri = (EdECPrivateKey) priKey; + EdECPublicKey pub = (EdECPublicKey) pubKey; + // Test the keys are serializable. + testSerialize(origkp, new KeyPair(pub, pri)); + // Test signature + testSignature(provider, name, origkp, new KeyPair(pub, pri)); + } + } + System.out.println("Passed."); + } + + private static KeyPair genKeyPair(String provider, String name, + Object param, boolean random) throws Exception { + + KeyPairGenerator kpg = KeyPairGenerator.getInstance(name, provider); + if (random) { + if (param instanceof Integer) { + kpg.initialize((Integer) param, S_RND); + } else if (param instanceof String) { + kpg.initialize(new NamedParameterSpec((String) param), S_RND); + } + } else { + if (param instanceof Integer) { + kpg.initialize((Integer) param); + } else if (param instanceof String) { + kpg.initialize(new NamedParameterSpec((String) param)); + } + } + equals(kpg.getProvider().getName(), provider); + equals(kpg.getAlgorithm(), name); + return kpg.generateKeyPair(); + } + + private static NamedParameterSpec namedParamSpec(String algo) { + NamedParameterSpec namedSpec = switch (algo) { + case EDDSA + , OIDN25519, OID25519 -> new NamedParameterSpec(ED25519); + case OIDN448 + , OID448 -> new NamedParameterSpec(ED448); + default-> + new NamedParameterSpec(algo); + }; + return namedSpec; + } + + private static Key[] manipulateKey(String provider, String name, int type, + Key key, NamedParameterSpec namedSpec) + throws NoSuchAlgorithmException, InvalidKeySpecException, + NoSuchProviderException, InvalidKeyException { + + KeyFactory kf = KeyFactory.getInstance(name, provider); + switch (type) { + case PUBLIC_KEY: + return new Key[]{ + kf.generatePublic(new X509EncodedKeySpec(key.getEncoded())), + kf.generatePublic(kf.getKeySpec( + key, EdECPublicKeySpec.class)), + kf.generatePublic(new EdECPublicKeySpec(namedSpec, + ((EdECPublicKey) key).getPoint())), + kf.translateKey(key) + }; + case PRIVATE_KEY: + return new Key[]{ + kf.generatePrivate(new PKCS8EncodedKeySpec(key.getEncoded())), + kf.generatePrivate( + kf.getKeySpec(key, EdECPrivateKeySpec.class)), + kf.generatePrivate(new EdECPrivateKeySpec(namedSpec, + ((EdECPrivateKey) key).getBytes().get())), + kf.translateKey(key) + }; + } + throw new RuntimeException("We shouldn't reach here"); + } + + /** + * Test Signature with a set of parameter combination. + */ + private static void testSignature(String provider, String name, + KeyPair origkp, KeyPair kp) throws Exception { + + signAndVerify(provider, name, origkp, kp, null); + // Test Case with Pre-Hash enabled and disabled. + for (boolean preHash : new boolean[]{true, false}) { + signAndVerify(provider, name, origkp, kp, + new EdDSAParameterSpec(preHash)); + // Test Case with Context combined. + for (byte[] context : new byte[][]{ + {}, "a".getBytes(), new byte[255]}) { + signAndVerify(provider, name, origkp, kp, + new EdDSAParameterSpec(preHash, context)); + } + } + } + + private static void signAndVerify(String provider, String name, + KeyPair origkp, KeyPair kp, EdDSAParameterSpec params) + throws Exception { + + Signature sig = Signature.getInstance(name, provider); + if (params != null) { + sig.setParameter(params); + } + sig.initSign(origkp.getPrivate()); + sig.update(MSG); + byte[] origSign = sig.sign(); + + sig.update(MSG); + byte[] computedSig = sig.sign(); + equals(origSign, computedSig); + // EdDSA signatures size (64 and 114 bytes) for Ed25519 and Ed448. + int expectedSigSize = edSignatureSize(name); + equals(origSign.length, expectedSigSize); + sig.initSign(kp.getPrivate()); + sig.update(MSG); + equals(computedSig, sig.sign()); + // Use same signature instance to verify with transformed PublicKey. + sig.initVerify(kp.getPublic()); + sig.update(MSG); + if (!sig.verify(origSign)) { + throw new RuntimeException(String.format("Signature did not verify" + + " for name:%s, prehash:%s, context:%s", name, + (params == null) ? null : params.isPrehash(), + (params == null) ? null : params.getContext().get())); + } + + // Create a new signature to re-verify. + sig = Signature.getInstance(name, provider); + if (params != null) { + sig.setParameter(params); + } + // Verify the signature with transformed PublicKey. + sig.initVerify(kp.getPublic()); + sig.update(MSG); + if (!sig.verify(origSign)) { + throw new RuntimeException(String.format("Signature did not verify" + + " for name:%s, prehash:%s, context:%s", + name, (params == null) ? null : params.isPrehash(), + (params == null) ? null : params.getContext().get())); + } + equals(sig.getAlgorithm(), name); + equals(sig.getProvider().getName(), provider); + } + + private static int edSignatureSize(String algo) { + int size = switch (algo) { + case EDDSA + , ED25519, OIDN25519, OID25519 -> 64; + case ED448 + , OIDN448, OID448 -> 114; + default-> + -1; + }; + return size; + } + + /** + * Compare original KeyPair with transformed ones. + */ + private static void testKeyEquals(KeyPair origkp, PublicKey pubKey, + PrivateKey priKey) { + + if (!origkp.getPrivate().equals(priKey) + && !Arrays.equals(origkp.getPrivate().getEncoded(), + priKey.getEncoded()) + && origkp.getPrivate().hashCode() != priKey.hashCode()) { + throw new RuntimeException( + "PrivateKey is not equal with transformed one"); + } + if (!origkp.getPublic().equals(pubKey) + && !Arrays.equals(origkp.getPublic().getEncoded(), + pubKey.getEncoded()) + && origkp.getPublic().hashCode() != pubKey.hashCode()) { + throw new RuntimeException( + "PublicKey is not equal with transformed one"); + } + } + + /** + * Test serialization of KeyPair and Keys. + */ + private static void testSerialize(KeyPair origkp, KeyPair kp) + throws Exception { + + testKeyEquals(origkp, kp.getPublic(), kp.getPrivate()); + PrivateKey priv = deserializedCopy(kp.getPrivate(), PrivateKey.class); + PublicKey pub = deserializedCopy(kp.getPublic(), PublicKey.class); + testKeyEquals(origkp, pub, priv); + // Verify Serialized KeyPair instance. + KeyPair copy = deserializedCopy(kp, KeyPair.class); + testKeyEquals(origkp, copy.getPublic(), copy.getPrivate()); + } + + private static T deserializedCopy(T origkp, Class type) + throws IOException, ClassNotFoundException { + return deserialize(serialize(origkp), type); + } + + /** + * Deserialize the Key object. + */ + private static T deserialize(byte[] serialized, + Class type) throws IOException, ClassNotFoundException { + + T key = null; + try (ByteArrayInputStream bis = new ByteArrayInputStream(serialized); + ObjectInputStream ois = new ObjectInputStream(bis)) { + key = (T) ois.readObject(); + } + return key; + } + + /** + * Serialize the given Key object. + */ + private static byte[] serialize(T key) + throws IOException { + + try (ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(bos)) { + oos.writeObject(key); + return bos.toByteArray(); + } + } + + private static void equals(Object actual, Object expected) { + if (!actual.equals(expected)) { + throw new RuntimeException(String.format("Actual: %s, Expected: %s", + actual, expected)); + } + } + + private static void equals(byte[] actual, byte[] expected) { + if (!Arrays.equals(actual, expected)) { + throw new RuntimeException(String.format("Actual array: %s, " + + "Expected array:%s", Convert.byteArrayToHexString(actual), + Convert.byteArrayToHexString(expected))); + } + } +} From ebf928a0e7d02ab66be47f78dd85e78c1147c2f3 Mon Sep 17 00:00:00 2001 From: Yasumasa Suenaga Date: Tue, 19 May 2020 20:58:51 +0900 Subject: [PATCH 114/143] 8244819: hsdis does not compile with binutils 2.34+ Reviewed-by: kvn, thartmann --- src/utils/hsdis/hsdis.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/utils/hsdis/hsdis.c b/src/utils/hsdis/hsdis.c index 37d1df55976..8de38bb7278 100644 --- a/src/utils/hsdis/hsdis.c +++ b/src/utils/hsdis/hsdis.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -568,7 +568,12 @@ static void init_disassemble_info_from_bfd(struct disassemble_info* dinfo, dinfo->arch = bfd_get_arch(abfd); dinfo->mach = bfd_get_mach(abfd); dinfo->disassembler_options = disassembler_options; +#if BFD_VERSION >= 234000000 + /* bfd_octets_per_byte() has 2 args since binutils 2.34 */ + dinfo->octets_per_byte = bfd_octets_per_byte (abfd, NULL); +#else dinfo->octets_per_byte = bfd_octets_per_byte (abfd); +#endif dinfo->skip_zeroes = sizeof(void*) * 2; dinfo->skip_zeroes_at_end = sizeof(void*)-1; dinfo->disassembler_needs_relocs = FALSE; From b6fde85f332b928f8a4cb26ae68b992fe2f07f86 Mon Sep 17 00:00:00 2001 From: Martin Doerr Date: Tue, 19 May 2020 15:11:58 +0200 Subject: [PATCH 115/143] 8245047: [PPC64] C2: ReverseBytes + Load always match to unordered Load (acquire semantics missing) Introduce separate nodes with acquire semantics which match ReverseBytes + Load.acquire. Reviewed-by: shade, lucy --- src/hotspot/cpu/ppc/ppc.ad | 59 +++++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/src/hotspot/cpu/ppc/ppc.ad b/src/hotspot/cpu/ppc/ppc.ad index ecf2b32f86d..ff85a36f39d 100644 --- a/src/hotspot/cpu/ppc/ppc.ad +++ b/src/hotspot/cpu/ppc/ppc.ad @@ -13830,6 +13830,7 @@ instruct bytes_reverse_short_Ex(iRegIdst dst, iRegIsrc src) %{ // Load Integer reversed byte order instruct loadI_reversed(iRegIdst dst, indirect mem) %{ match(Set dst (ReverseBytesI (LoadI mem))); + predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1))); ins_cost(MEMORY_REF_COST); size(4); @@ -13839,10 +13840,23 @@ instruct loadI_reversed(iRegIdst dst, indirect mem) %{ ins_pipe(pipe_class_default); %} +instruct loadI_reversed_acquire(iRegIdst dst, indirect mem) %{ + match(Set dst (ReverseBytesI (LoadI mem))); + ins_cost(2 * MEMORY_REF_COST); + + size(12); + ins_encode %{ + __ lwbrx($dst$$Register, $mem$$Register); + __ twi_0($dst$$Register); + __ isync(); + %} + ins_pipe(pipe_class_default); +%} + // Load Long - aligned and reversed instruct loadL_reversed(iRegLdst dst, indirect mem) %{ match(Set dst (ReverseBytesL (LoadL mem))); - predicate(VM_Version::has_ldbrx()); + predicate(VM_Version::has_ldbrx() && (n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1)))); ins_cost(MEMORY_REF_COST); size(4); @@ -13852,9 +13866,24 @@ instruct loadL_reversed(iRegLdst dst, indirect mem) %{ ins_pipe(pipe_class_default); %} +instruct loadL_reversed_acquire(iRegLdst dst, indirect mem) %{ + match(Set dst (ReverseBytesL (LoadL mem))); + predicate(VM_Version::has_ldbrx()); + ins_cost(2 * MEMORY_REF_COST); + + size(12); + ins_encode %{ + __ ldbrx($dst$$Register, $mem$$Register); + __ twi_0($dst$$Register); + __ isync(); + %} + ins_pipe(pipe_class_default); +%} + // Load unsigned short / char reversed byte order instruct loadUS_reversed(iRegIdst dst, indirect mem) %{ match(Set dst (ReverseBytesUS (LoadUS mem))); + predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1))); ins_cost(MEMORY_REF_COST); size(4); @@ -13864,9 +13893,23 @@ instruct loadUS_reversed(iRegIdst dst, indirect mem) %{ ins_pipe(pipe_class_default); %} +instruct loadUS_reversed_acquire(iRegIdst dst, indirect mem) %{ + match(Set dst (ReverseBytesUS (LoadUS mem))); + ins_cost(2 * MEMORY_REF_COST); + + size(12); + ins_encode %{ + __ lhbrx($dst$$Register, $mem$$Register); + __ twi_0($dst$$Register); + __ isync(); + %} + ins_pipe(pipe_class_default); +%} + // Load short reversed byte order instruct loadS_reversed(iRegIdst dst, indirect mem) %{ match(Set dst (ReverseBytesS (LoadS mem))); + predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1))); ins_cost(MEMORY_REF_COST + DEFAULT_COST); size(8); @@ -13877,6 +13920,20 @@ instruct loadS_reversed(iRegIdst dst, indirect mem) %{ ins_pipe(pipe_class_default); %} +instruct loadS_reversed_acquire(iRegIdst dst, indirect mem) %{ + match(Set dst (ReverseBytesS (LoadS mem))); + ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST); + + size(16); + ins_encode %{ + __ lhbrx($dst$$Register, $mem$$Register); + __ twi_0($dst$$Register); + __ extsh($dst$$Register, $dst$$Register); + __ isync(); + %} + ins_pipe(pipe_class_default); +%} + // Store Integer reversed byte order instruct storeI_reversed(iRegIsrc src, indirect mem) %{ match(Set mem (StoreI mem (ReverseBytesI src))); From 74f1e6da4e54656ed6a51d32ecd3da00ec23409d Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Tue, 19 May 2020 15:49:46 +0200 Subject: [PATCH 116/143] 8244093: Move all IDE support into coherent structure in make directory Reviewed-by: mcimadamore, jlahoda, chegar, erikj --- bin/idea.sh | 2 +- make/Main.gmk | 10 +- make/{idea => ide/idea/jdk}/build.xml | 0 make/ide/idea/jdk/idea.gmk | 58 + make/{idea => ide/idea/jdk}/template/.name | 0 make/{idea => ide/idea/jdk}/template/ant.xml | 2 +- .../idea/jdk}/template/compiler.xml | 0 .../template/copyright/profiles_settings.xml | 0 make/{idea => ide/idea/jdk}/template/jdk.iml | 0 make/{idea => ide/idea/jdk}/template/misc.xml | 2 +- .../idea/jdk}/template/modules.xml | 0 .../jdk}/template/scopes/scope_settings.xml | 0 .../template/src/idea/IdeaLoggerWrapper.java | 0 .../template/src/idea/JdkIdeaAntLogger.java | 0 make/{idea => ide/idea/jdk}/template/vcs.xml | 0 .../idea/jdk}/template/workspace.xml | 2 +- .../intellij => ide/idea/langtools}/build.xml | 4 +- .../idea/langtools}/template/ant.xml | 2 +- .../langtools}/template/codeStyleSettings.xml | 0 .../idea/langtools}/template/compiler.xml | 0 .../template/copyright/langtools.xml | 0 .../template/copyright/profiles_settings.xml | 0 .../template/inspectionProfiles/langtools.xml | 0 .../inspectionProfiles/profiles_settings.xml | 0 .../idea/langtools}/template/langtools.iml | 0 .../idea/langtools}/template/misc.xml | 2 +- .../idea/langtools}/template/modules.xml | 0 .../template/runConfigurations/javac.xml | 2 +- .../template/runConfigurations/javadoc.xml | 2 +- .../template/runConfigurations/javap.xml | 2 +- .../template/runConfigurations/jshell.xml | 2 +- .../template/runConfigurations/sjavac.xml | 2 +- .../template/src/idea/IdeaLoggerWrapper.java | 0 .../src/idea/LangtoolsIdeaAntLogger.java | 0 .../idea/langtools}/template/vcs.xml | 0 .../idea/langtools}/template/workspace.xml | 2 +- .../hotspot}/nbproject/configurations.xml | 0 .../netbeans/hotspot}/nbproject/project.xml | 0 .../netbeans/langtools}/README | 0 .../netbeans/langtools/build.xml | 0 .../langtools/nbproject/project.properties | 0 .../netbeans/langtools/nbproject/project.xml | 0 .../visualstudio/hotspot}/CreateVSProject.gmk | 4 +- .../tools/projectcreator/ArgsParser.java | 0 .../tools/projectcreator/BuildConfig.java | 0 .../tools/projectcreator/FileTreeCreator.java | 0 .../projectcreator/FileTreeCreatorVC10.java | 0 .../tools/projectcreator/ProjectCreator.java | 0 .../build/tools/projectcreator/Util.java | 0 .../projectcreator/WinGammaPlatform.java | 0 .../projectcreator/WinGammaPlatformVC10.java | 0 .../vscode/hotspot}/CreateVSCodeProject.gmk | 12 +- .../hotspot}/indexers/ccls-extensions.txt | 0 .../vscode/hotspot}/indexers/ccls-notes.txt | 0 .../hotspot}/indexers/ccls-settings.txt | 0 .../hotspot}/indexers/clangd-extensions.txt | 0 .../vscode/hotspot}/indexers/clangd-notes.txt | 0 .../hotspot}/indexers/clangd-settings.txt | 0 .../hotspot}/indexers/cpptools-extensions.txt | 0 .../hotspot}/indexers/cpptools-settings.txt | 0 .../hotspot}/indexers/rtags-extensions.txt | 0 .../hotspot}/indexers/rtags-settings.txt | 0 .../vscode/hotspot}/template-launch.jsonc | 0 .../vscode/hotspot}/template-tasks.jsonc | 0 .../hotspot}/template-workspace-folder.txt | 0 .../vscode/hotspot}/template-workspace.jsonc | 0 make/idea/idea.gmk | 33 - make/jdk/netbeans/README | 622 ------- make/jdk/netbeans/awt2d/README | 220 --- make/jdk/netbeans/awt2d/build.properties | 76 - make/jdk/netbeans/awt2d/build.xml | 100 -- make/jdk/netbeans/awt2d/nbproject/project.xml | 96 -- make/jdk/netbeans/client_sanity/README | 15 - make/jdk/netbeans/client_sanity/build.xml | 94 -- make/jdk/netbeans/client_sanity/manifest.mf | 3 - .../client_sanity/nbproject/build-impl.xml | 1429 ----------------- .../nbproject/genfiles.properties | 8 - .../nbproject/project.properties | 79 - .../client_sanity/nbproject/project.xml | 17 - make/jdk/netbeans/common/README-ent | 25 - make/jdk/netbeans/common/architectures/README | 3 - .../architectures/arch-amd64.properties | 32 - .../common/architectures/arch-i386.properties | 32 - .../architectures/arch-sparc.properties | 32 - .../common/architectures/arch-x86.properties | 32 - .../architectures/arch-x86_64.properties | 32 - .../common/architectures/name-Bsd.properties | 32 - .../architectures/name-Linux.properties | 32 - .../architectures/name-Macosx.properties | 32 - .../architectures/name-SunOS.properties | 32 - make/jdk/netbeans/common/build-folder.ent | 36 - .../netbeans/common/closed-share-sources.ent | 47 - .../jdk/netbeans/common/closed-share-view.ent | 39 - make/jdk/netbeans/common/demo-sources.ent | 38 - make/jdk/netbeans/common/demo-view.ent | 38 - make/jdk/netbeans/common/file-view.ent | 45 - make/jdk/netbeans/common/java-data-native.ent | 51 - .../netbeans/common/java-data-no-native.ent | 48 - make/jdk/netbeans/common/jtreg-sources.ent | 38 - make/jdk/netbeans/common/jtreg-view.ent | 38 - make/jdk/netbeans/common/macosx-sources.ent | 49 - make/jdk/netbeans/common/macosx-view.ent | 43 - make/jdk/netbeans/common/make.xml | 78 - make/jdk/netbeans/common/properties.ent | 45 - make/jdk/netbeans/common/sample-sources.ent | 38 - make/jdk/netbeans/common/sample-view.ent | 38 - make/jdk/netbeans/common/share-sources.ent | 45 - make/jdk/netbeans/common/share-view.ent | 39 - make/jdk/netbeans/common/shared.xml | 377 ----- make/jdk/netbeans/common/standard-actions.ent | 39 - .../jdk/netbeans/common/standard-bindings.ent | 177 -- make/jdk/netbeans/common/unix-sources.ent | 49 - make/jdk/netbeans/common/unix-view.ent | 43 - make/jdk/netbeans/common/windows-sources.ent | 45 - make/jdk/netbeans/common/windows-view.ent | 39 - make/jdk/netbeans/j2se/README | 13 - make/jdk/netbeans/j2se/build.properties | 35 - make/jdk/netbeans/j2se/build.xml | 47 - make/jdk/netbeans/j2se/nbproject/project.xml | 107 -- make/jdk/netbeans/jarzip/README | 38 - make/jdk/netbeans/jarzip/build.properties | 46 - make/jdk/netbeans/jarzip/build.xml | 48 - .../jdk/netbeans/jarzip/nbproject/project.xml | 76 - make/jdk/netbeans/jconsole/README | 67 - make/jdk/netbeans/jconsole/build.properties | 47 - make/jdk/netbeans/jconsole/build.xml | 74 - .../netbeans/jconsole/nbproject/project.xml | 84 - make/jdk/netbeans/jdbc/README | 64 - make/jdk/netbeans/jdbc/build.properties | 46 - make/jdk/netbeans/jdbc/build.xml | 52 - make/jdk/netbeans/jdbc/nbproject/project.xml | 88 - make/jdk/netbeans/jdwpgen/build.xml | 74 - .../netbeans/jdwpgen/nbproject/build-impl.xml | 642 -------- .../jdwpgen/nbproject/findbugs.settings | 72 - .../jdwpgen/nbproject/genfiles.properties | 8 - .../jdwpgen/nbproject/project.properties | 65 - .../netbeans/jdwpgen/nbproject/project.xml | 16 - .../netbeans/jdwpgen/nbproject/sqe.properties | 2 - make/jdk/netbeans/jmx/README | 90 -- make/jdk/netbeans/jmx/build.properties | 55 - make/jdk/netbeans/jmx/build.xml | 89 - make/jdk/netbeans/jmx/nbproject/project.xml | 77 - make/jdk/netbeans/swing/README | 62 - make/jdk/netbeans/swing/build.properties | 40 - make/jdk/netbeans/swing/build.xml | 116 -- make/jdk/netbeans/swing/nbproject/project.xml | 84 - make/jdk/netbeans/world/README | 15 - make/jdk/netbeans/world/build.properties | 34 - make/jdk/netbeans/world/build.xml | 44 - make/jdk/netbeans/world/nbproject/project.xml | 84 - make/langtools/build.xml | 5 +- 151 files changed, 88 insertions(+), 7300 deletions(-) rename make/{idea => ide/idea/jdk}/build.xml (100%) create mode 100644 make/ide/idea/jdk/idea.gmk rename make/{idea => ide/idea/jdk}/template/.name (100%) rename make/{idea => ide/idea/jdk}/template/ant.xml (87%) rename make/{idea => ide/idea/jdk}/template/compiler.xml (100%) rename make/{idea => ide/idea/jdk}/template/copyright/profiles_settings.xml (100%) rename make/{idea => ide/idea/jdk}/template/jdk.iml (100%) rename make/{idea => ide/idea/jdk}/template/misc.xml (86%) rename make/{idea => ide/idea/jdk}/template/modules.xml (100%) rename make/{idea => ide/idea/jdk}/template/scopes/scope_settings.xml (100%) rename make/{idea => ide/idea/jdk}/template/src/idea/IdeaLoggerWrapper.java (100%) rename make/{idea => ide/idea/jdk}/template/src/idea/JdkIdeaAntLogger.java (100%) rename make/{idea => ide/idea/jdk}/template/vcs.xml (100%) rename make/{idea => ide/idea/jdk}/template/workspace.xml (96%) rename make/{langtools/intellij => ide/idea/langtools}/build.xml (76%) rename make/{langtools/intellij => ide/idea/langtools}/template/ant.xml (85%) rename make/{langtools/intellij => ide/idea/langtools}/template/codeStyleSettings.xml (100%) rename make/{langtools/intellij => ide/idea/langtools}/template/compiler.xml (100%) rename make/{langtools/intellij => ide/idea/langtools}/template/copyright/langtools.xml (100%) rename make/{langtools/intellij => ide/idea/langtools}/template/copyright/profiles_settings.xml (100%) rename make/{langtools/intellij => ide/idea/langtools}/template/inspectionProfiles/langtools.xml (100%) rename make/{langtools/intellij => ide/idea/langtools}/template/inspectionProfiles/profiles_settings.xml (100%) rename make/{langtools/intellij => ide/idea/langtools}/template/langtools.iml (100%) rename make/{langtools/intellij => ide/idea/langtools}/template/misc.xml (90%) rename make/{langtools/intellij => ide/idea/langtools}/template/modules.xml (100%) rename make/{langtools/intellij => ide/idea/langtools}/template/runConfigurations/javac.xml (94%) rename make/{langtools/intellij => ide/idea/langtools}/template/runConfigurations/javadoc.xml (94%) rename make/{langtools/intellij => ide/idea/langtools}/template/runConfigurations/javap.xml (94%) rename make/{langtools/intellij => ide/idea/langtools}/template/runConfigurations/jshell.xml (94%) rename make/{langtools/intellij => ide/idea/langtools}/template/runConfigurations/sjavac.xml (94%) rename make/{langtools/intellij => ide/idea/langtools}/template/src/idea/IdeaLoggerWrapper.java (100%) rename make/{langtools/intellij => ide/idea/langtools}/template/src/idea/LangtoolsIdeaAntLogger.java (100%) rename make/{langtools/intellij => ide/idea/langtools}/template/vcs.xml (100%) rename make/{langtools/intellij => ide/idea/langtools}/template/workspace.xml (92%) rename make/{nb_native => ide/netbeans/hotspot}/nbproject/configurations.xml (100%) rename make/{nb_native => ide/netbeans/hotspot}/nbproject/project.xml (100%) rename make/{langtools/netbeans => ide/netbeans/langtools}/README (100%) rename make/{langtools => ide}/netbeans/langtools/build.xml (100%) rename make/{langtools => ide}/netbeans/langtools/nbproject/project.properties (100%) rename make/{langtools => ide}/netbeans/langtools/nbproject/project.xml (100%) rename make/{hotspot/ide => ide/visualstudio/hotspot}/CreateVSProject.gmk (97%) rename make/{ => ide/visualstudio}/hotspot/src/classes/build/tools/projectcreator/ArgsParser.java (100%) rename make/{ => ide/visualstudio}/hotspot/src/classes/build/tools/projectcreator/BuildConfig.java (100%) rename make/{ => ide/visualstudio}/hotspot/src/classes/build/tools/projectcreator/FileTreeCreator.java (100%) rename make/{ => ide/visualstudio}/hotspot/src/classes/build/tools/projectcreator/FileTreeCreatorVC10.java (100%) rename make/{ => ide/visualstudio}/hotspot/src/classes/build/tools/projectcreator/ProjectCreator.java (100%) rename make/{ => ide/visualstudio}/hotspot/src/classes/build/tools/projectcreator/Util.java (100%) rename make/{ => ide/visualstudio}/hotspot/src/classes/build/tools/projectcreator/WinGammaPlatform.java (100%) rename make/{ => ide/visualstudio}/hotspot/src/classes/build/tools/projectcreator/WinGammaPlatformVC10.java (100%) rename make/{vscode => ide/vscode/hotspot}/CreateVSCodeProject.gmk (89%) rename make/{vscode => ide/vscode/hotspot}/indexers/ccls-extensions.txt (100%) rename make/{vscode => ide/vscode/hotspot}/indexers/ccls-notes.txt (100%) rename make/{vscode => ide/vscode/hotspot}/indexers/ccls-settings.txt (100%) rename make/{vscode => ide/vscode/hotspot}/indexers/clangd-extensions.txt (100%) rename make/{vscode => ide/vscode/hotspot}/indexers/clangd-notes.txt (100%) rename make/{vscode => ide/vscode/hotspot}/indexers/clangd-settings.txt (100%) rename make/{vscode => ide/vscode/hotspot}/indexers/cpptools-extensions.txt (100%) rename make/{vscode => ide/vscode/hotspot}/indexers/cpptools-settings.txt (100%) rename make/{vscode => ide/vscode/hotspot}/indexers/rtags-extensions.txt (100%) rename make/{vscode => ide/vscode/hotspot}/indexers/rtags-settings.txt (100%) rename make/{vscode => ide/vscode/hotspot}/template-launch.jsonc (100%) rename make/{vscode => ide/vscode/hotspot}/template-tasks.jsonc (100%) rename make/{vscode => ide/vscode/hotspot}/template-workspace-folder.txt (100%) rename make/{vscode => ide/vscode/hotspot}/template-workspace.jsonc (100%) delete mode 100644 make/idea/idea.gmk delete mode 100644 make/jdk/netbeans/README delete mode 100644 make/jdk/netbeans/awt2d/README delete mode 100644 make/jdk/netbeans/awt2d/build.properties delete mode 100644 make/jdk/netbeans/awt2d/build.xml delete mode 100644 make/jdk/netbeans/awt2d/nbproject/project.xml delete mode 100644 make/jdk/netbeans/client_sanity/README delete mode 100644 make/jdk/netbeans/client_sanity/build.xml delete mode 100644 make/jdk/netbeans/client_sanity/manifest.mf delete mode 100644 make/jdk/netbeans/client_sanity/nbproject/build-impl.xml delete mode 100644 make/jdk/netbeans/client_sanity/nbproject/genfiles.properties delete mode 100644 make/jdk/netbeans/client_sanity/nbproject/project.properties delete mode 100644 make/jdk/netbeans/client_sanity/nbproject/project.xml delete mode 100644 make/jdk/netbeans/common/README-ent delete mode 100644 make/jdk/netbeans/common/architectures/README delete mode 100644 make/jdk/netbeans/common/architectures/arch-amd64.properties delete mode 100644 make/jdk/netbeans/common/architectures/arch-i386.properties delete mode 100644 make/jdk/netbeans/common/architectures/arch-sparc.properties delete mode 100644 make/jdk/netbeans/common/architectures/arch-x86.properties delete mode 100644 make/jdk/netbeans/common/architectures/arch-x86_64.properties delete mode 100644 make/jdk/netbeans/common/architectures/name-Bsd.properties delete mode 100644 make/jdk/netbeans/common/architectures/name-Linux.properties delete mode 100644 make/jdk/netbeans/common/architectures/name-Macosx.properties delete mode 100644 make/jdk/netbeans/common/architectures/name-SunOS.properties delete mode 100644 make/jdk/netbeans/common/build-folder.ent delete mode 100644 make/jdk/netbeans/common/closed-share-sources.ent delete mode 100644 make/jdk/netbeans/common/closed-share-view.ent delete mode 100644 make/jdk/netbeans/common/demo-sources.ent delete mode 100644 make/jdk/netbeans/common/demo-view.ent delete mode 100644 make/jdk/netbeans/common/file-view.ent delete mode 100644 make/jdk/netbeans/common/java-data-native.ent delete mode 100644 make/jdk/netbeans/common/java-data-no-native.ent delete mode 100644 make/jdk/netbeans/common/jtreg-sources.ent delete mode 100644 make/jdk/netbeans/common/jtreg-view.ent delete mode 100644 make/jdk/netbeans/common/macosx-sources.ent delete mode 100644 make/jdk/netbeans/common/macosx-view.ent delete mode 100644 make/jdk/netbeans/common/make.xml delete mode 100644 make/jdk/netbeans/common/properties.ent delete mode 100644 make/jdk/netbeans/common/sample-sources.ent delete mode 100644 make/jdk/netbeans/common/sample-view.ent delete mode 100644 make/jdk/netbeans/common/share-sources.ent delete mode 100644 make/jdk/netbeans/common/share-view.ent delete mode 100644 make/jdk/netbeans/common/shared.xml delete mode 100644 make/jdk/netbeans/common/standard-actions.ent delete mode 100644 make/jdk/netbeans/common/standard-bindings.ent delete mode 100644 make/jdk/netbeans/common/unix-sources.ent delete mode 100644 make/jdk/netbeans/common/unix-view.ent delete mode 100644 make/jdk/netbeans/common/windows-sources.ent delete mode 100644 make/jdk/netbeans/common/windows-view.ent delete mode 100644 make/jdk/netbeans/j2se/README delete mode 100644 make/jdk/netbeans/j2se/build.properties delete mode 100644 make/jdk/netbeans/j2se/build.xml delete mode 100644 make/jdk/netbeans/j2se/nbproject/project.xml delete mode 100644 make/jdk/netbeans/jarzip/README delete mode 100644 make/jdk/netbeans/jarzip/build.properties delete mode 100644 make/jdk/netbeans/jarzip/build.xml delete mode 100644 make/jdk/netbeans/jarzip/nbproject/project.xml delete mode 100644 make/jdk/netbeans/jconsole/README delete mode 100644 make/jdk/netbeans/jconsole/build.properties delete mode 100644 make/jdk/netbeans/jconsole/build.xml delete mode 100644 make/jdk/netbeans/jconsole/nbproject/project.xml delete mode 100644 make/jdk/netbeans/jdbc/README delete mode 100644 make/jdk/netbeans/jdbc/build.properties delete mode 100644 make/jdk/netbeans/jdbc/build.xml delete mode 100644 make/jdk/netbeans/jdbc/nbproject/project.xml delete mode 100644 make/jdk/netbeans/jdwpgen/build.xml delete mode 100644 make/jdk/netbeans/jdwpgen/nbproject/build-impl.xml delete mode 100644 make/jdk/netbeans/jdwpgen/nbproject/findbugs.settings delete mode 100644 make/jdk/netbeans/jdwpgen/nbproject/genfiles.properties delete mode 100644 make/jdk/netbeans/jdwpgen/nbproject/project.properties delete mode 100644 make/jdk/netbeans/jdwpgen/nbproject/project.xml delete mode 100644 make/jdk/netbeans/jdwpgen/nbproject/sqe.properties delete mode 100644 make/jdk/netbeans/jmx/README delete mode 100644 make/jdk/netbeans/jmx/build.properties delete mode 100644 make/jdk/netbeans/jmx/build.xml delete mode 100644 make/jdk/netbeans/jmx/nbproject/project.xml delete mode 100644 make/jdk/netbeans/swing/README delete mode 100644 make/jdk/netbeans/swing/build.properties delete mode 100644 make/jdk/netbeans/swing/build.xml delete mode 100644 make/jdk/netbeans/swing/nbproject/project.xml delete mode 100644 make/jdk/netbeans/world/README delete mode 100644 make/jdk/netbeans/world/build.properties delete mode 100644 make/jdk/netbeans/world/build.xml delete mode 100644 make/jdk/netbeans/world/nbproject/project.xml diff --git a/bin/idea.sh b/bin/idea.sh index ca674e2925d..ad89aedacbc 100644 --- a/bin/idea.sh +++ b/bin/idea.sh @@ -74,7 +74,7 @@ if [ "x$TOPLEVEL_DIR" = "x" ] ; then fi MAKE_DIR="$SCRIPT_DIR/../make" -IDEA_MAKE="$MAKE_DIR/idea" +IDEA_MAKE="$MAKE_DIR/ide/idea/jdk" IDEA_TEMPLATE="$IDEA_MAKE/template" cp -r "$IDEA_TEMPLATE"/* "$IDEA_OUTPUT" diff --git a/make/Main.gmk b/make/Main.gmk index 0b303fa52f8..e4d6d696b99 100644 --- a/make/Main.gmk +++ b/make/Main.gmk @@ -261,7 +261,7 @@ endef $(foreach v, $(JVM_VARIANTS), $(eval $(call DeclareHotspotLibsRecipe,$v))) $(eval $(call SetupTarget, hotspot-ide-project, \ - MAKEFILE := hotspot/ide/CreateVSProject, \ + MAKEFILE := ide/visualstudio/hotspot/CreateVSProject, \ DEPS := hotspot exploded-image, \ ARGS := -I$(TOPDIR)/make/hotspot, \ )) @@ -302,25 +302,25 @@ ALL_TARGETS += $(COMPILE_COMMANDS_TARGETS_HOTSPOT) $(COMPILE_COMMANDS_TARGETS_JD # VS Code projects $(eval $(call SetupTarget, vscode-project, \ - MAKEFILE := CreateVSCodeProject, \ + MAKEFILE := ide/vscode/hotspot/CreateVSCodeProject, \ ARGS := VSCODE_INDEXER=cpptools, \ DEPS := compile-commands, \ )) $(eval $(call SetupTarget, vscode-project-clangd, \ - MAKEFILE := CreateVSCodeProject, \ + MAKEFILE := ide/vscode/hotspot/CreateVSCodeProject, \ ARGS := VSCODE_INDEXER=clangd, \ DEPS := compile-commands, \ )) $(eval $(call SetupTarget, vscode-project-rtags, \ - MAKEFILE := CreateVSCodeProject, \ + MAKEFILE := ide/vscode/hotspot/CreateVSCodeProject, \ ARGS := VSCODE_INDEXER=rtags, \ DEPS := compile-commands, \ )) $(eval $(call SetupTarget, vscode-project-ccls, \ - MAKEFILE := CreateVSCodeProject, \ + MAKEFILE := ide/vscode/hotspot/CreateVSCodeProject, \ ARGS := VSCODE_INDEXER=ccls, \ DEPS := compile-commands, \ )) diff --git a/make/idea/build.xml b/make/ide/idea/jdk/build.xml similarity index 100% rename from make/idea/build.xml rename to make/ide/idea/jdk/build.xml diff --git a/make/ide/idea/jdk/idea.gmk b/make/ide/idea/jdk/idea.gmk new file mode 100644 index 00000000000..9d286c961d1 --- /dev/null +++ b/make/ide/idea/jdk/idea.gmk @@ -0,0 +1,58 @@ +# +# 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. 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. +# + +include Makefile +include make/MainSupport.gmk + +.PHONY: idea + +ifeq ($(SPEC),) + ifneq ($(words $(SPECS)),1) + @echo "Error: Multiple build specification files found. Please select one explicitly." + @exit 2 + endif + idea: + @cd $(topdir) + @$(MAKE) $(MFLAGS) $(MAKE_LOG_FLAGS) -r -R -j 1 -f $(topdir)/make/ide/idea/jdk/idea.gmk SPEC=$(SPECS) HAS_SPEC=true ACTUAL_TOPDIR=$(topdir) MODULES="$(MODULES)" idea +else #with SPEC + include make/common/Modules.gmk + + ifeq ($(MODULES),) + SEL_MODULES := $(call FindAllModules) + else + SEL_MODULES := $(MODULES) + endif + + idea: + $(ECHO) "SUPPORT=$(SUPPORT_OUTPUTDIR)" >> $(OUT) + $(ECHO) "MODULE_ROOTS=\"$(foreach mod, $(SEL_MODULES), $(call FindModuleSrcDirs,$(mod)))\"" >> $(OUT) + $(ECHO) "MODULE_NAMES=\"$(strip $(foreach mod, $(SEL_MODULES), $(mod)))\"" >> $(OUT) + $(ECHO) "SEL_MODULES=\"$(SEL_MODULES)\"" >> $(OUT) + $(ECHO) "BOOT_JDK=\"$(BOOT_JDK)\"" >> $(OUT) + $(ECHO) "CYGPATH=\"$(CYGPATH)\"" >> $(OUT) + $(ECHO) "SPEC=\"$(SPEC)\"" >> $(OUT) + $(ECHO) "JT_HOME=\"$(JT_HOME)\"" >> $(OUT) + +endif diff --git a/make/idea/template/.name b/make/ide/idea/jdk/template/.name similarity index 100% rename from make/idea/template/.name rename to make/ide/idea/jdk/template/.name diff --git a/make/idea/template/ant.xml b/make/ide/idea/jdk/template/ant.xml similarity index 87% rename from make/idea/template/ant.xml rename to make/ide/idea/jdk/template/ant.xml index c99a025be03..9cb90246ea0 100644 --- a/make/idea/template/ant.xml +++ b/make/ide/idea/jdk/template/ant.xml @@ -1,7 +1,7 @@ - + diff --git a/make/idea/template/compiler.xml b/make/ide/idea/jdk/template/compiler.xml similarity index 100% rename from make/idea/template/compiler.xml rename to make/ide/idea/jdk/template/compiler.xml diff --git a/make/idea/template/copyright/profiles_settings.xml b/make/ide/idea/jdk/template/copyright/profiles_settings.xml similarity index 100% rename from make/idea/template/copyright/profiles_settings.xml rename to make/ide/idea/jdk/template/copyright/profiles_settings.xml diff --git a/make/idea/template/jdk.iml b/make/ide/idea/jdk/template/jdk.iml similarity index 100% rename from make/idea/template/jdk.iml rename to make/ide/idea/jdk/template/jdk.iml diff --git a/make/idea/template/misc.xml b/make/ide/idea/jdk/template/misc.xml similarity index 86% rename from make/idea/template/misc.xml rename to make/ide/idea/jdk/template/misc.xml index f9e33b817d7..d05605a4041 100644 --- a/make/idea/template/misc.xml +++ b/make/ide/idea/jdk/template/misc.xml @@ -9,7 +9,7 @@ - + diff --git a/make/idea/template/modules.xml b/make/ide/idea/jdk/template/modules.xml similarity index 100% rename from make/idea/template/modules.xml rename to make/ide/idea/jdk/template/modules.xml diff --git a/make/idea/template/scopes/scope_settings.xml b/make/ide/idea/jdk/template/scopes/scope_settings.xml similarity index 100% rename from make/idea/template/scopes/scope_settings.xml rename to make/ide/idea/jdk/template/scopes/scope_settings.xml diff --git a/make/idea/template/src/idea/IdeaLoggerWrapper.java b/make/ide/idea/jdk/template/src/idea/IdeaLoggerWrapper.java similarity index 100% rename from make/idea/template/src/idea/IdeaLoggerWrapper.java rename to make/ide/idea/jdk/template/src/idea/IdeaLoggerWrapper.java diff --git a/make/idea/template/src/idea/JdkIdeaAntLogger.java b/make/ide/idea/jdk/template/src/idea/JdkIdeaAntLogger.java similarity index 100% rename from make/idea/template/src/idea/JdkIdeaAntLogger.java rename to make/ide/idea/jdk/template/src/idea/JdkIdeaAntLogger.java diff --git a/make/idea/template/vcs.xml b/make/ide/idea/jdk/template/vcs.xml similarity index 100% rename from make/idea/template/vcs.xml rename to make/ide/idea/jdk/template/vcs.xml diff --git a/make/idea/template/workspace.xml b/make/ide/idea/jdk/template/workspace.xml similarity index 96% rename from make/idea/template/workspace.xml rename to make/ide/idea/jdk/template/workspace.xml index 498ec8df0b3..f1270d4fb5d 100644 --- a/make/idea/template/workspace.xml +++ b/make/ide/idea/jdk/template/workspace.xml @@ -11,7 +11,7 @@ diff --git a/make/langtools/intellij/template/runConfigurations/javap.xml b/make/ide/idea/langtools/template/runConfigurations/javap.xml similarity index 94% rename from make/langtools/intellij/template/runConfigurations/javap.xml rename to make/ide/idea/langtools/template/runConfigurations/javap.xml index 3dcf3e4d18a..38d5cd5289d 100644 --- a/make/langtools/intellij/template/runConfigurations/javap.xml +++ b/make/ide/idea/langtools/template/runConfigurations/javap.xml @@ -16,7 +16,7 @@ diff --git a/make/langtools/intellij/template/runConfigurations/jshell.xml b/make/ide/idea/langtools/template/runConfigurations/jshell.xml similarity index 94% rename from make/langtools/intellij/template/runConfigurations/jshell.xml rename to make/ide/idea/langtools/template/runConfigurations/jshell.xml index 06c2fd21ced..7b849fbc730 100644 --- a/make/langtools/intellij/template/runConfigurations/jshell.xml +++ b/make/ide/idea/langtools/template/runConfigurations/jshell.xml @@ -14,7 +14,7 @@ diff --git a/make/langtools/intellij/template/runConfigurations/sjavac.xml b/make/ide/idea/langtools/template/runConfigurations/sjavac.xml similarity index 94% rename from make/langtools/intellij/template/runConfigurations/sjavac.xml rename to make/ide/idea/langtools/template/runConfigurations/sjavac.xml index 1e613df3deb..cba46ff58d8 100644 --- a/make/langtools/intellij/template/runConfigurations/sjavac.xml +++ b/make/ide/idea/langtools/template/runConfigurations/sjavac.xml @@ -16,7 +16,7 @@ diff --git a/make/langtools/intellij/template/src/idea/IdeaLoggerWrapper.java b/make/ide/idea/langtools/template/src/idea/IdeaLoggerWrapper.java similarity index 100% rename from make/langtools/intellij/template/src/idea/IdeaLoggerWrapper.java rename to make/ide/idea/langtools/template/src/idea/IdeaLoggerWrapper.java diff --git a/make/langtools/intellij/template/src/idea/LangtoolsIdeaAntLogger.java b/make/ide/idea/langtools/template/src/idea/LangtoolsIdeaAntLogger.java similarity index 100% rename from make/langtools/intellij/template/src/idea/LangtoolsIdeaAntLogger.java rename to make/ide/idea/langtools/template/src/idea/LangtoolsIdeaAntLogger.java diff --git a/make/langtools/intellij/template/vcs.xml b/make/ide/idea/langtools/template/vcs.xml similarity index 100% rename from make/langtools/intellij/template/vcs.xml rename to make/ide/idea/langtools/template/vcs.xml diff --git a/make/langtools/intellij/template/workspace.xml b/make/ide/idea/langtools/template/workspace.xml similarity index 92% rename from make/langtools/intellij/template/workspace.xml rename to make/ide/idea/langtools/template/workspace.xml index 94f6d01b59b..9001832c826 100644 --- a/make/langtools/intellij/template/workspace.xml +++ b/make/ide/idea/langtools/template/workspace.xml @@ -6,7 +6,7 @@