diff --git a/.hgtags b/.hgtags index ce61a561609..b013607d06a 100644 --- a/.hgtags +++ b/.hgtags @@ -631,3 +631,4 @@ dd5198db2e5b1ebcafe065d987c03ba9fcb50fc3 jdk-15+17 44aef192b488a48cce12422394691a6b1d16b98e jdk-15+18 7cc27caabe6e342151e8baf549beb07a9c755ec2 jdk-15+19 46bca5e5e6fb26efd07245d26fe96a9c3260f51e jdk-15+20 +12b55fad80f30d24b1f8fdb3b947ea6465ef9518 jdk-15+21 diff --git a/bin/idea.sh b/bin/idea.sh index eedd138fdde..ca674e2925d 100644 --- a/bin/idea.sh +++ b/bin/idea.sh @@ -197,13 +197,15 @@ CP=$ANT_HOME/lib/ant.jar rm -rf $CLASSES; mkdir $CLASSES if [ "x$CYGPATH" = "x" ] ; then ## CYGPATH may be set in env.cfg - JAVAC_SOURCE_FILE=$IDEA_OUTPUT/src/idea/JdkIdeaAntLogger.java + JAVAC_SOURCE_FILE=$IDEA_OUTPUT/src/idea/IdeaLoggerWrapper.java + JAVAC_SOURCE_PATH=$IDEA_OUTPUT/src JAVAC_CLASSES=$CLASSES JAVAC_CP=$CP else - JAVAC_SOURCE_FILE=`cygpath -am $IDEA_OUTPUT/src/idea/JdkIdeaAntLogger.java` + JAVAC_SOURCE_FILE=`cygpath -am $IDEA_OUTPUT/src/idea/IdeaLoggerWrapper.java` + JAVAC_SOURCE_PATH=`cygpath -am $IDEA_OUTPUT/src` JAVAC_CLASSES=`cygpath -am $CLASSES` JAVAC_CP=`cygpath -am $CP` fi -$BOOT_JDK/bin/javac -d $JAVAC_CLASSES -cp $JAVAC_CP $JAVAC_SOURCE_FILE +$BOOT_JDK/bin/javac -d $JAVAC_CLASSES -sourcepath $JAVAC_SOURCE_PATH -cp $JAVAC_CP $JAVAC_SOURCE_FILE diff --git a/doc/building.html b/doc/building.html index 36da52360f0..d715086f69b 100644 --- a/doc/building.html +++ b/doc/building.html @@ -578,7 +578,7 @@
Most of the JDK tests are using the JTReg test framework. Make sure that your configuration knows where to find your installation of JTReg. If this is not picked up automatically, use the --with-jtreg=<path to jtreg home>
option to point to the JTReg framework. Note that this option should point to the JTReg home, i.e. the top directory, containing lib/jtreg.jar
etc.
The Adoption Group provides recent builds of jtreg here. Download the latest .tar.gz
file, unpack it, and point --with-jtreg
to the jtreg
directory that you just unpacked.
The Adoption Group provides recent builds of jtreg here. Download the latest .tar.gz
file, unpack it, and point --with-jtreg
to the jtreg
directory that you just unpacked.
To execute the most basic tests (tier 1), use:
make run-test-tier1
For more details on how to run tests, please see the Testing the JDK document.
diff --git a/doc/building.md b/doc/building.md index 041cb0fe5ea..32069933ec5 100644 --- a/doc/building.md +++ b/doc/building.md @@ -891,7 +891,7 @@ containing `lib/jtreg.jar` etc. The [Adoption Group](https://wiki.openjdk.java.net/display/Adoption) provides recent builds of jtreg [here]( -https://adopt-openjdk.ci.cloudbees.com/job/jtreg/lastSuccessfulBuild/artifact). +https://ci.adoptopenjdk.net/view/Dependencies/job/jtreg/lastSuccessfulBuild/artifact). Download the latest `.tar.gz` file, unpack it, and point `--with-jtreg` to the `jtreg` directory that you just unpacked. diff --git a/doc/testing.html b/doc/testing.html index bb7974cac60..c4ad9e6c40c 100644 --- a/doc/testing.html +++ b/doc/testing.html @@ -56,7 +56,7 @@It is possible to control various aspects of the test suites using make control variables.
These variables use a keyword=value approach to allow multiple values to be set. So, for instance, JTREG="JOBS=1;TIMEOUT_FACTOR=8"
will set the JTReg concurrency level to 1 and the timeout factor to 8. This is equivalent to setting JTREG_JOBS=1 JTREG_TIMEOUT_FACTOR=8
, but using the keyword format means that the JTREG
variable is parsed and verified for correctness, so JTREG="TMIEOUT_FACTOR=8"
would give an error, while JTREG_TMIEOUT_FACTOR=8
would just pass unnoticed.
To separate multiple keyword=value pairs, use ;
(semicolon). Since the shell normally eats ;
, the recommended usage is to write the assignment inside qoutes, e.g. JTREG="...;..."
. This will also make sure spaces are preserved, as in JTREG="VM_OPTIONS=-XshowSettings -Xlog:gc+ref=debug"
.
(Other ways are possible, e.g. using backslash: JTREG=JOBS=1\;TIMEOUT_FACTOR=8
. Also, as a special technique, the string %20
will be replaced with space for certain options, e.g. JTREG=VM_OPTIONS=-XshowSettings%20-Xlog:gc+ref=debug
. This can be useful if you have layers of scripts and have trouble getting proper quoting of command line arguments through.)
To separate multiple keyword=value pairs, use ;
(semicolon). Since the shell normally eats ;
, the recommended usage is to write the assignment inside qoutes, e.g. JTREG="...;..."
. This will also make sure spaces are preserved, as in JTREG="JAVA_OPTIONS=-XshowSettings -Xlog:gc+ref=debug"
.
(Other ways are possible, e.g. using backslash: JTREG=JOBS=1\;TIMEOUT_FACTOR=8
. Also, as a special technique, the string %20
will be replaced with space for certain options, e.g. JTREG=JAVA_OPTIONS=-XshowSettings%20-Xlog:gc+ref=debug
. This can be useful if you have layers of scripts and have trouble getting proper quoting of command line arguments through.)
As far as possible, the names of the keywords have been standardized between test suites.
Some keywords are valid across different test suites. If you want to run tests from multiple test suites, or just don't want to care which test suite specific control variable to use, then you can use the general TEST_OPTS control variable.
@@ -116,16 +116,16 @@Currently only applies to JTReg.
Currently only applies to JTReg.
-Applies to JTReg, GTest and Micro.
Applies to JTReg, GTest and Micro.
+Applies to JTReg, GTest and Micro.
Applies to JTReg and GTest.
This keywords applies globally to the test runner system. If set to true
, it enables JCov coverage reporting for all tests run. To be useful, the JDK under test must be run with a JDK built with JCov instrumentation (configure --with-jcov=<path to directory containing lib/jcov.jar>
, make jcov-image
).
The simplest way to run tests with JCov coverage report is to use the special target jcov-test
instead of test
, e.g. make jcov-test TEST=jdk_lang
. This will make sure the JCov image is built, and that JCov reporting is enabled.
The JCov report is stored in build/$BUILD/test-results/jcov-output
.
The JCov report is stored in build/$BUILD/test-results/jcov-output/report
.
Please note that running with JCov reporting can be very memory intensive.
While collecting code coverage with JCov, it is also possible to find coverage for only recently changed code. JCOV_DIFF_CHANGESET specifies a source revision. A textual report will be generated showing coverage of the diff between the specified revision and the repository tip.
@@ -166,9 +166,10 @@Additional options to the JTReg test framework.
Use JTREG="OPTIONS=--help all"
to see all available JTReg options.
Additional Java options to JTReg (-javaoption
).
Additional Java options for running test classes (sent to JTReg as -javaoption
).
Additional VM options to JTReg (-vmoption
).
Additional Java options to be used when compiling and running classes (sent to JTReg as -vmoption
).
This option is only needed in special circumstances. To pass Java options to your test classes, use JAVA_OPTIONS
.
Generate AOT modules before testing for the specified module, or set of modules. If multiple modules are specified, they should be separated by space (or, to help avoid quoting issues, the special value %20
).
For example, for dynamically-computed call site, a the first argument + *
For example, for dynamically-computed call site, the first argument
* could be {@code Object} instead of {@code MethodHandles.Lookup}, and the return type
* could also be {@code Object} instead of {@code CallSite}.
* (Note that the types and number of the stacked arguments limit
diff --git a/src/java.base/share/classes/java/text/CompactNumberFormat.java b/src/java.base/share/classes/java/text/CompactNumberFormat.java
index a55f097a8a7..e9f1c0bd909 100644
--- a/src/java.base/share/classes/java/text/CompactNumberFormat.java
+++ b/src/java.base/share/classes/java/text/CompactNumberFormat.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, 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
@@ -206,7 +206,7 @@
* {@link java.math.RoundingMode} for formatting. By default, it uses
* {@link java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}.
*
- * @see CompactNumberFormat.Style
+ * @see NumberFormat.Style
* @see NumberFormat
* @see DecimalFormat
* @since 12
diff --git a/src/java.base/share/classes/java/util/zip/ZipCoder.java b/src/java.base/share/classes/java/util/zip/ZipCoder.java
index 204f786c4b5..2e74d0f062e 100644
--- a/src/java.base/share/classes/java/util/zip/ZipCoder.java
+++ b/src/java.base/share/classes/java/util/zip/ZipCoder.java
@@ -32,6 +32,7 @@
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.CodingErrorAction;
+import java.util.Arrays;
import sun.nio.cs.UTF_8;
@@ -43,51 +44,13 @@
private static final jdk.internal.access.JavaLangAccess JLA =
jdk.internal.access.SharedSecrets.getJavaLangAccess();
- static final class UTF8ZipCoder extends ZipCoder {
-
- // Encoding/decoding is stateless, so make it singleton.
- static final ZipCoder INSTANCE = new UTF8ZipCoder(UTF_8.INSTANCE);
-
- private UTF8ZipCoder(Charset utf8) {
- super(utf8);
- }
-
- @Override
- boolean isUTF8() {
- return true;
- }
-
- @Override
- String toString(byte[] ba, int off, int length) {
- return JLA.newStringUTF8NoRepl(ba, off, length);
- }
-
- @Override
- byte[] getBytes(String s) {
- return JLA.getBytesUTF8NoRepl(s);
- }
-
- @Override
- int hashN(byte[] a, int off, int len) {
- // Performance optimization: when UTF8-encoded, ZipFile.getEntryPos
- // assume that the hash of a name remains unchanged when appending a
- // trailing '/', which allows lookups to avoid rehashing
- int end = off + len;
- if (len > 0 && a[end - 1] == '/') {
- end--;
- }
-
- int h = 1;
- for (int i = off; i < end; i++) {
- h = 31 * h + a[i];
- }
- return h;
- }
- }
+ // Encoding/decoding is stateless, so make it singleton.
+ static final UTF8ZipCoder UTF8 = new UTF8ZipCoder(UTF_8.INSTANCE);
public static ZipCoder get(Charset charset) {
- if (charset == UTF_8.INSTANCE)
- return UTF8ZipCoder.INSTANCE;
+ if (charset == UTF_8.INSTANCE) {
+ return UTF8;
+ }
return new ZipCoder(charset);
}
@@ -123,40 +86,74 @@ String toString(byte[] ba) {
}
}
- // assume invoked only if "this" is not utf8
- byte[] getBytesUTF8(String s) {
- return UTF8ZipCoder.INSTANCE.getBytes(s);
+ String toStringUTF8(byte[] ba, int len) {
+ return UTF8.toString(ba, 0, len);
}
- String toStringUTF8(byte[] ba, int len) {
- return UTF8ZipCoder.INSTANCE.toString(ba, 0, len);
+ boolean isUTF8() {
+ return false;
+ }
+
+ // Hash code functions for ZipFile entry names. We generate the hash as-if
+ // we first decoded the byte sequence to a String, then appended '/' if no
+ // trailing slash was found, then called String.hashCode(). This
+ // normalization ensures we can simplify and speed up lookups.
+ int normalizedHash(byte[] a, int off, int len) {
+ if (len == 0) {
+ return 0;
+ }
+ return normalizedHashDecode(0, a, off, off + len);
}
- String toStringUTF8(byte[] ba, int off, int len) {
- return UTF8ZipCoder.INSTANCE.toString(ba, off, len);
+ // Matching normalized hash code function for Strings
+ static int normalizedHash(String name) {
+ int hsh = name.hashCode();
+ int len = name.length();
+ if (len > 0 && name.charAt(len - 1) != '/') {
+ hsh = hsh * 31 + '/';
+ }
+ return hsh;
}
- boolean isUTF8() {
- return false;
+ boolean hasTrailingSlash(byte[] a, int end) {
+ byte[] slashBytes = slashBytes();
+ return end >= slashBytes.length &&
+ Arrays.mismatch(a, end - slashBytes.length, end, slashBytes, 0, slashBytes.length) == -1;
}
- int hashN(byte[] a, int off, int len) {
- int h = 1;
- while (len-- > 0) {
- h = 31 * h + a[off++];
+ // Implements normalizedHash by decoding byte[] to char[] and then computing
+ // the hash. This is a slow-path used for non-UTF8 charsets and also when
+ // aborting the ASCII fast-path in the UTF8 implementation, so {@code h}
+ // might be a partially calculated hash code
+ int normalizedHashDecode(int h, byte[] a, int off, int end) {
+ try {
+ // cb will be a newly allocated CharBuffer with pos == 0,
+ // arrayOffset == 0, backed by an array.
+ CharBuffer cb = decoder().decode(ByteBuffer.wrap(a, off, end - off));
+ int limit = cb.limit();
+ char[] decoded = cb.array();
+ for (int i = 0; i < limit; i++) {
+ h = 31 * h + decoded[i];
+ }
+ if (limit > 0 && decoded[limit - 1] != '/') {
+ h = 31 * h + '/';
+ }
+ } catch (CharacterCodingException cce) {
+ // Ignore - return the hash code generated so far.
}
return h;
}
- private Charset cs;
- private CharsetDecoder dec;
+ private byte[] slashBytes;
+ private final Charset cs;
+ protected CharsetDecoder dec;
private CharsetEncoder enc;
private ZipCoder(Charset cs) {
this.cs = cs;
}
- private CharsetDecoder decoder() {
+ protected CharsetDecoder decoder() {
if (dec == null) {
dec = cs.newDecoder()
.onMalformedInput(CodingErrorAction.REPORT)
@@ -173,4 +170,73 @@ private CharsetEncoder encoder() {
}
return enc;
}
+
+ // This method produces an array with the bytes that will correspond to a
+ // trailing '/' in the chosen character encoding.
+ //
+ // While in most charsets a trailing slash will be encoded as the byte
+ // value of '/', this does not hold in the general case. E.g., in charsets
+ // such as UTF-16 and UTF-32 it will be represented by a sequence of 2 or 4
+ // bytes, respectively.
+ private byte[] slashBytes() {
+ if (slashBytes == null) {
+ // Take into account charsets that produce a BOM, e.g., UTF-16
+ byte[] slash = "/".getBytes(cs);
+ byte[] doubleSlash = "//".getBytes(cs);
+ slashBytes = Arrays.copyOfRange(doubleSlash, slash.length, doubleSlash.length);
+ }
+ return slashBytes;
+ }
+
+ static final class UTF8ZipCoder extends ZipCoder {
+
+ private UTF8ZipCoder(Charset utf8) {
+ super(utf8);
+ }
+
+ @Override
+ boolean isUTF8() {
+ return true;
+ }
+
+ @Override
+ String toString(byte[] ba, int off, int length) {
+ return JLA.newStringUTF8NoRepl(ba, off, length);
+ }
+
+ @Override
+ byte[] getBytes(String s) {
+ return JLA.getBytesUTF8NoRepl(s);
+ }
+
+ @Override
+ int normalizedHash(byte[] a, int off, int len) {
+ if (len == 0) {
+ return 0;
+ }
+
+ int end = off + len;
+ int h = 0;
+ while (off < end) {
+ byte b = a[off];
+ if (b < 0) {
+ // Non-ASCII, fall back to decoder loop
+ return normalizedHashDecode(h, a, off, end);
+ } else {
+ h = 31 * h + b;
+ off++;
+ }
+ }
+
+ if (a[end - 1] != '/') {
+ h = 31 * h + '/';
+ }
+ return h;
+ }
+
+ @Override
+ boolean hasTrailingSlash(byte[] a, int end) {
+ return end > 0 && a[end - 1] == '/';
+ }
+ }
}
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 a15407a1626..bb05e19454d 100644
--- a/src/java.base/share/classes/java/util/zip/ZipFile.java
+++ b/src/java.base/share/classes/java/util/zip/ZipFile.java
@@ -92,7 +92,6 @@
private final String name; // zip file name
private volatile boolean closeRequested;
- private final @Stable ZipCoder zc;
// The "resource" used by this zip file that needs to be
// cleaned after use.
@@ -232,11 +231,10 @@ public ZipFile(File file, int mode, Charset charset) throws IOException
}
Objects.requireNonNull(charset, "charset");
- this.zc = ZipCoder.get(charset);
this.name = name;
long t0 = System.nanoTime();
- this.res = new CleanableResource(this, file, mode);
+ this.res = new CleanableResource(this, ZipCoder.get(charset), file, mode);
PerfCounter.getZipFileOpenTime().addElapsedTimeFrom(t0);
PerfCounter.getZipFileCount().increment();
@@ -307,7 +305,7 @@ public String getComment() {
if (res.zsrc.comment == null) {
return null;
}
- return zc.toString(res.zsrc.comment);
+ return res.zsrc.zc.toString(res.zsrc.comment);
}
}
@@ -338,18 +336,9 @@ private ZipEntry getEntry(String name, Function