diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index d02ef91ad86..9bb43a8b83c 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -63,7 +63,7 @@ env: jobs: build-windows: name: build - runs-on: windows-2019 + runs-on: windows-2025 defaults: run: shell: bash @@ -102,7 +102,7 @@ jobs: id: toolchain-check run: | set +e - '/c/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/vc/auxiliary/build/vcvars64.bat' -vcvars_ver=${{ inputs.msvc-toolset-version }} + '/c/Program Files/Microsoft Visual Studio/2022/Enterprise/vc/auxiliary/build/vcvars64.bat' -vcvars_ver=${{ inputs.msvc-toolset-version }} if [ $? -eq 0 ]; then echo "Toolchain is already installed" echo "toolchain-installed=true" >> $GITHUB_OUTPUT @@ -115,7 +115,7 @@ jobs: run: | # Run Visual Studio Installer '/c/Program Files (x86)/Microsoft Visual Studio/Installer/vs_installer.exe' \ - modify --quiet --installPath 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise' \ + modify --quiet --installPath 'C:\Program Files\Microsoft Visual Studio\2022\Enterprise' \ --add Microsoft.VisualStudio.Component.VC.${{ inputs.msvc-toolset-version }}.${{ inputs.msvc-toolset-architecture }} if: steps.toolchain-check.outputs.toolchain-installed != 'true' diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 6ca64bb82d0..0e64ad78625 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -310,7 +310,7 @@ jobs: uses: ./.github/workflows/build-windows.yml with: platform: windows-x64 - msvc-toolset-version: '14.29' + msvc-toolset-version: '14.43' msvc-toolset-architecture: 'x86.x64' configure-arguments: ${{ github.event.inputs.configure-arguments }} make-arguments: ${{ github.event.inputs.make-arguments }} @@ -322,7 +322,7 @@ jobs: uses: ./.github/workflows/build-windows.yml with: platform: windows-aarch64 - msvc-toolset-version: '14.29' + msvc-toolset-version: '14.43' msvc-toolset-architecture: 'arm64' make-target: 'hotspot' extra-conf-options: '--openjdk-target=aarch64-unknown-cygwin' @@ -393,5 +393,5 @@ jobs: with: platform: windows-x64 bootjdk-platform: windows-x64 - runs-on: windows-2019 + runs-on: windows-2025 debug-suffix: -debug diff --git a/.jcheck/conf b/.jcheck/conf index 6ab5c2d64c2..60881e74d2a 100644 --- a/.jcheck/conf +++ b/.jcheck/conf @@ -1,7 +1,7 @@ [general] project=jdk jbs=JDK -version=25 +version=26 [checks] error=author,committer,reviewers,merge,issues,executable,symlink,message,hg-tag,whitespace,problemlists,copyright diff --git a/doc/starting-next-release.html b/doc/starting-next-release.html new file mode 100644 index 00000000000..421229f9fbc --- /dev/null +++ b/doc/starting-next-release.html @@ -0,0 +1,127 @@ + + +
+ + + +The start of release changes, the changes that turn JDK N
+into JDK (N+1), are primarily small updates to various files
+along with new files to store symbol information to allow
+javac --release N ...
to run on JDK (N+1).
The updates include changes to files holding meta-data about the
+release, files under the src
directory for API and tooling
+updates, and incidental updates under the test
+directory.
As a matter of policy, there are a number of semantically distinct +concepts which get incremented separately at the start of a new +release:
+Runtime.version()
javax.lang.model.SourceVersion
-source
/-target
/--release
+argument recognized by javac
and related toolsThe expected file updates are listed below. Additional files may need +to be updated for a particular release.
+jcheck/conf
: update meta-data used by
+jcheck
and the Skara toolingmake/conf/version-numbers.conf
: update to meta-data
+used in the buildsrc
filessrc/hotspot/share/classfile/classFileParser.cpp
: add a
+#define
for the new versionsrc/java.base/share/classes/java/lang/classfile/ClassFile.java
:
+add a constant for the new class file format versionsrc/java.base/share/classes/java/lang/reflect/ClassFileFormatVersion.java
:
+add an enum
constant for the new class file format
+versionsrc/java.compiler/share/classes/javax/lang/model/SourceVersion.java
:
+add an enum
constant for the new source versionsrc/java.compiler/share/classes/javax/lang/model/util/*
+visitors: Update @SupportedSourceVersion
annotations to
+latest value. Note this update is done in lieu of introducing another
+set of visitors for each Java SE release.src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java
:
+add an enum
constant for the new source version internal to
+javac
src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassFile.java
:
+add an enum
constant for the new class file format version
+internal to javac
src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Target.java
:
+add an enum
constant for the new target version internal to
+javac
src/jdk.compiler/share/classes/com/sun/tools/javac/processing/PrintingProcessor.java
+update printing processor to support the new source version--release
is stored as new
+text files in the src/jdk.compiler/share/data/symbols
+directory, one file per module. The README file in that directory
+contains directions on how to create the files.test
filestest/langtools/tools/javac/api/TestGetSourceVersions.java
:
+add new SourceVersion
constant to test matrix.test/langtools/tools/javac/classfiles/ClassVersionChecker.java
:
+add new enum constant for the new class file versiontest/langtools/tools/javac/lib/JavacTestingAbstractProcessor.java
+update annotation processor extended by javac
tests to
+cover the new source versiontest/langtools/tools/javac/preview/classReaderTest/Client.nopreview.out
+and
+test/langtools/tools/javac/preview/classReaderTest/Client.preview.out
:
+update expected messages for preview errors and warnings@Artifact
class. (See
JTREG="JAVA_OPTIONS=-Djdk.test.lib.artifacts.nsslib-linux_aarch64=/path/to/NSS-libs"
For more notes about the PKCS11 tests, please refer to test/jdk/sun/security/pkcs11/README.
-One way to improve test coverage of ahead-of-time (AOT) optimizations in the JDK is to run existing jtreg test cases in a special "AOT_JDK" mode. Example:
diff --git a/make/Init.gmk b/make/Init.gmk index 32624d7dee6..38959323628 100644 --- a/make/Init.gmk +++ b/make/Init.gmk @@ -110,7 +110,18 @@ reconfigure: CUSTOM_CONFIG_DIR="$(CUSTOM_CONFIG_DIR)" \ $(RECONFIGURE_COMMAND) ) -.PHONY: print-modules print-targets print-tests print-configuration reconfigure +# Create files that are needed to run most targets in Main.gmk +create-make-helpers: + ( cd $(TOPDIR) && \ + $(MAKE) $(MAKE_ARGS) -j 1 -f make/GenerateFindTests.gmk \ + $(USER_MAKE_VARS) ) + ( cd $(TOPDIR) && \ + $(MAKE) $(MAKE_ARGS) -j 1 -f make/Main.gmk $(USER_MAKE_VARS) \ + UPDATE_MODULE_DEPS=true NO_RECIPES=true \ + create-main-targets-include ) + +.PHONY: print-modules print-targets print-tests print-configuration \ + reconfigure create-make-helpers ############################################################################## # The main target. This will delegate all other targets into Main.gmk. @@ -130,7 +141,7 @@ TARGET_DESCRIPTION := target$(if $(word 2, $(MAIN_TARGETS)),s) \ # variables are explicitly propagated using $(USER_MAKE_VARS). main: MAKEOVERRIDES := -main: $(INIT_TARGETS) +main: $(INIT_TARGETS) create-make-helpers ifneq ($(SEQUENTIAL_TARGETS)$(PARALLEL_TARGETS), ) $(call RotateLogFiles) $(ECHO) "Building $(TARGET_DESCRIPTION)" $(BUILD_LOG_PIPE_SIMPLE) @@ -142,12 +153,7 @@ main: $(INIT_TARGETS) $(SEQUENTIAL_TARGETS) ) # We might have cleaned away essential files, recreate them. ( cd $(TOPDIR) && \ - $(MAKE) $(MAKE_ARGS) -j 1 -f make/GenerateFindTests.gmk \ - $(USER_MAKE_VARS) ) - ( cd $(TOPDIR) && \ - $(MAKE) $(MAKE_ARGS) -j 1 -f make/Main.gmk $(USER_MAKE_VARS) \ - UPDATE_MODULE_DEPS=true NO_RECIPES=true \ - create-main-targets-include ) + $(MAKE) $(MAKE_ARGS) -j 1 -f make/Init.gmk create-make-helpers ) endif ifneq ($(PARALLEL_TARGETS), ) $(call PrepareFailureLogs) diff --git a/make/Main.gmk b/make/Main.gmk index 6a800a2edd5..d0568509a4e 100644 --- a/make/Main.gmk +++ b/make/Main.gmk @@ -417,12 +417,14 @@ $(eval $(call SetupTarget, create-source-revision-tracker, \ )) BOOTCYCLE_TARGET := product-images +BOOTCYCLE_SPEC := $(dir $(SPEC))bootcycle-spec.gmk + bootcycle-images: ifneq ($(COMPILE_TYPE), cross) $(call LogWarn, Boot cycle build step 2: Building a new JDK image using previously built image) $(call MakeDir, $(OUTPUTDIR)/bootcycle-build) +$(MAKE) $(MAKE_ARGS) -f $(TOPDIR)/make/Init.gmk PARALLEL_TARGETS=$(BOOTCYCLE_TARGET) \ - LOG_PREFIX="[bootcycle] " JOBS= SPEC=$(dir $(SPEC))bootcycle-spec.gmk main + LOG_PREFIX="[bootcycle] " JOBS= SPEC=$(BOOTCYCLE_SPEC) main else $(call LogWarn, Boot cycle build disabled when cross compiling) endif diff --git a/make/PreInit.gmk b/make/PreInit.gmk index bce61ccde5f..3df44308dd9 100644 --- a/make/PreInit.gmk +++ b/make/PreInit.gmk @@ -50,7 +50,8 @@ include $(TOPDIR)/make/Global.gmk # Targets provided by Init.gmk. ALL_INIT_TARGETS := print-modules print-targets print-configuration \ - print-tests reconfigure pre-compare-build post-compare-build + print-tests reconfigure pre-compare-build post-compare-build \ + create-make-helpers # CALLED_TARGETS is the list of targets that the user provided, # or "default" if unspecified. diff --git a/make/autoconf/lib-tests.m4 b/make/autoconf/lib-tests.m4 index d2a4fcbb191..9eb5ee5a046 100644 --- a/make/autoconf/lib-tests.m4 +++ b/make/autoconf/lib-tests.m4 @@ -28,7 +28,7 @@ ################################################################################ # Minimum supported versions -JTREG_MINIMUM_VERSION=7.5.1 +JTREG_MINIMUM_VERSION=7.5.2 GTEST_MINIMUM_VERSION=1.14.0 ################################################################################ diff --git a/make/conf/github-actions.conf b/make/conf/github-actions.conf index 27845ffbd7a..d2b6cd23128 100644 --- a/make/conf/github-actions.conf +++ b/make/conf/github-actions.conf @@ -26,7 +26,7 @@ # Versions and download locations for dependencies used by GitHub Actions (GHA) GTEST_VERSION=1.14.0 -JTREG_VERSION=7.5.1+1 +JTREG_VERSION=7.5.2+1 LINUX_X64_BOOT_JDK_EXT=tar.gz LINUX_X64_BOOT_JDK_URL=https://download.java.net/java/GA/jdk24/1f9ff9062db4449d8ca828c504ffae90/36/GPL/openjdk-24_linux-x64_bin.tar.gz diff --git a/make/conf/jib-profiles.js b/make/conf/jib-profiles.js index 9bedc77cc28..d4877604a90 100644 --- a/make/conf/jib-profiles.js +++ b/make/conf/jib-profiles.js @@ -1174,9 +1174,9 @@ var getJibProfilesDependencies = function (input, common) { jtreg: { server: "jpg", product: "jtreg", - version: "7.5.1", + version: "7.5.2", build_number: "1", - file: "bundles/jtreg-7.5.1+1.zip", + file: "bundles/jtreg-7.5.2+1.zip", environment_name: "JT_HOME", environment_path: input.get("jtreg", "home_path") + "/bin", configure_args: "--with-jtreg=" + input.get("jtreg", "home_path"), @@ -1192,8 +1192,8 @@ var getJibProfilesDependencies = function (input, common) { server: "jpg", product: "jcov", version: "3.0", - build_number: "1", - file: "bundles/jcov-3.0+1.zip", + build_number: "3", + file: "bundles/jcov-3.0+3.zip", environment_name: "JCOV_HOME", }, diff --git a/make/conf/version-numbers.conf b/make/conf/version-numbers.conf index ce9e32315a9..38d6e42dff9 100644 --- a/make/conf/version-numbers.conf +++ b/make/conf/version-numbers.conf @@ -26,17 +26,17 @@ # Default version, product, and vendor information to use, # unless overridden by configure -DEFAULT_VERSION_FEATURE=25 +DEFAULT_VERSION_FEATURE=26 DEFAULT_VERSION_INTERIM=0 DEFAULT_VERSION_UPDATE=0 DEFAULT_VERSION_PATCH=0 DEFAULT_VERSION_EXTRA1=0 DEFAULT_VERSION_EXTRA2=0 DEFAULT_VERSION_EXTRA3=0 -DEFAULT_VERSION_DATE=2025-09-16 -DEFAULT_VERSION_CLASSFILE_MAJOR=69 # "`$EXPR $DEFAULT_VERSION_FEATURE + 44`" +DEFAULT_VERSION_DATE=2026-03-17 +DEFAULT_VERSION_CLASSFILE_MAJOR=70 # "`$EXPR $DEFAULT_VERSION_FEATURE + 44`" DEFAULT_VERSION_CLASSFILE_MINOR=0 DEFAULT_VERSION_DOCS_API_SINCE=11 -DEFAULT_ACCEPTABLE_BOOT_VERSIONS="24 25" -DEFAULT_JDK_SOURCE_TARGET_VERSION=25 +DEFAULT_ACCEPTABLE_BOOT_VERSIONS="24 25 26" +DEFAULT_JDK_SOURCE_TARGET_VERSION=26 DEFAULT_PROMOTED_VERSION_PRE=ea diff --git a/make/jdk/src/classes/build/tools/generatecharacter/GenerateCharacter.java b/make/jdk/src/classes/build/tools/generatecharacter/GenerateCharacter.java index 8d6a703f1c9..a2f37db72d9 100644 --- a/make/jdk/src/classes/build/tools/generatecharacter/GenerateCharacter.java +++ b/make/jdk/src/classes/build/tools/generatecharacter/GenerateCharacter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1190,7 +1190,7 @@ OUTER: for (int i = 0; i < n; i += m) { if (Csyntax) result.append(" static "); else - result.append(" static final "); + result.append(" @Stable static final "); result.append(atype); result.append(" ").append(name).append("["); if (Csyntax) @@ -1347,7 +1347,7 @@ OUTER: for (int i = 0; i < n; i += m) { } static void genCaseMapTableDeclaration(StringBuffer result) { - result.append(" static final char[][][] charMap;\n"); + result.append(" @Stable static final char[][][] charMap;\n"); } static void genCaseMapTable(StringBuffer result, SpecialCaseMap[] specialCaseMaps){ diff --git a/make/modules/java.base/Gensrc.gmk b/make/modules/java.base/Gensrc.gmk index 3a482388bec..e4a019ed584 100644 --- a/make/modules/java.base/Gensrc.gmk +++ b/make/modules/java.base/Gensrc.gmk @@ -46,6 +46,8 @@ CLDR_GEN_DONE := $(GENSRC_DIR)/_cldr-gensrc.marker TZ_DATA_DIR := $(MODULE_SRC)/share/data/tzdata ZONENAME_TEMPLATE := $(MODULE_SRC)/share/classes/java/time/format/ZoneName.java.template +# The `-utf8` option is used even for US English, as some names +# may contain non-ASCII characters, such as “Türkiye”. $(CLDR_GEN_DONE): $(wildcard $(CLDR_DATA_DIR)/dtd/*.dtd) \ $(wildcard $(CLDR_DATA_DIR)/main/en*.xml) \ $(wildcard $(CLDR_DATA_DIR)/supplemental/*.xml) \ @@ -61,7 +63,8 @@ $(CLDR_GEN_DONE): $(wildcard $(CLDR_DATA_DIR)/dtd/*.dtd) \ -basemodule \ -year $(COPYRIGHT_YEAR) \ -zntempfile $(ZONENAME_TEMPLATE) \ - -tzdatadir $(TZ_DATA_DIR)) + -tzdatadir $(TZ_DATA_DIR) \ + -utf8) $(TOUCH) $@ TARGETS += $(CLDR_GEN_DONE) diff --git a/make/modules/jdk.localedata/Gensrc.gmk b/make/modules/jdk.localedata/Gensrc.gmk index a3c5cdf82e8..93b863df66f 100644 --- a/make/modules/jdk.localedata/Gensrc.gmk +++ b/make/modules/jdk.localedata/Gensrc.gmk @@ -45,7 +45,8 @@ $(CLDR_GEN_DONE): $(wildcard $(CLDR_DATA_DIR)/dtd/*.dtd) \ -baselocales "en-US" \ -year $(COPYRIGHT_YEAR) \ -o $(GENSRC_DIR) \ - -tzdatadir $(TZ_DATA_DIR)) + -tzdatadir $(TZ_DATA_DIR) \ + -utf8) $(TOUCH) $@ TARGETS += $(CLDR_GEN_DONE) diff --git a/src/demo/share/jfc/Stylepad/HelloWorld.java b/src/demo/share/jfc/Stylepad/HelloWorld.java index c4e7a8aee40..59ea1b45335 100644 --- a/src/demo/share/jfc/Stylepad/HelloWorld.java +++ b/src/demo/share/jfc/Stylepad/HelloWorld.java @@ -187,22 +187,18 @@ public class HelloWorld { new Run("none", "Hello from Cupertino") }), new Paragraph("title", new Run[] { - new Run("none", "\u53F0\u5317\u554F\u5019\u60A8\u0021") + new Run("none", "台北問候您!") }), new Paragraph("title", new Run[] { - new Run("none", "\u0391\u03B8\u03B7\u03BD\u03B1\u03B9\u0020" // Greek - + "\u03B1\u03C3\u03C0\u03B1\u03B6\u03BF\u03BD" - + "\u03C4\u03B1\u03B9\u0020\u03C5\u03BC\u03B1" - + "\u03C2\u0021") + new Run("none", "Αθηναι ασπαζονται υμας!") // Greek }), new Paragraph("title", new Run[] { - new Run("none", "\u6771\u4eac\u304b\u3089\u4eca\u65e5\u306f") + new Run("none", "東京から今日は") }), new Paragraph("title", new Run[] { - new Run("none", "\u05e9\u05dc\u05d5\u05dd \u05de\u05d9\u05e8\u05d5" - + "\u05e9\u05dc\u05d9\u05dd") + new Run("none", "שלום מירושלים") }), new Paragraph("title", new Run[] { - new Run("none", "\u0633\u0644\u0627\u0645") + new Run("none", "سلام") }), }; } diff --git a/src/hotspot/cpu/aarch64/aarch64.ad b/src/hotspot/cpu/aarch64/aarch64.ad index 690210a8c40..75baef153f8 100644 --- a/src/hotspot/cpu/aarch64/aarch64.ad +++ b/src/hotspot/cpu/aarch64/aarch64.ad @@ -3921,6 +3921,10 @@ ins_attrib ins_alignment(4); // Required alignment attribute (must // compute_padding() function must be // provided for the instruction +// Whether this node is expanded during code emission into a sequence of +// instructions and the first instruction can perform an implicit null check. +ins_attrib ins_is_late_expanded_null_check_candidate(false); + //----------OPERANDS----------------------------------------------------------- // Operand definitions must precede instruction definitions for correct parsing // in the ADLC because operands constitute user defined types which are used in @@ -7761,14 +7765,12 @@ instruct popCountI(iRegINoSp dst, iRegIorL2I src, vRegF tmp) %{ effect(TEMP tmp); ins_cost(INSN_COST * 13); - format %{ "movw $src, $src\n\t" - "mov $tmp, $src\t# vector (1D)\n\t" + format %{ "fmovs $tmp, $src\t# vector (1S)\n\t" "cnt $tmp, $tmp\t# vector (8B)\n\t" "addv $tmp, $tmp\t# vector (8B)\n\t" "mov $dst, $tmp\t# vector (1D)" %} ins_encode %{ - __ movw($src$$Register, $src$$Register); // ensure top 32 bits 0 - __ mov($tmp$$FloatRegister, __ D, 0, $src$$Register); + __ fmovs($tmp$$FloatRegister, $src$$Register); __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); __ mov($dst$$Register, $tmp$$FloatRegister, __ D, 0); diff --git a/src/hotspot/cpu/aarch64/gc/z/z_aarch64.ad b/src/hotspot/cpu/aarch64/gc/z/z_aarch64.ad index 47abaae3d5b..78dc5d56bbd 100644 --- a/src/hotspot/cpu/aarch64/gc/z/z_aarch64.ad +++ b/src/hotspot/cpu/aarch64/gc/z/z_aarch64.ad @@ -106,6 +106,13 @@ instruct zLoadP(iRegPNoSp dst, memory8 mem, rFlagsReg cr) match(Set dst (LoadP mem)); predicate(UseZGC && !needs_acquiring_load(n) && n->as_Load()->barrier_data() != 0); effect(TEMP dst, KILL cr); + // The main load is a candidate to implement implicit null checks, as long as + // legitimize_address() does not require a preceding lea instruction to + // materialize the memory operand. The absence of a preceding lea instruction + // is guaranteed for immLoffset8 memory operands, because these do not lead to + // out-of-range offsets (see definition of immLoffset8). Fortunately, + // immLoffset8 memory operands are the most common ones in practice. + ins_is_late_expanded_null_check_candidate(opnd_array(1)->opcode() == INDOFFL8); ins_cost(4 * INSN_COST); @@ -117,7 +124,11 @@ instruct zLoadP(iRegPNoSp dst, memory8 mem, rFlagsReg cr) // Fix up any out-of-range offsets. assert_different_registers(rscratch2, as_Register($mem$$base)); assert_different_registers(rscratch2, $dst$$Register); - ref_addr = __ legitimize_address(ref_addr, 8, rscratch2); + int size = 8; + assert(!this->is_late_expanded_null_check_candidate() || + !MacroAssembler::legitimize_address_requires_lea(ref_addr, size), + "an instruction that can be used for implicit null checking should emit the candidate memory access first"); + ref_addr = __ legitimize_address(ref_addr, size, rscratch2); } __ ldr($dst$$Register, ref_addr); z_load_barrier(masm, this, ref_addr, $dst$$Register, rscratch1); diff --git a/src/hotspot/cpu/aarch64/globals_aarch64.hpp b/src/hotspot/cpu/aarch64/globals_aarch64.hpp index 800e7718921..b316103d656 100644 --- a/src/hotspot/cpu/aarch64/globals_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/globals_aarch64.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2019, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -83,8 +83,6 @@ define_pd_global(intx, InlineSmallCode, 1000); range, \ constraint) \ \ - product(bool, NearCpool, true, \ - "constant pool is close to instructions") \ product(bool, UseCRC32, false, \ "Use CRC32 instructions for CRC32 computation") \ product(bool, UseCryptoPmullForCRC32, false, \ @@ -97,6 +95,8 @@ define_pd_global(intx, InlineSmallCode, 1000); "Use simplest and shortest implementation for array equals") \ product(bool, UseSIMDForBigIntegerShiftIntrinsics, true, \ "Use SIMD instructions for left/right shift of BigInteger") \ + product(bool, UseSIMDForSHA3Intrinsic, true, \ + "Use SIMD SHA3 instructions for SHA3 intrinsic") \ product(bool, AvoidUnalignedAccesses, false, \ "Avoid generating unaligned memory accesses") \ product(bool, UseLSE, false, \ diff --git a/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp b/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp index 48f92d28e03..276fdd013db 100644 --- a/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp @@ -926,60 +926,26 @@ void InterpreterMacroAssembler::set_mdp_data_at(Register mdp_in, void InterpreterMacroAssembler::increment_mdp_data_at(Register mdp_in, - int constant, - bool decrement) { - increment_mdp_data_at(mdp_in, noreg, constant, decrement); + int constant) { + increment_mdp_data_at(mdp_in, noreg, constant); } void InterpreterMacroAssembler::increment_mdp_data_at(Register mdp_in, - Register reg, - int constant, - bool decrement) { + Register index, + int constant) { assert(ProfileInterpreter, "must be profiling interpreter"); - // %%% this does 64bit counters at best it is wasting space - // at worst it is a rare bug when counters overflow - assert_different_registers(rscratch2, rscratch1, mdp_in, reg); + assert_different_registers(rscratch2, rscratch1, mdp_in, index); Address addr1(mdp_in, constant); - Address addr2(rscratch2, reg, Address::lsl(0)); + Address addr2(rscratch2, index, Address::lsl(0)); Address &addr = addr1; - if (reg != noreg) { + if (index != noreg) { lea(rscratch2, addr1); addr = addr2; } - if (decrement) { - // Decrement the register. Set condition codes. - // Intel does this - // addptr(data, (int32_t) -DataLayout::counter_increment); - // If the decrement causes the counter to overflow, stay negative - // Label L; - // jcc(Assembler::negative, L); - // addptr(data, (int32_t) DataLayout::counter_increment); - // so we do this - ldr(rscratch1, addr); - subs(rscratch1, rscratch1, (unsigned)DataLayout::counter_increment); - Label L; - br(Assembler::LO, L); // skip store if counter underflow - str(rscratch1, addr); - bind(L); - } else { - assert(DataLayout::counter_increment == 1, - "flow-free idiom only works with 1"); - // Intel does this - // Increment the register. Set carry flag. - // addptr(data, DataLayout::counter_increment); - // If the increment causes the counter to overflow, pull back by 1. - // sbbptr(data, (int32_t)0); - // so we do this - ldr(rscratch1, addr); - adds(rscratch1, rscratch1, DataLayout::counter_increment); - Label L; - br(Assembler::CS, L); // skip store if counter overflow - str(rscratch1, addr); - bind(L); - } + increment(addr, DataLayout::counter_increment); } void InterpreterMacroAssembler::set_mdp_flag_at(Register mdp_in, diff --git a/src/hotspot/cpu/aarch64/interp_masm_aarch64.hpp b/src/hotspot/cpu/aarch64/interp_masm_aarch64.hpp index 58a7ed03150..447d4f8244e 100644 --- a/src/hotspot/cpu/aarch64/interp_masm_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/interp_masm_aarch64.hpp @@ -247,11 +247,8 @@ class InterpreterMacroAssembler: public MacroAssembler { void verify_method_data_pointer(); void set_mdp_data_at(Register mdp_in, int constant, Register value); - void increment_mdp_data_at(Address data, bool decrement = false); - void increment_mdp_data_at(Register mdp_in, int constant, - bool decrement = false); - void increment_mdp_data_at(Register mdp_in, Register reg, int constant, - bool decrement = false); + void increment_mdp_data_at(Register mdp_in, int constant); + void increment_mdp_data_at(Register mdp_in, Register index, int constant); void increment_mask_and_jump(Address counter_addr, int increment, Address mask, Register scratch, Register scratch2, diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp index 32506c49cfa..f5f0f630c0c 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp @@ -129,16 +129,21 @@ class MacroAssembler: public Assembler { a.lea(this, r); } + // Whether materializing the given address for a LDR/STR requires an + // additional lea instruction. + static bool legitimize_address_requires_lea(const Address &a, int size) { + return a.getMode() == Address::base_plus_offset && + !Address::offset_ok_for_immed(a.offset(), exact_log2(size)); + } + /* Sometimes we get misaligned loads and stores, usually from Unsafe accesses, and these can exceed the offset range. */ Address legitimize_address(const Address &a, int size, Register scratch) { - if (a.getMode() == Address::base_plus_offset) { - if (! Address::offset_ok_for_immed(a.offset(), exact_log2(size))) { - block_comment("legitimize_address {"); - lea(scratch, a); - block_comment("} legitimize_address"); - return Address(scratch); - } + if (legitimize_address_requires_lea(a, size)) { + block_comment("legitimize_address {"); + lea(scratch, a); + block_comment("} legitimize_address"); + return Address(scratch); } return a; } @@ -323,6 +328,27 @@ class MacroAssembler: public Assembler { extr(Rd, Rn, Rn, imm); } + inline void rolw(Register Rd, Register Rn, unsigned imm) { + extrw(Rd, Rn, Rn, (32 - imm)); + } + + inline void rol(Register Rd, Register Rn, unsigned imm) { + extr(Rd, Rn, Rn, (64 - imm)); + } + + using Assembler::rax1; + using Assembler::eor3; + + inline void rax1(Register Rd, Register Rn, Register Rm) { + eor(Rd, Rn, Rm, ROR, 63); // Rd = Rn ^ rol(Rm, 1) + } + + inline void eor3(Register Rd, Register Rn, Register Rm, Register Rk) { + assert(Rd != Rn, "Use tmp register"); + eor(Rd, Rm, Rk); + eor(Rd, Rd, Rn); + } + inline void sxtbw(Register Rd, Register Rn) { sbfmw(Rd, Rn, 0, 7); } diff --git a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp index 1b6f6d489f3..a0d1e22ff96 100644 --- a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp @@ -7081,6 +7081,366 @@ class StubGenerator: public StubCodeGenerator { return start; } + void bcax5(Register a0, Register a1, Register a2, Register a3, Register a4, + Register tmp0, Register tmp1, Register tmp2) { + __ bic(tmp0, a2, a1); // for a0 + __ bic(tmp1, a3, a2); // for a1 + __ bic(tmp2, a4, a3); // for a2 + __ eor(a2, a2, tmp2); + __ bic(tmp2, a0, a4); // for a3 + __ eor(a3, a3, tmp2); + __ bic(tmp2, a1, a0); // for a4 + __ eor(a0, a0, tmp0); + __ eor(a1, a1, tmp1); + __ eor(a4, a4, tmp2); + } + + void keccak_round_gpr(bool can_use_fp, bool can_use_r18, Register rc, + Register a0, Register a1, Register a2, Register a3, Register a4, + Register a5, Register a6, Register a7, Register a8, Register a9, + Register a10, Register a11, Register a12, Register a13, Register a14, + Register a15, Register a16, Register a17, Register a18, Register a19, + Register a20, Register a21, Register a22, Register a23, Register a24, + Register tmp0, Register tmp1, Register tmp2) { + __ eor3(tmp1, a4, a9, a14); + __ eor3(tmp0, tmp1, a19, a24); // tmp0 = a4^a9^a14^a19^a24 = c4 + __ eor3(tmp2, a1, a6, a11); + __ eor3(tmp1, tmp2, a16, a21); // tmp1 = a1^a6^a11^a16^a21 = c1 + __ rax1(tmp2, tmp0, tmp1); // d0 + { + + Register tmp3, tmp4; + if (can_use_fp && can_use_r18) { + tmp3 = rfp; + tmp4 = r18_tls; + } else { + tmp3 = a4; + tmp4 = a9; + __ stp(tmp3, tmp4, __ pre(sp, -16)); + } + + __ eor3(tmp3, a0, a5, a10); + __ eor3(tmp4, tmp3, a15, a20); // tmp4 = a0^a5^a10^a15^a20 = c0 + __ eor(a0, a0, tmp2); + __ eor(a5, a5, tmp2); + __ eor(a10, a10, tmp2); + __ eor(a15, a15, tmp2); + __ eor(a20, a20, tmp2); // d0(tmp2) + __ eor3(tmp3, a2, a7, a12); + __ eor3(tmp2, tmp3, a17, a22); // tmp2 = a2^a7^a12^a17^a22 = c2 + __ rax1(tmp3, tmp4, tmp2); // d1 + __ eor(a1, a1, tmp3); + __ eor(a6, a6, tmp3); + __ eor(a11, a11, tmp3); + __ eor(a16, a16, tmp3); + __ eor(a21, a21, tmp3); // d1(tmp3) + __ rax1(tmp3, tmp2, tmp0); // d3 + __ eor3(tmp2, a3, a8, a13); + __ eor3(tmp0, tmp2, a18, a23); // tmp0 = a3^a8^a13^a18^a23 = c3 + __ eor(a3, a3, tmp3); + __ eor(a8, a8, tmp3); + __ eor(a13, a13, tmp3); + __ eor(a18, a18, tmp3); + __ eor(a23, a23, tmp3); + __ rax1(tmp2, tmp1, tmp0); // d2 + __ eor(a2, a2, tmp2); + __ eor(a7, a7, tmp2); + __ eor(a12, a12, tmp2); + __ rax1(tmp0, tmp0, tmp4); // d4 + if (!can_use_fp || !can_use_r18) { + __ ldp(tmp3, tmp4, __ post(sp, 16)); + } + __ eor(a17, a17, tmp2); + __ eor(a22, a22, tmp2); + __ eor(a4, a4, tmp0); + __ eor(a9, a9, tmp0); + __ eor(a14, a14, tmp0); + __ eor(a19, a19, tmp0); + __ eor(a24, a24, tmp0); + } + + __ rol(tmp0, a10, 3); + __ rol(a10, a1, 1); + __ rol(a1, a6, 44); + __ rol(a6, a9, 20); + __ rol(a9, a22, 61); + __ rol(a22, a14, 39); + __ rol(a14, a20, 18); + __ rol(a20, a2, 62); + __ rol(a2, a12, 43); + __ rol(a12, a13, 25); + __ rol(a13, a19, 8) ; + __ rol(a19, a23, 56); + __ rol(a23, a15, 41); + __ rol(a15, a4, 27); + __ rol(a4, a24, 14); + __ rol(a24, a21, 2); + __ rol(a21, a8, 55); + __ rol(a8, a16, 45); + __ rol(a16, a5, 36); + __ rol(a5, a3, 28); + __ rol(a3, a18, 21); + __ rol(a18, a17, 15); + __ rol(a17, a11, 10); + __ rol(a11, a7, 6); + __ mov(a7, tmp0); + + bcax5(a0, a1, a2, a3, a4, tmp0, tmp1, tmp2); + bcax5(a5, a6, a7, a8, a9, tmp0, tmp1, tmp2); + bcax5(a10, a11, a12, a13, a14, tmp0, tmp1, tmp2); + bcax5(a15, a16, a17, a18, a19, tmp0, tmp1, tmp2); + bcax5(a20, a21, a22, a23, a24, tmp0, tmp1, tmp2); + + __ ldr(tmp1, __ post(rc, 8)); + __ eor(a0, a0, tmp1); + + } + + // Arguments: + // + // Inputs: + // c_rarg0 - byte[] source+offset + // c_rarg1 - byte[] SHA.state + // c_rarg2 - int block_size + // c_rarg3 - int offset + // c_rarg4 - int limit + // + address generate_sha3_implCompress_gpr(StubGenStubId stub_id) { + bool multi_block; + switch (stub_id) { + case sha3_implCompress_id: + multi_block = false; + break; + case sha3_implCompressMB_id: + multi_block = true; + break; + default: + ShouldNotReachHere(); + } + + static const uint64_t round_consts[24] = { + 0x0000000000000001L, 0x0000000000008082L, 0x800000000000808AL, + 0x8000000080008000L, 0x000000000000808BL, 0x0000000080000001L, + 0x8000000080008081L, 0x8000000000008009L, 0x000000000000008AL, + 0x0000000000000088L, 0x0000000080008009L, 0x000000008000000AL, + 0x000000008000808BL, 0x800000000000008BL, 0x8000000000008089L, + 0x8000000000008003L, 0x8000000000008002L, 0x8000000000000080L, + 0x000000000000800AL, 0x800000008000000AL, 0x8000000080008081L, + 0x8000000000008080L, 0x0000000080000001L, 0x8000000080008008L + }; + + __ align(CodeEntryAlignment); + StubCodeMark mark(this, stub_id); + address start = __ pc(); + + Register buf = c_rarg0; + Register state = c_rarg1; + Register block_size = c_rarg2; + Register ofs = c_rarg3; + Register limit = c_rarg4; + + // use r3.r17,r19..r28 to keep a0..a24. + // a0..a24 are respective locals from SHA3.java + Register a0 = r25, + a1 = r26, + a2 = r27, + a3 = r3, + a4 = r4, + a5 = r5, + a6 = r6, + a7 = r7, + a8 = rscratch1, // r8 + a9 = rscratch2, // r9 + a10 = r10, + a11 = r11, + a12 = r12, + a13 = r13, + a14 = r14, + a15 = r15, + a16 = r16, + a17 = r17, + a18 = r28, + a19 = r19, + a20 = r20, + a21 = r21, + a22 = r22, + a23 = r23, + a24 = r24; + + Register tmp0 = block_size, tmp1 = buf, tmp2 = state, tmp3 = r30; + + Label sha3_loop, rounds24_preloop, loop_body; + Label sha3_512_or_sha3_384, shake128; + + bool can_use_r18 = false; +#ifndef R18_RESERVED + can_use_r18 = true; +#endif + bool can_use_fp = !PreserveFramePointer; + + __ enter(); + + // save almost all yet unsaved gpr registers on stack + __ str(block_size, __ pre(sp, -128)); + if (multi_block) { + __ stpw(ofs, limit, Address(sp, 8)); + } + // 8 bytes at sp+16 will be used to keep buf + __ stp(r19, r20, Address(sp, 32)); + __ stp(r21, r22, Address(sp, 48)); + __ stp(r23, r24, Address(sp, 64)); + __ stp(r25, r26, Address(sp, 80)); + __ stp(r27, r28, Address(sp, 96)); + if (can_use_r18 && can_use_fp) { + __ stp(r18_tls, state, Address(sp, 112)); + } else { + __ str(state, Address(sp, 112)); + } + + // begin sha3 calculations: loading a0..a24 from state arrary + __ ldp(a0, a1, state); + __ ldp(a2, a3, Address(state, 16)); + __ ldp(a4, a5, Address(state, 32)); + __ ldp(a6, a7, Address(state, 48)); + __ ldp(a8, a9, Address(state, 64)); + __ ldp(a10, a11, Address(state, 80)); + __ ldp(a12, a13, Address(state, 96)); + __ ldp(a14, a15, Address(state, 112)); + __ ldp(a16, a17, Address(state, 128)); + __ ldp(a18, a19, Address(state, 144)); + __ ldp(a20, a21, Address(state, 160)); + __ ldp(a22, a23, Address(state, 176)); + __ ldr(a24, Address(state, 192)); + + __ BIND(sha3_loop); + + // load input + __ ldp(tmp3, tmp2, __ post(buf, 16)); + __ eor(a0, a0, tmp3); + __ eor(a1, a1, tmp2); + __ ldp(tmp3, tmp2, __ post(buf, 16)); + __ eor(a2, a2, tmp3); + __ eor(a3, a3, tmp2); + __ ldp(tmp3, tmp2, __ post(buf, 16)); + __ eor(a4, a4, tmp3); + __ eor(a5, a5, tmp2); + __ ldr(tmp3, __ post(buf, 8)); + __ eor(a6, a6, tmp3); + + // block_size == 72, SHA3-512; block_size == 104, SHA3-384 + __ tbz(block_size, 7, sha3_512_or_sha3_384); + + __ ldp(tmp3, tmp2, __ post(buf, 16)); + __ eor(a7, a7, tmp3); + __ eor(a8, a8, tmp2); + __ ldp(tmp3, tmp2, __ post(buf, 16)); + __ eor(a9, a9, tmp3); + __ eor(a10, a10, tmp2); + __ ldp(tmp3, tmp2, __ post(buf, 16)); + __ eor(a11, a11, tmp3); + __ eor(a12, a12, tmp2); + __ ldp(tmp3, tmp2, __ post(buf, 16)); + __ eor(a13, a13, tmp3); + __ eor(a14, a14, tmp2); + __ ldp(tmp3, tmp2, __ post(buf, 16)); + __ eor(a15, a15, tmp3); + __ eor(a16, a16, tmp2); + + // block_size == 136, bit4 == 0 and bit5 == 0, SHA3-256 or SHAKE256 + __ andw(tmp2, block_size, 48); + __ cbzw(tmp2, rounds24_preloop); + __ tbnz(block_size, 5, shake128); + // block_size == 144, bit5 == 0, SHA3-244 + __ ldr(tmp3, __ post(buf, 8)); + __ eor(a17, a17, tmp3); + __ b(rounds24_preloop); + + __ BIND(shake128); + __ ldp(tmp3, tmp2, __ post(buf, 16)); + __ eor(a17, a17, tmp3); + __ eor(a18, a18, tmp2); + __ ldp(tmp3, tmp2, __ post(buf, 16)); + __ eor(a19, a19, tmp3); + __ eor(a20, a20, tmp2); + __ b(rounds24_preloop); // block_size == 168, SHAKE128 + + __ BIND(sha3_512_or_sha3_384); + __ ldp(tmp3, tmp2, __ post(buf, 16)); + __ eor(a7, a7, tmp3); + __ eor(a8, a8, tmp2); + __ tbz(block_size, 5, rounds24_preloop); // SHA3-512 + + // SHA3-384 + __ ldp(tmp3, tmp2, __ post(buf, 16)); + __ eor(a9, a9, tmp3); + __ eor(a10, a10, tmp2); + __ ldp(tmp3, tmp2, __ post(buf, 16)); + __ eor(a11, a11, tmp3); + __ eor(a12, a12, tmp2); + + __ BIND(rounds24_preloop); + __ fmovs(v0, 24.0); // float loop counter, + __ fmovs(v1, 1.0); // exact representation + + __ str(buf, Address(sp, 16)); + __ lea(tmp3, ExternalAddress((address) round_consts)); + + __ BIND(loop_body); + keccak_round_gpr(can_use_fp, can_use_r18, tmp3, + a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, + a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, + tmp0, tmp1, tmp2); + __ fsubs(v0, v0, v1); + __ fcmps(v0, 0.0); + __ br(__ NE, loop_body); + + if (multi_block) { + __ ldrw(block_size, sp); // block_size + __ ldpw(tmp2, tmp1, Address(sp, 8)); // offset, limit + __ addw(tmp2, tmp2, block_size); + __ cmpw(tmp2, tmp1); + __ strw(tmp2, Address(sp, 8)); // store offset in case we're jumping + __ ldr(buf, Address(sp, 16)); // restore buf in case we're jumping + __ br(Assembler::LE, sha3_loop); + __ movw(c_rarg0, tmp2); // return offset + } + if (can_use_fp && can_use_r18) { + __ ldp(r18_tls, state, Address(sp, 112)); + } else { + __ ldr(state, Address(sp, 112)); + } + // save calculated sha3 state + __ stp(a0, a1, Address(state)); + __ stp(a2, a3, Address(state, 16)); + __ stp(a4, a5, Address(state, 32)); + __ stp(a6, a7, Address(state, 48)); + __ stp(a8, a9, Address(state, 64)); + __ stp(a10, a11, Address(state, 80)); + __ stp(a12, a13, Address(state, 96)); + __ stp(a14, a15, Address(state, 112)); + __ stp(a16, a17, Address(state, 128)); + __ stp(a18, a19, Address(state, 144)); + __ stp(a20, a21, Address(state, 160)); + __ stp(a22, a23, Address(state, 176)); + __ str(a24, Address(state, 192)); + + // restore required registers from stack + __ ldp(r19, r20, Address(sp, 32)); + __ ldp(r21, r22, Address(sp, 48)); + __ ldp(r23, r24, Address(sp, 64)); + __ ldp(r25, r26, Address(sp, 80)); + __ ldp(r27, r28, Address(sp, 96)); + if (can_use_fp && can_use_r18) { + __ add(rfp, sp, 128); // leave() will copy rfp to sp below + } // else no need to recalculate rfp, since it wasn't changed + + __ leave(); + + __ ret(lr); + + return start; + } + /** * Arguments: * @@ -11512,9 +11872,15 @@ class StubGenerator: public StubCodeGenerator { StubRoutines::_sha512_implCompressMB = generate_sha512_implCompress(StubGenStubId::sha512_implCompressMB_id); } if (UseSHA3Intrinsics) { - StubRoutines::_sha3_implCompress = generate_sha3_implCompress(StubGenStubId::sha3_implCompress_id); + StubRoutines::_double_keccak = generate_double_keccak(); - StubRoutines::_sha3_implCompressMB = generate_sha3_implCompress(StubGenStubId::sha3_implCompressMB_id); + if (UseSIMDForSHA3Intrinsic) { + StubRoutines::_sha3_implCompress = generate_sha3_implCompress(StubGenStubId::sha3_implCompress_id); + StubRoutines::_sha3_implCompressMB = generate_sha3_implCompress(StubGenStubId::sha3_implCompressMB_id); + } else { + StubRoutines::_sha3_implCompress = generate_sha3_implCompress_gpr(StubGenStubId::sha3_implCompress_id); + StubRoutines::_sha3_implCompressMB = generate_sha3_implCompress_gpr(StubGenStubId::sha3_implCompressMB_id); + } } if (UsePoly1305Intrinsics) { diff --git a/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp index af41ab3ef69..710970d1ea2 100644 --- a/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp @@ -865,6 +865,10 @@ void TemplateInterpreterGenerator::lock_method() { // rcpool: cp cache // stack_pointer: previous sp void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) { + // Save ConstMethod* in r5_const_method for later use to avoid loading multiple times + Register r5_const_method = r5; + __ ldr(r5_const_method, Address(rmethod, Method::const_offset())); + // initialize fixed part of activation frame if (native_call) { __ sub(esp, sp, 14 * wordSize); @@ -875,8 +879,7 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) { __ stp(zr, zr, Address(sp, 12 * wordSize)); } else { __ sub(esp, sp, 12 * wordSize); - __ ldr(rscratch1, Address(rmethod, Method::const_offset())); // get ConstMethod - __ add(rbcp, rscratch1, in_bytes(ConstMethod::codes_offset())); // get codebase + __ add(rbcp, r5_const_method, in_bytes(ConstMethod::codes_offset())); // get codebase __ mov(rscratch1, frame::interpreter_frame_initial_sp_offset); __ stp(rscratch1, rbcp, Address(__ pre(sp, -12 * wordSize))); } @@ -896,9 +899,10 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) { __ stp(rfp, lr, Address(sp, 10 * wordSize)); __ lea(rfp, Address(sp, 10 * wordSize)); - __ ldr(rcpool, Address(rmethod, Method::const_offset())); - __ ldr(rcpool, Address(rcpool, ConstMethod::constants_offset())); - __ ldr(rcpool, Address(rcpool, ConstantPool::cache_offset())); + // Save ConstantPool* in r11_constants for later use to avoid loading multiple times + Register r11_constants = r11; + __ ldr(r11_constants, Address(r5_const_method, ConstMethod::constants_offset())); + __ ldr(rcpool, Address(r11_constants, ConstantPool::cache_offset())); __ sub(rscratch1, rlocals, rfp); __ lsr(rscratch1, rscratch1, Interpreter::logStackElementSize); // rscratch1 = rlocals - fp(); // Store relativized rlocals, see frame::interpreter_frame_locals(). @@ -908,11 +912,12 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) { // leave last_sp as null __ stp(zr, r19_sender_sp, Address(sp, 8 * wordSize)); - // Get mirror - __ load_mirror(r10, rmethod, r5, rscratch2); + // Get mirror. Resolve ConstantPool* -> InstanceKlass* -> Java mirror. + __ ldr(r10, Address(r11_constants, ConstantPool::pool_holder_offset())); + __ ldr(r10, Address(r10, in_bytes(Klass::java_mirror_offset()))); + __ resolve_oop_handle(r10, rscratch1, rscratch2); if (! native_call) { - __ ldr(rscratch1, Address(rmethod, Method::const_offset())); - __ ldrh(rscratch1, Address(rscratch1, ConstMethod::max_stack_offset())); + __ ldrh(rscratch1, Address(r5_const_method, ConstMethod::max_stack_offset())); __ add(rscratch1, rscratch1, MAX2(3, Method::extra_stack_entries())); __ sub(rscratch1, sp, rscratch1, ext::uxtw, 3); __ andr(rscratch1, rscratch1, -16); @@ -1888,6 +1893,7 @@ void TemplateInterpreterGenerator::generate_throw_exception() { Interpreter::_remove_activation_preserving_args_entry = __ pc(); __ empty_expression_stack(); + __ restore_bcp(); // We could have returned from deoptimizing this frame, so restore rbcp. // Set the popframe_processing bit in pending_popframe_condition // indicating that we are currently handling popframe, so that // call_VMs that may happen later do not trigger new popframe diff --git a/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp b/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp index 4c1e4ce3a05..fcfe153a9a5 100644 --- a/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp @@ -1144,6 +1144,7 @@ void TemplateTable::aastore() { // Get the value we will store __ ldr(r0, at_tos()); // Now store using the appropriate barrier + // Clobbers: r10, r11, r3 do_oop_store(_masm, element_address, r0, IS_ARRAY); __ b(done); @@ -1152,6 +1153,7 @@ void TemplateTable::aastore() { __ profile_null_seen(r2); // Store a null + // Clobbers: r10, r11, r3 do_oop_store(_masm, element_address, noreg, IS_ARRAY); // Pop stack arguments @@ -2882,6 +2884,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteContr __ pop(atos); if (!is_static) pop_and_check_object(obj); // Store into the field + // Clobbers: r10, r11, r3 do_oop_store(_masm, field, r0, IN_HEAP); if (rc == may_rewrite) { patch_bytecode(Bytecodes::_fast_aputfield, bc, r1, true, byte_no); @@ -3077,12 +3080,12 @@ void TemplateTable::fast_storefield(TosState state) // access constant pool cache __ load_field_entry(r2, r1); - // R1: field offset, R2: field holder, R3: flags - load_resolved_field_entry(r2, r2, noreg, r1, r3); + // R1: field offset, R2: field holder, R5: flags + load_resolved_field_entry(r2, r2, noreg, r1, r5); { Label notVolatile; - __ tbz(r3, ResolvedFieldEntry::is_volatile_shift, notVolatile); + __ tbz(r5, ResolvedFieldEntry::is_volatile_shift, notVolatile); __ membar(MacroAssembler::StoreStore | MacroAssembler::LoadStore); __ bind(notVolatile); } @@ -3098,6 +3101,7 @@ void TemplateTable::fast_storefield(TosState state) // access field switch (bytecode()) { case Bytecodes::_fast_aputfield: + // Clobbers: r10, r11, r3 do_oop_store(_masm, field, r0, IN_HEAP); break; case Bytecodes::_fast_lputfield: @@ -3130,7 +3134,7 @@ void TemplateTable::fast_storefield(TosState state) { Label notVolatile; - __ tbz(r3, ResolvedFieldEntry::is_volatile_shift, notVolatile); + __ tbz(r5, ResolvedFieldEntry::is_volatile_shift, notVolatile); __ membar(MacroAssembler::StoreLoad | MacroAssembler::StoreStore); __ bind(notVolatile); } diff --git a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp index 6ed7a6be585..941cb254532 100644 --- a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp @@ -379,7 +379,7 @@ void VM_Version::initialize() { FLAG_SET_DEFAULT(UseSHA3Intrinsics, true); } } - } else if (UseSHA3Intrinsics) { + } else if (UseSHA3Intrinsics && UseSIMDForSHA3Intrinsic) { warning("Intrinsics for SHA3-224, SHA3-256, SHA3-384 and SHA3-512 crypto hash functions not available on this CPU."); FLAG_SET_DEFAULT(UseSHA3Intrinsics, false); } diff --git a/src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp b/src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp index 30d88a4db91..db4a5c8625c 100644 --- a/src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp +++ b/src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp @@ -175,6 +175,7 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M case Interpreter::java_lang_math_fmaD: case Interpreter::java_lang_math_fmaF: case Interpreter::java_lang_math_tanh: + case Interpreter::java_lang_math_cbrt: // TODO: Implement intrinsic break; default: diff --git a/src/hotspot/cpu/ppc/assembler_ppc.hpp b/src/hotspot/cpu/ppc/assembler_ppc.hpp index 491bd107819..314517fd56a 100644 --- a/src/hotspot/cpu/ppc/assembler_ppc.hpp +++ b/src/hotspot/cpu/ppc/assembler_ppc.hpp @@ -591,6 +591,10 @@ class Assembler : public AbstractAssembler { XVRDPIC_OPCODE = (60u << OPCODE_SHIFT | 235u << 2), XVRDPIM_OPCODE = (60u << OPCODE_SHIFT | 249u << 2), XVRDPIP_OPCODE = (60u << OPCODE_SHIFT | 233u << 2), + XVMINSP_OPCODE = (60u << OPCODE_SHIFT | 200u << 3), + XVMINDP_OPCODE = (60u << OPCODE_SHIFT | 232u << 3), + XVMAXSP_OPCODE = (60u << OPCODE_SHIFT | 192u << 3), + XVMAXDP_OPCODE = (60u << OPCODE_SHIFT | 224u << 3), // Deliver A Random Number (introduced with POWER9) DARN_OPCODE = (31u << OPCODE_SHIFT | 755u << 1), @@ -699,15 +703,19 @@ class Assembler : public AbstractAssembler { VMAXSB_OPCODE = (4u << OPCODE_SHIFT | 258u ), VMAXSW_OPCODE = (4u << OPCODE_SHIFT | 386u ), VMAXSH_OPCODE = (4u << OPCODE_SHIFT | 322u ), + VMAXSD_OPCODE = (4u << OPCODE_SHIFT | 450u ), VMAXUB_OPCODE = (4u << OPCODE_SHIFT | 2u ), VMAXUW_OPCODE = (4u << OPCODE_SHIFT | 130u ), VMAXUH_OPCODE = (4u << OPCODE_SHIFT | 66u ), + VMAXUD_OPCODE = (4u << OPCODE_SHIFT | 194u ), VMINSB_OPCODE = (4u << OPCODE_SHIFT | 770u ), VMINSW_OPCODE = (4u << OPCODE_SHIFT | 898u ), VMINSH_OPCODE = (4u << OPCODE_SHIFT | 834u ), + VMINSD_OPCODE = (4u << OPCODE_SHIFT | 962u ), VMINUB_OPCODE = (4u << OPCODE_SHIFT | 514u ), VMINUW_OPCODE = (4u << OPCODE_SHIFT | 642u ), VMINUH_OPCODE = (4u << OPCODE_SHIFT | 578u ), + VMINUD_OPCODE = (4u << OPCODE_SHIFT | 706u ), VCMPEQUB_OPCODE= (4u << OPCODE_SHIFT | 6u ), VCMPEQUH_OPCODE= (4u << OPCODE_SHIFT | 70u ), @@ -2302,15 +2310,19 @@ class Assembler : public AbstractAssembler { inline void vmaxsb( VectorRegister d, VectorRegister a, VectorRegister b); inline void vmaxsw( VectorRegister d, VectorRegister a, VectorRegister b); inline void vmaxsh( VectorRegister d, VectorRegister a, VectorRegister b); + inline void vmaxsd( VectorRegister d, VectorRegister a, VectorRegister b); inline void vmaxub( VectorRegister d, VectorRegister a, VectorRegister b); inline void vmaxuw( VectorRegister d, VectorRegister a, VectorRegister b); inline void vmaxuh( VectorRegister d, VectorRegister a, VectorRegister b); + inline void vmaxud( VectorRegister d, VectorRegister a, VectorRegister b); inline void vminsb( VectorRegister d, VectorRegister a, VectorRegister b); inline void vminsw( VectorRegister d, VectorRegister a, VectorRegister b); inline void vminsh( VectorRegister d, VectorRegister a, VectorRegister b); + inline void vminsd( VectorRegister d, VectorRegister a, VectorRegister b); inline void vminub( VectorRegister d, VectorRegister a, VectorRegister b); inline void vminuw( VectorRegister d, VectorRegister a, VectorRegister b); inline void vminuh( VectorRegister d, VectorRegister a, VectorRegister b); + inline void vminud( VectorRegister d, VectorRegister a, VectorRegister b); inline void vcmpequb( VectorRegister d, VectorRegister a, VectorRegister b); inline void vcmpequh( VectorRegister d, VectorRegister a, VectorRegister b); inline void vcmpequw( VectorRegister d, VectorRegister a, VectorRegister b); @@ -2435,6 +2447,12 @@ class Assembler : public AbstractAssembler { inline void xvrdpim( VectorSRegister d, VectorSRegister b); inline void xvrdpip( VectorSRegister d, VectorSRegister b); + // The following functions do not match exactly the Java.math semantics. + inline void xvminsp( VectorSRegister d, VectorSRegister a, VectorSRegister b); + inline void xvmindp( VectorSRegister d, VectorSRegister a, VectorSRegister b); + inline void xvmaxsp( VectorSRegister d, VectorSRegister a, VectorSRegister b); + inline void xvmaxdp( VectorSRegister d, VectorSRegister a, VectorSRegister b); + // VSX Extended Mnemonics inline void xxspltd( VectorSRegister d, VectorSRegister a, int x); inline void xxmrghd( VectorSRegister d, VectorSRegister a, VectorSRegister b); diff --git a/src/hotspot/cpu/ppc/assembler_ppc.inline.hpp b/src/hotspot/cpu/ppc/assembler_ppc.inline.hpp index 176994cf92c..792e5d6d5ad 100644 --- a/src/hotspot/cpu/ppc/assembler_ppc.inline.hpp +++ b/src/hotspot/cpu/ppc/assembler_ppc.inline.hpp @@ -908,6 +908,11 @@ inline void Assembler::xvrdpic( VectorSRegister d, VectorSRegister b) inline void Assembler::xvrdpim( VectorSRegister d, VectorSRegister b) { emit_int32( XVRDPIM_OPCODE | vsrt(d) | vsrb(b)); } inline void Assembler::xvrdpip( VectorSRegister d, VectorSRegister b) { emit_int32( XVRDPIP_OPCODE | vsrt(d) | vsrb(b)); } +inline void Assembler::xvminsp(VectorSRegister d, VectorSRegister a, VectorSRegister b) { emit_int32( XVMINSP_OPCODE | vsrt(d) | vsra(a) | vsrb(b)); } +inline void Assembler::xvmindp(VectorSRegister d, VectorSRegister a, VectorSRegister b) { emit_int32( XVMINDP_OPCODE | vsrt(d) | vsra(a) | vsrb(b)); } +inline void Assembler::xvmaxsp(VectorSRegister d, VectorSRegister a, VectorSRegister b) { emit_int32( XVMAXSP_OPCODE | vsrt(d) | vsra(a) | vsrb(b)); } +inline void Assembler::xvmaxdp(VectorSRegister d, VectorSRegister a, VectorSRegister b) { emit_int32( XVMAXDP_OPCODE | vsrt(d) | vsra(a) | vsrb(b)); } + inline void Assembler::mtvrd( VectorRegister d, Register a) { emit_int32( MTVSRD_OPCODE | vsrt(d->to_vsr()) | ra(a)); } inline void Assembler::mfvrd( Register a, VectorRegister d) { emit_int32( MFVSRD_OPCODE | vsrt(d->to_vsr()) | ra(a)); } inline void Assembler::mtvrwz( VectorRegister d, Register a) { emit_int32( MTVSRWZ_OPCODE | vsrt(d->to_vsr()) | ra(a)); } @@ -1022,15 +1027,19 @@ inline void Assembler::vavguh( VectorRegister d, VectorRegister a, VectorRegist inline void Assembler::vmaxsb( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VMAXSB_OPCODE | vrt(d) | vra(a) | vrb(b)); } inline void Assembler::vmaxsw( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VMAXSW_OPCODE | vrt(d) | vra(a) | vrb(b)); } inline void Assembler::vmaxsh( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VMAXSH_OPCODE | vrt(d) | vra(a) | vrb(b)); } +inline void Assembler::vmaxsd( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VMAXSD_OPCODE | vrt(d) | vra(a) | vrb(b)); } inline void Assembler::vmaxub( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VMAXUB_OPCODE | vrt(d) | vra(a) | vrb(b)); } inline void Assembler::vmaxuw( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VMAXUW_OPCODE | vrt(d) | vra(a) | vrb(b)); } inline void Assembler::vmaxuh( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VMAXUH_OPCODE | vrt(d) | vra(a) | vrb(b)); } +inline void Assembler::vmaxud( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VMAXUD_OPCODE | vrt(d) | vra(a) | vrb(b)); } inline void Assembler::vminsb( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VMINSB_OPCODE | vrt(d) | vra(a) | vrb(b)); } inline void Assembler::vminsw( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VMINSW_OPCODE | vrt(d) | vra(a) | vrb(b)); } inline void Assembler::vminsh( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VMINSH_OPCODE | vrt(d) | vra(a) | vrb(b)); } +inline void Assembler::vminsd( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VMINSD_OPCODE | vrt(d) | vra(a) | vrb(b)); } inline void Assembler::vminub( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VMINUB_OPCODE | vrt(d) | vra(a) | vrb(b)); } inline void Assembler::vminuw( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VMINUW_OPCODE | vrt(d) | vra(a) | vrb(b)); } inline void Assembler::vminuh( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VMINUH_OPCODE | vrt(d) | vra(a) | vrb(b)); } +inline void Assembler::vminud( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VMINUD_OPCODE | vrt(d) | vra(a) | vrb(b)); } inline void Assembler::vcmpequb(VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VCMPEQUB_OPCODE | vrt(d) | vra(a) | vrb(b) | vcmp_rc(0)); } inline void Assembler::vcmpequh(VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VCMPEQUH_OPCODE | vrt(d) | vra(a) | vrb(b) | vcmp_rc(0)); } inline void Assembler::vcmpequw(VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VCMPEQUW_OPCODE | vrt(d) | vra(a) | vrb(b) | vcmp_rc(0)); } diff --git a/src/hotspot/cpu/ppc/c2_MacroAssembler_ppc.cpp b/src/hotspot/cpu/ppc/c2_MacroAssembler_ppc.cpp index 5e18be552a9..eab3df03fde 100644 --- a/src/hotspot/cpu/ppc/c2_MacroAssembler_ppc.cpp +++ b/src/hotspot/cpu/ppc/c2_MacroAssembler_ppc.cpp @@ -619,3 +619,48 @@ void C2_MacroAssembler::count_positives(Register src, Register cnt, Register res bind(Ldone); subf(result, src, result); // Result is offset from src. } + +void C2_MacroAssembler::reduceI(int opcode, Register dst, Register iSrc, VectorRegister vSrc, + VectorRegister vTmp1, VectorRegister vTmp2) { + + auto fn_vec_op = [this](int opcode, const VectorRegister &dst, const VectorRegister &a, const VectorRegister &b) { + switch(opcode) { + case Op_AddReductionVI: vadduwm(dst, a, b); break; + case Op_MulReductionVI: vmuluwm(dst, a , b); break; + case Op_AndReductionV: vand(dst, a, b); break; + case Op_OrReductionV: vor(dst, a, b); break; + case Op_XorReductionV: vxor(dst, a, b); break; + case Op_MinReductionV: vminsw(dst, a, b); break; + case Op_MaxReductionV: vmaxsw(dst, a, b); break; + default: assert(false, "wrong opcode"); + } + }; + + auto fn_scalar_op = [this](int opcode, const Register &dst, const Register &a, const Register &b) { + switch (opcode) { + case Op_AddReductionVI: add(dst, a, b); break; + case Op_MulReductionVI: mullw(dst, a, b); break; + case Op_AndReductionV: andr(dst, a, b); break; + case Op_OrReductionV: orr(dst, a, b); break; + case Op_XorReductionV: xorr(dst, a, b); break; + case Op_MinReductionV: + cmpw(CR0, a, b); + isel(dst, CR0, Assembler::less, /*invert*/false, a, b); + break; + case Op_MaxReductionV: + cmpw(CR0, a, b); + isel(dst, CR0, Assembler::greater, /*invert*/false, a, b); + break; + default: assert(false, "wrong opcode"); + } + }; + + // vSrc = [i0,i1,i2,i3] + vsldoi(vTmp1, vSrc, vSrc, 8); // vTmp1 <- [i2,i3,i0,i1] + fn_vec_op(opcode, vTmp2, vSrc, vTmp1); // vTmp2 <- [op(i0,i2), op(i1,i3), op(i2,i0), op(i3,i1)] + vsldoi(vTmp1, vTmp2, vTmp2, 4); // vTmp1 <- [op(i1,i3), op(i2,i0), op(i3,i1), op(i0,i2)] + fn_vec_op(opcode, vTmp1, vTmp1, vTmp2); // vTmp1 <- [op(i0,i1,i2,i3), op(i0,i1,i2,i3), op(i0,i1,i2,i3), op(i0,i1,i2,i3)] + mfvsrwz(R0, vTmp1.to_vsr()); // R0 <- op(i0,i1,i2,i3) + fn_scalar_op(opcode, dst, iSrc, R0); // dst <- op(iSrc, R0) +} + diff --git a/src/hotspot/cpu/ppc/c2_MacroAssembler_ppc.hpp b/src/hotspot/cpu/ppc/c2_MacroAssembler_ppc.hpp index 345d5a6350d..16b6d1935ba 100644 --- a/src/hotspot/cpu/ppc/c2_MacroAssembler_ppc.hpp +++ b/src/hotspot/cpu/ppc/c2_MacroAssembler_ppc.hpp @@ -73,4 +73,6 @@ void count_positives(Register src, Register cnt, Register result, Register tmp1, Register tmp2); + void reduceI(int opcode, Register dst, Register iSrc, VectorRegister vSrc, VectorRegister vTmp1, VectorRegister vTmp2); + #endif // CPU_PPC_C2_MACROASSEMBLER_PPC_HPP diff --git a/src/hotspot/cpu/ppc/gc/z/zAddress_ppc.cpp b/src/hotspot/cpu/ppc/gc/z/zAddress_ppc.cpp index f3a7a948f70..20d96f6e937 100644 --- a/src/hotspot/cpu/ppc/gc/z/zAddress_ppc.cpp +++ b/src/hotspot/cpu/ppc/gc/z/zAddress_ppc.cpp @@ -34,9 +34,11 @@ #includeWhen this reader reaches the end of the stream, further + * invocations of this method will return an empty list. + * + *
A line is either a sequence of zero or more characters + * followed by a line terminator, or it is a sequence of one or + * more characters followed by the end of the stream. + * A line does not include the line terminator. + * + *
A line terminator is one of the following: + * a line feed character {@code "\n"} (U+000A), + * a carriage return character {@code "\r"} (U+000D), + * or a carriage return followed immediately by a line feed + * {@code "\r\n"} (U+000D U+000A). + * + *
The behavior for the case where the reader is + * asynchronously closed, or the thread interrupted during the + * read, is highly reader specific, and therefore not specified. + * + *
If an I/O error occurs reading from the stream then it
+ * may do so after some, but not all, characters have been read.
+ * Consequently the stream may not be at end of stream and may
+ * be in an inconsistent state. It is strongly recommended that the reader
+ * be promptly closed if an I/O error occurs.
+ *
+ * @apiNote
+ * This method is intended for simple cases where it is appropriate and
+ * convenient to read the entire input into a list of lines. It is not
+ * suitable for reading input from an unknown origin, as this may result
+ * in the allocation of an arbitrary amount of memory.
+ *
+ * @return the remaining characters as lines of text stored in an
+ * unmodifiable {@code List} of {@code String}s in the order
+ * they are read
+ *
+ * @throws IOException If an I/O error occurs
+ * @throws OutOfMemoryError If the number of remaining characters
+ * exceeds the implementation limit for {@code String}.
+ *
+ * @see String#lines
+ * @see #readAllAsString
+ * @see java.nio.file.Files#readAllLines
+ *
+ * @since 25
+ */
+ public List When this reader reaches the end of the stream, further
+ * invocations of this method will return an empty string.
+ *
+ * The behavior for the case where the reader
+ * is asynchronously closed, or the thread interrupted during the
+ * read, is highly reader specific, and therefore not specified.
+ *
+ * If an I/O error occurs reading from the stream then it
+ * may do so after some, but not all, characters have been read.
+ * Consequently the stream may not be at end of stream and may
+ * be in an inconsistent state. It is strongly recommended that the reader
+ * be promptly closed if an I/O error occurs.
+ *
+ * @apiNote
+ * This method is intended for simple cases where it is appropriate and
+ * convenient to read the entire input into a {@code String}. It is not
+ * suitable for reading input from an unknown origin, as this may result
+ * in the allocation of an arbitrary amount of memory.
+ *
+ * @return a {@code String} containing all remaining characters
+ *
+ * @throws IOException If an I/O error occurs
+ * @throws OutOfMemoryError If the number of remaining characters
+ * exceeds the implementation limit for
+ * {@code String}.
+ *
+ * @see #readAllLines
+ * @see java.nio.file.Files#readString
+ *
+ * @since 25
+ */
+ public String readAllAsString() throws IOException {
+ return readAllCharsAsString();
+ }
+
/** Maximum skip-buffer size */
private static final int maxSkipBufferSize = 8192;
diff --git a/src/java.base/share/classes/java/lang/CharacterData.java b/src/java.base/share/classes/java/lang/CharacterData.java
index d75853fe9ca..6631b7c204e 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, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2025, Oracle and/or its affiliates. All rights reserved.
* 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 @@
package java.lang;
-abstract class CharacterData {
+abstract sealed class CharacterData
+ permits CharacterData00, CharacterData01, CharacterData02, CharacterData03,
+ CharacterData0E, CharacterDataLatin1, CharacterDataPrivateUse, CharacterDataUndefined {
abstract int getProperties(int ch);
abstract int getType(int ch);
abstract boolean isDigit(int ch);
diff --git a/src/java.base/share/classes/java/lang/CharacterData00.java.template b/src/java.base/share/classes/java/lang/CharacterData00.java.template
index db496250201..247a3ec7050 100644
--- a/src/java.base/share/classes/java/lang/CharacterData00.java.template
+++ b/src/java.base/share/classes/java/lang/CharacterData00.java.template
@@ -25,12 +25,14 @@
package java.lang;
+import jdk.internal.vm.annotation.Stable;
+
/**
* The CharacterData00 class encapsulates the large tables once found in
* java.lang.Character
*/
-class CharacterData00 extends CharacterData {
+final class CharacterData00 extends CharacterData {
/* The character properties are currently encoded into 32 bits in the following manner:
1 bit mirrored property
4 bits directionality property
diff --git a/src/java.base/share/classes/java/lang/CharacterData01.java.template b/src/java.base/share/classes/java/lang/CharacterData01.java.template
index 0c25f633391..e634e3486e8 100644
--- a/src/java.base/share/classes/java/lang/CharacterData01.java.template
+++ b/src/java.base/share/classes/java/lang/CharacterData01.java.template
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,11 +25,13 @@
package java.lang;
-/** The CharacterData class encapsulates the large tables once found in
+import jdk.internal.vm.annotation.Stable;
+
+/** The CharacterData01 class encapsulates the large tables once found in
* java.lang.Character.
*/
-class CharacterData01 extends CharacterData {
+final class CharacterData01 extends CharacterData {
/* The character properties are currently encoded into 32 bits in the following manner:
1 bit mirrored property
4 bits directionality property
diff --git a/src/java.base/share/classes/java/lang/CharacterData02.java.template b/src/java.base/share/classes/java/lang/CharacterData02.java.template
index ff5a1c30189..65570ae3f5b 100644
--- a/src/java.base/share/classes/java/lang/CharacterData02.java.template
+++ b/src/java.base/share/classes/java/lang/CharacterData02.java.template
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,10 +25,12 @@
package java.lang;
-/** The CharacterData class encapsulates the large tables found in
+import jdk.internal.vm.annotation.Stable;
+
+/** The CharacterData02 class encapsulates the large tables found in
Java.lang.Character. */
-class CharacterData02 extends CharacterData {
+final class CharacterData02 extends CharacterData {
/* The character properties are currently encoded into 32 bits in the following manner:
1 bit mirrored property
4 bits directionality property
diff --git a/src/java.base/share/classes/java/lang/CharacterData03.java.template b/src/java.base/share/classes/java/lang/CharacterData03.java.template
index 27d1f4b9a69..6b7d037fbc3 100644
--- a/src/java.base/share/classes/java/lang/CharacterData03.java.template
+++ b/src/java.base/share/classes/java/lang/CharacterData03.java.template
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,10 +25,12 @@
package java.lang;
-/** The CharacterData class encapsulates the large tables found in
+import jdk.internal.vm.annotation.Stable;
+
+/** The CharacterData03 class encapsulates the large tables found in
Java.lang.Character. */
-class CharacterData03 extends CharacterData {
+final 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
diff --git a/src/java.base/share/classes/java/lang/CharacterData0E.java.template b/src/java.base/share/classes/java/lang/CharacterData0E.java.template
index f2ac14682ac..6e4858e4d3d 100644
--- a/src/java.base/share/classes/java/lang/CharacterData0E.java.template
+++ b/src/java.base/share/classes/java/lang/CharacterData0E.java.template
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,10 +25,12 @@
package java.lang;
-/** The CharacterData class encapsulates the large tables found in
+import jdk.internal.vm.annotation.Stable;
+
+/** The CharacterData0E class encapsulates the large tables found in
Java.lang.Character. */
-class CharacterData0E extends CharacterData {
+final class CharacterData0E extends CharacterData {
/* The character properties are currently encoded into 32 bits in the following manner:
1 bit mirrored property
4 bits directionality property
diff --git a/src/java.base/share/classes/java/lang/CharacterDataLatin1.java.template b/src/java.base/share/classes/java/lang/CharacterDataLatin1.java.template
index 3f162e6cc16..8316164c7c5 100644
--- a/src/java.base/share/classes/java/lang/CharacterDataLatin1.java.template
+++ b/src/java.base/share/classes/java/lang/CharacterDataLatin1.java.template
@@ -26,11 +26,12 @@
package java.lang;
import jdk.internal.vm.annotation.IntrinsicCandidate;
+import jdk.internal.vm.annotation.Stable;
-/** The CharacterData class encapsulates the large tables found in
+/** The CharacterDataLatin1 class encapsulates the large tables found in
Java.lang.Character. */
-class CharacterDataLatin1 extends CharacterData {
+final class CharacterDataLatin1 extends CharacterData {
/* The character properties are currently encoded into 32 bits in the following manner:
1 bit mirrored property
@@ -230,6 +231,7 @@ class CharacterDataLatin1 extends CharacterData {
//
// Analysis has shown that generating the whole array allows the JIT to generate
// better code compared to a slimmed down array, such as one cutting off after 'z'
+ @Stable
private static final byte[] DIGITS = new byte[] {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
@@ -314,6 +316,7 @@ class CharacterDataLatin1 extends CharacterData {
return mapChar;
}
+ @Stable
static char[] sharpsMap = new char[] {'S', 'S'};
char[] toUpperCaseCharArray(int ch) {
diff --git a/src/java.base/share/classes/java/lang/CharacterDataPrivateUse.java b/src/java.base/share/classes/java/lang/CharacterDataPrivateUse.java
index 9e6c446f86a..22eae86f4a3 100644
--- a/src/java.base/share/classes/java/lang/CharacterDataPrivateUse.java
+++ b/src/java.base/share/classes/java/lang/CharacterDataPrivateUse.java
@@ -25,10 +25,10 @@
package java.lang;
-/** The CharacterData class encapsulates the large tables found in
+/** The CharacterDataPrivateUse class encapsulates the large tables found in
Java.lang.Character. */
-class CharacterDataPrivateUse extends CharacterData {
+final class CharacterDataPrivateUse extends CharacterData {
int getProperties(int ch) {
return 0;
diff --git a/src/java.base/share/classes/java/lang/CharacterDataUndefined.java b/src/java.base/share/classes/java/lang/CharacterDataUndefined.java
index 58c74b658b1..4db9ff4ed3c 100644
--- a/src/java.base/share/classes/java/lang/CharacterDataUndefined.java
+++ b/src/java.base/share/classes/java/lang/CharacterDataUndefined.java
@@ -25,10 +25,10 @@
package java.lang;
-/** The CharacterData class encapsulates the large tables found in
+/** The CharacterDataUndefined class encapsulates the large tables found in
Java.lang.Character. */
-class CharacterDataUndefined extends CharacterData {
+final class CharacterDataUndefined extends CharacterData {
int getProperties(int ch) {
return 0;
diff --git a/src/java.base/share/classes/java/lang/IO.java b/src/java.base/share/classes/java/lang/IO.java
index 1f88de7e238..4630d8a3be2 100644
--- a/src/java.base/share/classes/java/lang/IO.java
+++ b/src/java.base/share/classes/java/lang/IO.java
@@ -38,7 +38,7 @@ import java.nio.charset.StandardCharsets;
*
* The {@link #readln()} and {@link #readln(String)} methods decode bytes read from
* {@code System.in} into characters. The charset used for decoding is specified by the
- * {@link System#getProperties stdin.encoding} property. If this property is not present,
+ * {@link System##stdin.encoding stdin.encoding} property. If this property is not present,
* or if the charset it names cannot be loaded, then UTF-8 is used instead. Decoding
* always replaces malformed and unmappable byte sequences with the charset's default
* replacement string.
diff --git a/src/java.base/share/classes/java/lang/InheritableThreadLocal.java b/src/java.base/share/classes/java/lang/InheritableThreadLocal.java
index 10543314ead..ebc95e58418 100644
--- a/src/java.base/share/classes/java/lang/InheritableThreadLocal.java
+++ b/src/java.base/share/classes/java/lang/InheritableThreadLocal.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -80,7 +80,7 @@ public class InheritableThreadLocal The {@linkplain #decode(String, Class)} and
- * {@linkplain #decode(InputStream, Class)} methods take a Class parameter
+ * {@linkplain #decode(InputStream, Class)} methods take a class parameter
* which determines the type of {@code DEREncodable} that is returned. These
* methods are useful when extracting or changing the return class.
* For example, if the PEM contains both public and private keys, the
- * Class parameter can specify which to return. Use
+ * class parameter can specify which to return. Use
* {@code PrivateKey.class} to return only the private key.
- * If the Class parameter is set to {@code X509EncodedKeySpec.class}, the
+ * If the class parameter is set to {@code X509EncodedKeySpec.class}, the
* public key will be returned in that format. Any type of PEM data can be
* decoded into a {@code PEMRecord} by specifying {@code PEMRecord.class}.
- * If the Class parameter doesn't match the PEM content, an
- * {@code IllegalArgumentException} will be thrown.
+ * If the class parameter doesn't match the PEM content, a
+ * {@linkplain ClassCastException} will be thrown.
*
* A new {@code PEMDecoder} instance is created when configured
* with {@linkplain #withFactory(Provider)} and/or
* {@linkplain #withDecryption(char[])}. {@linkplain #withFactory(Provider)}
* configures the decoder to use only {@linkplain KeyFactory} and
* {@linkplain CertificateFactory} instances from the given {@code Provider}.
- * {@link#withDecryption(char[])} configures the decoder to decrypt all
+ * {@linkplain #withDecryption(char[])} configures the decoder to decrypt all
* encrypted private key PEM data using the given password.
* Configuring an instance for decryption does not prevent decoding with
* unencrypted PEM. Any encrypted PEM that fails decryption
@@ -117,15 +117,15 @@ import java.util.Objects;
* Here is an example of a {@code PEMDecoder} configured with decryption
* and a factory provider:
* {@snippet lang = java:
- * PEMDecoder pe = PEMDecoder.of().withDecryption(password).
+ * PEMDecoder pd = PEMDecoder.of().withDecryption(password).
* withFactory(provider);
- * byte[] pemData = pe.decode(privKey);
+ * byte[] pemData = pd.decode(privKey);
* }
*
* @implNote An implementation may support other PEM types and
- * {@code DEREncodables}. This implementation additionally supports PEM types:
- * {@code X509 CERTIFICATE}, {@code X.509 CERTIFICATE}, {@code CRL},
- * and {@code RSA PRIVATE KEY}.
+ * {@code DEREncodable} objects. This implementation additionally supports
+ * the following PEM types: {@code X509 CERTIFICATE},
+ * {@code X.509 CERTIFICATE}, {@code CRL}, and {@code RSA PRIVATE KEY}.
*
* @see PEMEncoder
* @see PEMRecord
@@ -179,13 +179,13 @@ public final class PEMDecoder {
return switch (pem.type()) {
case Pem.PUBLIC_KEY -> {
X509EncodedKeySpec spec =
- new X509EncodedKeySpec(decoder.decode(pem.pem()));
+ new X509EncodedKeySpec(decoder.decode(pem.content()));
yield getKeyFactory(
KeyUtil.getAlgorithm(spec.getEncoded())).
generatePublic(spec);
}
case Pem.PRIVATE_KEY -> {
- PKCS8Key p8key = new PKCS8Key(decoder.decode(pem.pem()));
+ PKCS8Key p8key = new PKCS8Key(decoder.decode(pem.content()));
String algo = p8key.getAlgorithm();
KeyFactory kf = getKeyFactory(algo);
DEREncodable d = kf.generatePrivate(
@@ -216,27 +216,27 @@ public final class PEMDecoder {
case Pem.ENCRYPTED_PRIVATE_KEY -> {
if (password == null) {
yield new EncryptedPrivateKeyInfo(decoder.decode(
- pem.pem()));
+ pem.content()));
}
- yield new EncryptedPrivateKeyInfo(decoder.decode(pem.pem())).
+ yield new EncryptedPrivateKeyInfo(decoder.decode(pem.content())).
getKey(password.getPassword());
}
case Pem.CERTIFICATE, Pem.X509_CERTIFICATE,
Pem.X_509_CERTIFICATE -> {
CertificateFactory cf = getCertFactory("X509");
yield (X509Certificate) cf.generateCertificate(
- new ByteArrayInputStream(decoder.decode(pem.pem())));
+ new ByteArrayInputStream(decoder.decode(pem.content())));
}
case Pem.X509_CRL, Pem.CRL -> {
CertificateFactory cf = getCertFactory("X509");
yield (X509CRL) cf.generateCRL(
- new ByteArrayInputStream(decoder.decode(pem.pem())));
+ new ByteArrayInputStream(decoder.decode(pem.content())));
}
case Pem.RSA_PRIVATE_KEY -> {
KeyFactory kf = getKeyFactory("RSA");
yield kf.generatePrivate(
RSAPrivateCrtKeyImpl.getKeySpec(decoder.decode(
- pem.pem())));
+ pem.content())));
}
default -> pem;
};
@@ -271,7 +271,6 @@ public final class PEMDecoder {
*/
public DEREncodable decode(String str) {
Objects.requireNonNull(str);
- DEREncodable de;
try {
return decode(new ByteArrayInputStream(
str.getBytes(StandardCharsets.UTF_8)));
@@ -483,9 +482,6 @@ public final class PEMDecoder {
* from the specified {@link Provider} to produce cryptographic objects.
* Any errors using the {@code Provider} will occur during decoding.
*
- * If {@code provider} is {@code null}, a new instance is returned with
- * the default provider configuration.
- *
* @param provider the factory provider
* @return a new PEMEncoder instance configured to the {@code Provider}.
* @throws NullPointerException if {@code provider} is null
diff --git a/src/java.base/share/classes/java/security/PEMEncoder.java b/src/java.base/share/classes/java/security/PEMEncoder.java
index d5465083330..95fcffe967b 100644
--- a/src/java.base/share/classes/java/security/PEMEncoder.java
+++ b/src/java.base/share/classes/java/security/PEMEncoder.java
@@ -71,7 +71,7 @@ import java.util.concurrent.locks.ReentrantLock;
* OneAsymmetricKey structure using the "PRIVATE KEY" type.
*
* When encoding a {@link PEMRecord}, the API surrounds the
- * {@linkplain PEMRecord#pem()} with the PEM header and footer
+ * {@linkplain PEMRecord#content()} with the PEM header and footer
* from {@linkplain PEMRecord#type()}. {@linkplain PEMRecord#leadingData()} is
* not included in the encoding. {@code PEMRecord} will not perform
* validity checks on the data.
@@ -108,7 +108,8 @@ import java.util.concurrent.locks.ReentrantLock;
* byte[] pemData = pe.encode(privKey);
* }
*
- * @implNote An implementation may support other PEM types and DEREncodables.
+ * @implNote An implementation may support other PEM types and
+ * {@code DEREncodable} objects.
*
*
* @see PEMDecoder
@@ -287,7 +288,7 @@ public final class PEMEncoder {
}
// If `keySpec` is non-null, then `key` hasn't been established.
- // Setting a `key' prevents repeated key generations operations.
+ // Setting a `key` prevents repeated key generation operations.
// withEncryption() is a configuration method and cannot throw an
// exception; therefore generation is delayed.
if (keySpec != null) {
diff --git a/src/java.base/share/classes/java/security/PEMRecord.java b/src/java.base/share/classes/java/security/PEMRecord.java
index dfe951a0963..2ce567f9fde 100644
--- a/src/java.base/share/classes/java/security/PEMRecord.java
+++ b/src/java.base/share/classes/java/security/PEMRecord.java
@@ -29,7 +29,6 @@ import jdk.internal.javac.PreviewFeature;
import sun.security.util.Pem;
-import java.util.Base64;
import java.util.Objects;
/**
@@ -39,20 +38,20 @@ import java.util.Objects;
* cryptographic object is not desired or the type has no
* {@code DEREncodable}.
*
- * {@code type} and {@code pem} may not be {@code null}.
+ * {@code type} and {@code content} may not be {@code null}.
* {@code leadingData} may be null if no non-PEM data preceded PEM header
* during decoding. {@code leadingData} may be useful for reading metadata
* that accompanies PEM data.
*
* No validation is performed during instantiation to ensure that
- * {@code type} conforms to {@code RFC 7468}, that {@code pem} is valid Base64,
- * or that {@code pem} matches the {@code type}. {@code leadingData} is not
- * defensively copied and does not return a clone when
- * {@linkplain #leadingData()} is called.
+ * {@code type} conforms to {@code RFC 7468}, that {@code content} is valid
+ * Base64, or that {@code content} matches the {@code type}.
+ * {@code leadingData} is not defensively copied and does not return a
+ * clone when {@linkplain #leadingData()} is called.
*
* @param type the type identifier in the PEM header without PEM syntax labels.
* For a public key, {@code type} would be "PUBLIC KEY".
- * @param pem any data between the PEM header and footer.
+ * @param content the Base64-encoded data, excluding the PEM header and footer
* @param leadingData any non-PEM data preceding the PEM header when decoding.
*
* @spec https://www.rfc-editor.org/info/rfc7468
@@ -64,25 +63,25 @@ import java.util.Objects;
* @since 25
*/
@PreviewFeature(feature = PreviewFeature.Feature.PEM_API)
-public record PEMRecord(String type, String pem, byte[] leadingData)
+public record PEMRecord(String type, String content, byte[] leadingData)
implements DEREncodable {
/**
* Creates a {@code PEMRecord} instance with the given parameters.
*
* @param type the type identifier
- * @param pem the Base64-encoded data encapsulated by the PEM header and
- * footer.
+ * @param content the Base64-encoded data, excluding the PEM header and
+ * footer
* @param leadingData any non-PEM data read during the decoding process
* before the PEM header. This value maybe {@code null}.
- * @throws IllegalArgumentException if the {@code type} is incorrectly
+ * @throws IllegalArgumentException if {@code type} is incorrectly
* formatted.
- * @throws NullPointerException if {@code type} and/or {@code pem} are
+ * @throws NullPointerException if {@code type} and/or {@code content} are
* {@code null}.
*/
- public PEMRecord(String type, String pem, byte[] leadingData) {
+ public PEMRecord {
Objects.requireNonNull(type, "\"type\" cannot be null.");
- Objects.requireNonNull(pem, "\"pem\" cannot be null.");
+ Objects.requireNonNull(content, "\"content\" cannot be null.");
// With no validity checking on `type`, the constructor accept anything
// including lowercase. The onus is on the caller.
@@ -92,37 +91,22 @@ public record PEMRecord(String type, String pem, byte[] leadingData)
"Only the PEM type identifier is allowed");
}
- this.type = type;
- this.pem = pem;
- this.leadingData = leadingData;
}
/**
* Creates a {@code PEMRecord} instance with a given {@code type} and
- * {@code pem} data in String form. {@code leadingData} is set to null.
+ * {@code content} data in String form. {@code leadingData} is set to null.
*
* @param type the PEM type identifier
- * @param pem the Base64-encoded data encapsulated by the PEM header and
- * footer.
- * @throws IllegalArgumentException if the {@code type} is incorrectly
+ * @param content the Base64-encoded data, excluding the PEM header and
+ * footer
+ * @throws IllegalArgumentException if {@code type} is incorrectly
* formatted.
- * @throws NullPointerException if {@code type} and/or {@code pem} are
+ * @throws NullPointerException if {@code type} and/or {@code content} are
* {@code null}.
*/
- public PEMRecord(String type, String pem) {
- this(type, pem, null);
- }
-
- /**
- * Returns the binary encoding from the Base64 data contained in
- * {@code pem}.
- *
- * @throws IllegalArgumentException if {@code pem} cannot be decoded.
- * @return a new array of the binary encoding each time this
- * method is called.
- */
- public byte[] getEncoded() {
- return Base64.getMimeDecoder().decode(pem);
+ public PEMRecord(String type, String content) {
+ this(type, content, null);
}
/**
diff --git a/src/java.base/share/classes/java/security/SecureClassLoader.java b/src/java.base/share/classes/java/security/SecureClassLoader.java
index 8a6ba76e211..b398d7332d7 100644
--- a/src/java.base/share/classes/java/security/SecureClassLoader.java
+++ b/src/java.base/share/classes/java/security/SecureClassLoader.java
@@ -64,15 +64,22 @@ public class SecureClassLoader extends ClassLoader {
* Creates a new {@code SecureClassLoader} using the specified parent
* class loader for delegation.
*
- * @param parent the parent ClassLoader
+ * @apiNote If {@code parent} is specified as {@code null} (for the
+ * bootstrap class loader) then there is no guarantee that all platform
+ * classes are visible.
+ * See {@linkplain ClassLoader##builtinLoaders Run-time Built-in Class Loaders}
+ * for information on the bootstrap class loader and other built-in class loaders.
+ *
+ * @param parent the parent ClassLoader, can be {@code null} for the bootstrap
+ * class loader
*/
protected SecureClassLoader(ClassLoader parent) {
super(parent);
}
/**
- * Creates a new {@code SecureClassLoader} using the default parent class
- * loader for delegation.
+ * Creates a new {@code SecureClassLoader} using the
+ * {@linkplain ClassLoader#getSystemClassLoader() system class loader as the parent}.
*/
protected SecureClassLoader() {
super();
@@ -82,8 +89,15 @@ public class SecureClassLoader extends ClassLoader {
* Creates a new {@code SecureClassLoader} of the specified name and
* using the specified parent class loader for delegation.
*
+ * @apiNote If {@code parent} is specified as {@code null} (for the
+ * bootstrap class loader) then there is no guarantee that all platform
+ * classes are visible.
+ * See {@linkplain ClassLoader##builtinLoaders Run-time Built-in Class Loaders}
+ * for information on the bootstrap class loader and other built-in class loaders.
+ *
* @param name class loader name; or {@code null} if not named
- * @param parent the parent class loader
+ * @param parent the parent class loader, can be {@code null} for the bootstrap
+ * class loader
*
* @throws IllegalArgumentException if the given name is empty.
*
diff --git a/src/java.base/share/classes/java/security/doc-files/debug-system-property.html b/src/java.base/share/classes/java/security/doc-files/debug-system-property.html
index 4ea34252b3c..ac325b2ef62 100644
--- a/src/java.base/share/classes/java/security/doc-files/debug-system-property.html
+++ b/src/java.base/share/classes/java/security/doc-files/debug-system-property.html
@@ -52,24 +52,10 @@
To monitor security access, you can set the
- You can append the following strings to any option specified in the
-
- For example, to add thread, caller, and timestamp information to all
- debugging output, set the The following table lists the java.security.debug
system property, which determines what trace messages are printed during
execution. The value of the property is one or more options separated by a
- comma.
+ comma. Each trace message includes the thread id, caller information, and
+ timestamp.
Printing Thread and Timestamp Information
-java.security.debug
system property to print additional
- information:
-
-
-+thread
: Print thread and caller information+timestamp
: Print timestamp informationjava.security.debug
system property
- on the command line as follows:
-
-
java -Djava.security.debug=all+thread+timestamp MyApp
java.security.debug
options:
diff --git a/src/java.base/share/classes/java/util/AbstractMap.java b/src/java.base/share/classes/java/util/AbstractMap.java
index 7c0b4d9dd1b..afc5b339354 100644
--- a/src/java.base/share/classes/java/util/AbstractMap.java
+++ b/src/java.base/share/classes/java/util/AbstractMap.java
@@ -877,6 +877,14 @@ public abstract class AbstractMap
Locale Matching
@@ -733,58 +733,24 @@ public final class Locale implements Cloneable, Serializable {
* @see #getISOCountries(Locale.IsoCountryCode)
* @since 9
*/
- public static enum IsoCountryCode {
+ public enum IsoCountryCode {
/**
* PART1_ALPHA2 is used to represent the ISO3166-1 alpha-2 two letter
* country codes.
*/
- PART1_ALPHA2 {
- @Override
- Set