diff --git a/make/conf/jib-profiles.js b/make/conf/jib-profiles.js index 91876878046..d4877604a90 100644 --- a/make/conf/jib-profiles.js +++ b/make/conf/jib-profiles.js @@ -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/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 f367362b4d8..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 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/macroAssembler_aarch64.hpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp index d77bc92875f..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; } diff --git a/src/hotspot/cpu/ppc/gc/z/z_ppc.ad b/src/hotspot/cpu/ppc/gc/z/z_ppc.ad index 65fb206ad7e..0872932ccb2 100644 --- a/src/hotspot/cpu/ppc/gc/z/z_ppc.ad +++ b/src/hotspot/cpu/ppc/gc/z/z_ppc.ad @@ -141,6 +141,7 @@ instruct zLoadP(iRegPdst dst, memoryAlg4 mem, flagsRegCR0 cr0) %{ match(Set dst (LoadP mem)); effect(TEMP_DEF dst, KILL cr0); + ins_is_late_expanded_null_check_candidate(true); ins_cost(MEMORY_REF_COST); predicate((UseZGC && n->as_Load()->barrier_data() != 0) @@ -160,6 +161,7 @@ instruct zLoadP_acq(iRegPdst dst, memoryAlg4 mem, flagsRegCR0 cr0) %{ match(Set dst (LoadP mem)); effect(TEMP_DEF dst, KILL cr0); + ins_is_late_expanded_null_check_candidate(true); ins_cost(3 * MEMORY_REF_COST); // Predicate on instruction order is implicitly present due to the predicate of the cheaper zLoadP operation diff --git a/src/hotspot/cpu/ppc/ppc.ad b/src/hotspot/cpu/ppc/ppc.ad index 128e566d0f3..d8e00cfef89 100644 --- a/src/hotspot/cpu/ppc/ppc.ad +++ b/src/hotspot/cpu/ppc/ppc.ad @@ -4036,6 +4036,10 @@ ins_attrib ins_field_cbuf_insts_offset(-1); ins_attrib ins_field_load_ic_hi_node(0); ins_attrib ins_field_load_ic_node(0); +// 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 diff --git a/src/hotspot/cpu/riscv/gc/z/z_riscv.ad b/src/hotspot/cpu/riscv/gc/z/z_riscv.ad index fd9a1d43afc..e3847019bb3 100644 --- a/src/hotspot/cpu/riscv/gc/z/z_riscv.ad +++ b/src/hotspot/cpu/riscv/gc/z/z_riscv.ad @@ -96,6 +96,7 @@ instruct zLoadP(iRegPNoSp dst, memory mem, iRegPNoSp tmp, rFlagsReg cr) match(Set dst (LoadP mem)); predicate(UseZGC && n->as_Load()->barrier_data() != 0); effect(TEMP dst, TEMP tmp, KILL cr); + ins_is_late_expanded_null_check_candidate(true); ins_cost(4 * DEFAULT_COST); diff --git a/src/hotspot/cpu/riscv/riscv.ad b/src/hotspot/cpu/riscv/riscv.ad index e838ee184fb..0d44acc803f 100644 --- a/src/hotspot/cpu/riscv/riscv.ad +++ b/src/hotspot/cpu/riscv/riscv.ad @@ -2619,6 +2619,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 diff --git a/src/hotspot/cpu/x86/gc/z/z_x86_64.ad b/src/hotspot/cpu/x86/gc/z/z_x86_64.ad index 045aa5d5381..e66b4b0da7a 100644 --- a/src/hotspot/cpu/x86/gc/z/z_x86_64.ad +++ b/src/hotspot/cpu/x86/gc/z/z_x86_64.ad @@ -118,6 +118,10 @@ instruct zLoadP(rRegP dst, memory mem, rFlagsReg cr) predicate(UseZGC && n->as_Load()->barrier_data() != 0); match(Set dst (LoadP mem)); effect(TEMP dst, KILL cr); + // The main load is a candidate to implement implicit null checks. The + // barrier's slow path includes an identical reload, which does not need to be + // registered in the exception table because it is dominated by the main one. + ins_is_late_expanded_null_check_candidate(true); ins_cost(125); diff --git a/src/hotspot/cpu/x86/x86_64.ad b/src/hotspot/cpu/x86/x86_64.ad index 22490ba7bb3..d17bdf5e2c9 100644 --- a/src/hotspot/cpu/x86/x86_64.ad +++ b/src/hotspot/cpu/x86/x86_64.ad @@ -2055,6 +2055,10 @@ ins_attrib ins_alignment(1); // 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 diff --git a/src/hotspot/os/aix/os_aix.cpp b/src/hotspot/os/aix/os_aix.cpp index e7b401701ac..9c6218aee16 100644 --- a/src/hotspot/os/aix/os_aix.cpp +++ b/src/hotspot/os/aix/os_aix.cpp @@ -1261,69 +1261,6 @@ void os::pd_print_cpu_info(outputStream* st, char* buf, size_t buflen) { // Nothing to do beyond of what os::print_cpu_info() does. } -static char saved_jvm_path[MAXPATHLEN] = {0}; - -// Find the full path to the current module, libjvm.so. -void os::jvm_path(char *buf, jint buflen) { - // Error checking. - if (buflen < MAXPATHLEN) { - assert(false, "must use a large-enough buffer"); - buf[0] = '\0'; - return; - } - // Lazy resolve the path to current module. - if (saved_jvm_path[0] != 0) { - strcpy(buf, saved_jvm_path); - return; - } - - Dl_info dlinfo; - int ret = dladdr(CAST_FROM_FN_PTR(void *, os::jvm_path), &dlinfo); - assert(ret != 0, "cannot locate libjvm"); - char* rp = os::realpath((char *)dlinfo.dli_fname, buf, buflen); - assert(rp != nullptr, "error in realpath(): maybe the 'path' argument is too long?"); - - // If executing unit tests we require JAVA_HOME to point to the real JDK. - if (Arguments::executing_unit_tests()) { - // Look for JAVA_HOME in the environment. - char* java_home_var = ::getenv("JAVA_HOME"); - if (java_home_var != nullptr && java_home_var[0] != 0) { - - // Check the current module name "libjvm.so". - const char* p = strrchr(buf, '/'); - if (p == nullptr) { - return; - } - assert(strstr(p, "/libjvm") == p, "invalid library name"); - - stringStream ss(buf, buflen); - rp = os::realpath(java_home_var, buf, buflen); - if (rp == nullptr) { - return; - } - - assert((int)strlen(buf) < buflen, "Ran out of buffer room"); - ss.print("%s/lib", buf); - - if (0 == access(buf, F_OK)) { - // Use current module name "libjvm.so" - ss.print("/%s/libjvm%s", Abstract_VM_Version::vm_variant(), JNI_LIB_SUFFIX); - assert(strcmp(buf + strlen(buf) - strlen(JNI_LIB_SUFFIX), JNI_LIB_SUFFIX) == 0, - "buf has been truncated"); - } else { - // Go back to path of .so - rp = os::realpath((char *)dlinfo.dli_fname, buf, buflen); - if (rp == nullptr) { - return; - } - } - } - } - - strncpy(saved_jvm_path, buf, sizeof(saved_jvm_path)); - saved_jvm_path[sizeof(saved_jvm_path) - 1] = '\0'; -} - //////////////////////////////////////////////////////////////////////////////// // Virtual Memory diff --git a/src/hotspot/os/bsd/os_bsd.cpp b/src/hotspot/os/bsd/os_bsd.cpp index 3535d027dbc..9f77d5a4bde 100644 --- a/src/hotspot/os/bsd/os_bsd.cpp +++ b/src/hotspot/os/bsd/os_bsd.cpp @@ -1482,83 +1482,6 @@ void os::print_memory_info(outputStream* st) { st->cr(); } -static char saved_jvm_path[MAXPATHLEN] = {0}; - -// Find the full path to the current module, libjvm -void os::jvm_path(char *buf, jint buflen) { - // Error checking. - if (buflen < MAXPATHLEN) { - assert(false, "must use a large-enough buffer"); - buf[0] = '\0'; - return; - } - // Lazy resolve the path to current module. - if (saved_jvm_path[0] != 0) { - strcpy(buf, saved_jvm_path); - return; - } - - char dli_fname[MAXPATHLEN]; - dli_fname[0] = '\0'; - bool ret = dll_address_to_library_name( - CAST_FROM_FN_PTR(address, os::jvm_path), - dli_fname, sizeof(dli_fname), nullptr); - assert(ret, "cannot locate libjvm"); - char *rp = nullptr; - if (ret && dli_fname[0] != '\0') { - rp = os::realpath(dli_fname, buf, buflen); - } - if (rp == nullptr) { - return; - } - - // If executing unit tests we require JAVA_HOME to point to the real JDK. - if (Arguments::executing_unit_tests()) { - // Look for JAVA_HOME in the environment. - char* java_home_var = ::getenv("JAVA_HOME"); - if (java_home_var != nullptr && java_home_var[0] != 0) { - - // Check the current module name "libjvm" - const char* p = strrchr(buf, '/'); - assert(strstr(p, "/libjvm") == p, "invalid library name"); - - stringStream ss(buf, buflen); - rp = os::realpath(java_home_var, buf, buflen); - if (rp == nullptr) { - return; - } - - assert((int)strlen(buf) < buflen, "Ran out of buffer space"); - // Add the appropriate library and JVM variant subdirs - ss.print("%s/lib/%s", buf, Abstract_VM_Version::vm_variant()); - - if (0 != access(buf, F_OK)) { - ss.reset(); - ss.print("%s/lib", buf); - } - - // If the path exists within JAVA_HOME, add the JVM library name - // to complete the path to JVM being overridden. Otherwise fallback - // to the path to the current library. - if (0 == access(buf, F_OK)) { - // Use current module name "libjvm" - ss.print("/libjvm%s", JNI_LIB_SUFFIX); - assert(strcmp(buf + strlen(buf) - strlen(JNI_LIB_SUFFIX), JNI_LIB_SUFFIX) == 0, - "buf has been truncated"); - } else { - // Fall back to path of current library - rp = os::realpath(dli_fname, buf, buflen); - if (rp == nullptr) { - return; - } - } - } - } - - strncpy(saved_jvm_path, buf, MAXPATHLEN); - saved_jvm_path[MAXPATHLEN - 1] = '\0'; -} - //////////////////////////////////////////////////////////////////////////////// // Virtual Memory diff --git a/src/hotspot/os/linux/globals_linux.hpp b/src/hotspot/os/linux/globals_linux.hpp index 331690ec3ee..542e034f59f 100644 --- a/src/hotspot/os/linux/globals_linux.hpp +++ b/src/hotspot/os/linux/globals_linux.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -35,9 +35,6 @@ range, \ constraint) \ \ - product(bool, UseOprofile, false, \ - "(Deprecated) enable support for Oprofile profiler") \ - \ product(bool, UseTransparentHugePages, false, \ "Use MADV_HUGEPAGE for large pages") \ \ diff --git a/src/hotspot/os/linux/os_linux.cpp b/src/hotspot/os/linux/os_linux.cpp index 807014e7b0c..ff2195d3839 100644 --- a/src/hotspot/os/linux/os_linux.cpp +++ b/src/hotspot/os/linux/os_linux.cpp @@ -2746,118 +2746,9 @@ void os::get_summary_cpu_info(char* cpuinfo, size_t length) { #endif } -static char saved_jvm_path[MAXPATHLEN] = {0}; - -// Find the full path to the current module, libjvm.so -void os::jvm_path(char *buf, jint buflen) { - // Error checking. - if (buflen < MAXPATHLEN) { - assert(false, "must use a large-enough buffer"); - buf[0] = '\0'; - return; - } - // Lazy resolve the path to current module. - if (saved_jvm_path[0] != 0) { - strcpy(buf, saved_jvm_path); - return; - } - - char dli_fname[MAXPATHLEN]; - dli_fname[0] = '\0'; - bool ret = dll_address_to_library_name( - CAST_FROM_FN_PTR(address, os::jvm_path), - dli_fname, sizeof(dli_fname), nullptr); - assert(ret, "cannot locate libjvm"); - char *rp = nullptr; - if (ret && dli_fname[0] != '\0') { - rp = os::realpath(dli_fname, buf, buflen); - } - if (rp == nullptr) { - return; - } - - // If executing unit tests we require JAVA_HOME to point to the real JDK. - if (Arguments::executing_unit_tests()) { - // Look for JAVA_HOME in the environment. - char* java_home_var = ::getenv("JAVA_HOME"); - if (java_home_var != nullptr && java_home_var[0] != 0) { - - // Check the current module name "libjvm.so". - const char* p = strrchr(buf, '/'); - if (p == nullptr) { - return; - } - assert(strstr(p, "/libjvm") == p, "invalid library name"); - - stringStream ss(buf, buflen); - rp = os::realpath(java_home_var, buf, buflen); - if (rp == nullptr) { - return; - } - - assert((int)strlen(buf) < buflen, "Ran out of buffer room"); - ss.print("%s/lib", buf); - - if (0 == access(buf, F_OK)) { - // Use current module name "libjvm.so" - ss.print("/%s/libjvm%s", Abstract_VM_Version::vm_variant(), JNI_LIB_SUFFIX); - assert(strcmp(buf + strlen(buf) - strlen(JNI_LIB_SUFFIX), JNI_LIB_SUFFIX) == 0, - "buf has been truncated"); - } else { - // Go back to path of .so - rp = os::realpath(dli_fname, buf, buflen); - if (rp == nullptr) { - return; - } - } - } - } - - strncpy(saved_jvm_path, buf, MAXPATHLEN); - saved_jvm_path[MAXPATHLEN - 1] = '\0'; -} - //////////////////////////////////////////////////////////////////////////////// // Virtual Memory -// Rationale behind this function: -// current (Mon Apr 25 20:12:18 MSD 2005) oprofile drops samples without executable -// mapping for address (see lookup_dcookie() in the kernel module), thus we cannot get -// samples for JITted code. Here we create private executable mapping over the code cache -// and then we can use standard (well, almost, as mapping can change) way to provide -// info for the reporting script by storing timestamp and location of symbol -void linux_wrap_code(char* base, size_t size) { - static volatile jint cnt = 0; - - static_assert(sizeof(off_t) == 8, "Expected Large File Support in this file"); - - if (!UseOprofile) { - return; - } - - char buf[PATH_MAX+1]; - int num = Atomic::add(&cnt, 1); - - snprintf(buf, sizeof(buf), "%s/hs-vm-%d-%d", - os::get_temp_directory(), os::current_process_id(), num); - unlink(buf); - - int fd = ::open(buf, O_CREAT | O_RDWR, S_IRWXU); - - if (fd != -1) { - off_t rv = ::lseek(fd, size-2, SEEK_SET); - if (rv != (off_t)-1) { - if (::write(fd, "", 1) == 1) { - mmap(base, size, - PROT_READ|PROT_WRITE|PROT_EXEC, - MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE, fd, 0); - } - } - ::close(fd); - unlink(buf); - } -} - static bool recoverable_mmap_error(int err) { // See if the error is one we can let the caller handle. This // list of errno values comes from JBS-6843484. I can't find a diff --git a/src/hotspot/os/posix/os_posix.cpp b/src/hotspot/os/posix/os_posix.cpp index 448ebce620a..303e44eadcb 100644 --- a/src/hotspot/os/posix/os_posix.cpp +++ b/src/hotspot/os/posix/os_posix.cpp @@ -59,6 +59,7 @@ #ifdef AIX #include "loadlib_aix.hpp" #include "os_aix.hpp" +#include "porting_aix.hpp" #endif #ifdef LINUX #include "os_linux.hpp" @@ -1060,6 +1061,95 @@ bool os::same_files(const char* file1, const char* file2) { return is_same; } +static char saved_jvm_path[MAXPATHLEN] = {0}; + +// Find the full path to the current module, libjvm.so +void os::jvm_path(char *buf, jint buflen) { + // Error checking. + if (buflen < MAXPATHLEN) { + assert(false, "must use a large-enough buffer"); + buf[0] = '\0'; + return; + } + // Lazy resolve the path to current module. + if (saved_jvm_path[0] != 0) { + strcpy(buf, saved_jvm_path); + return; + } + + const char* fname; +#ifdef AIX + Dl_info dlinfo; + int ret = dladdr(CAST_FROM_FN_PTR(void *, os::jvm_path), &dlinfo); + assert(ret != 0, "cannot locate libjvm"); + if (ret == 0) { + return; + } + fname = dlinfo.dli_fname; +#else + char dli_fname[MAXPATHLEN]; + dli_fname[0] = '\0'; + bool ret = dll_address_to_library_name( + CAST_FROM_FN_PTR(address, os::jvm_path), + dli_fname, sizeof(dli_fname), nullptr); + assert(ret, "cannot locate libjvm"); + if (!ret) { + return; + } + fname = dli_fname; +#endif // AIX + char* rp = nullptr; + if (fname[0] != '\0') { + rp = os::realpath(fname, buf, buflen); + } + if (rp == nullptr) { + return; + } + + // If executing unit tests we require JAVA_HOME to point to the real JDK. + if (Arguments::executing_unit_tests()) { + // Look for JAVA_HOME in the environment. + char* java_home_var = ::getenv("JAVA_HOME"); + if (java_home_var != nullptr && java_home_var[0] != 0) { + + // Check the current module name "libjvm.so". + const char* p = strrchr(buf, '/'); + if (p == nullptr) { + return; + } + assert(strstr(p, "/libjvm") == p, "invalid library name"); + + stringStream ss(buf, buflen); + rp = os::realpath(java_home_var, buf, buflen); + if (rp == nullptr) { + return; + } + + assert((int)strlen(buf) < buflen, "Ran out of buffer room"); + ss.print("%s/lib", buf); + + // If the path exists within JAVA_HOME, add the VM variant directory and JVM + // library name to complete the path to JVM being overridden. Otherwise fallback + // to the path to the current library. + if (0 == access(buf, F_OK)) { + // Use current module name "libjvm.so" + ss.print("/%s/libjvm%s", Abstract_VM_Version::vm_variant(), JNI_LIB_SUFFIX); + assert(strcmp(buf + strlen(buf) - strlen(JNI_LIB_SUFFIX), JNI_LIB_SUFFIX) == 0, + "buf has been truncated"); + } else { + // Go back to path of .so + rp = os::realpath(fname, buf, buflen); + if (rp == nullptr) { + return; + } + } + } + } + + strncpy(saved_jvm_path, buf, MAXPATHLEN); + saved_jvm_path[MAXPATHLEN - 1] = '\0'; +} + // Called when creating the thread. The minimum stack sizes have already been calculated size_t os::Posix::get_initial_stack_size(ThreadType thr_type, size_t req_stack_size) { size_t stack_size; diff --git a/src/hotspot/share/adlc/main.cpp b/src/hotspot/share/adlc/main.cpp index 16fd4ddcf93..4e8a96617e8 100644 --- a/src/hotspot/share/adlc/main.cpp +++ b/src/hotspot/share/adlc/main.cpp @@ -481,7 +481,3 @@ int get_legal_text(FileBuff &fbuf, char **legal_text) *legal_text = legal_start; return (int) (legal_end - legal_start); } - -void *operator new( size_t size, int, const char *, int ) throw() { - return ::operator new( size ); -} diff --git a/src/hotspot/share/adlc/output_h.cpp b/src/hotspot/share/adlc/output_h.cpp index b62bc43791f..cbcc00efa3b 100644 --- a/src/hotspot/share/adlc/output_h.cpp +++ b/src/hotspot/share/adlc/output_h.cpp @@ -1626,6 +1626,8 @@ void ArchDesc::declareClasses(FILE *fp) { while (attr != nullptr) { if (strcmp (attr->_ident, "ins_is_TrapBasedCheckNode") == 0) { fprintf(fp, " virtual bool is_TrapBasedCheckNode() const { return %s; }\n", attr->_val); + } else if (strcmp (attr->_ident, "ins_is_late_expanded_null_check_candidate") == 0) { + fprintf(fp, " virtual bool is_late_expanded_null_check_candidate() const { return %s; }\n", attr->_val); } else if (strcmp (attr->_ident, "ins_cost") != 0 && strncmp(attr->_ident, "ins_field_", 10) != 0 && // Must match function in node.hpp: return type bool, no prefix "ins_". diff --git a/src/hotspot/share/cds/cdsConfig.cpp b/src/hotspot/share/cds/cdsConfig.cpp index b3c13b63aff..b93238eca88 100644 --- a/src/hotspot/share/cds/cdsConfig.cpp +++ b/src/hotspot/share/cds/cdsConfig.cpp @@ -110,12 +110,24 @@ const char* CDSConfig::default_archive_path() { // before CDSConfig::ergo_initialize() is called. assert(_cds_ergo_initialize_started, "sanity"); if (_default_archive_path == nullptr) { - char jvm_path[JVM_MAXPATHLEN]; - os::jvm_path(jvm_path, sizeof(jvm_path)); - char *end = strrchr(jvm_path, *os::file_separator()); - if (end != nullptr) *end = '\0'; stringStream tmp; - tmp.print("%s%sclasses", jvm_path, os::file_separator()); + if (is_vm_statically_linked()) { + // It's easier to form the path using JAVA_HOME as os::jvm_path + // gives the path to the launcher executable on static JDK. + const char* subdir = WINDOWS_ONLY("bin") NOT_WINDOWS("lib"); + tmp.print("%s%s%s%s%s%sclasses", + Arguments::get_java_home(), os::file_separator(), + subdir, os::file_separator(), + Abstract_VM_Version::vm_variant(), os::file_separator()); + } else { + // Assume .jsa is in the same directory where libjvm resides on + // non-static JDK. + char jvm_path[JVM_MAXPATHLEN]; + os::jvm_path(jvm_path, sizeof(jvm_path)); + char *end = strrchr(jvm_path, *os::file_separator()); + if (end != nullptr) *end = '\0'; + tmp.print("%s%sclasses", jvm_path, os::file_separator()); + } #ifdef _LP64 if (!UseCompressedOops) { tmp.print_raw("_nocoops"); diff --git a/src/hotspot/share/gc/parallel/parallelArguments.cpp b/src/hotspot/share/gc/parallel/parallelArguments.cpp index 2cddbafd871..cae6f9a93d5 100644 --- a/src/hotspot/share/gc/parallel/parallelArguments.cpp +++ b/src/hotspot/share/gc/parallel/parallelArguments.cpp @@ -98,15 +98,15 @@ void ParallelArguments::initialize() { FullGCForwarding::initialize_flags(heap_reserved_size_bytes()); } -// The alignment used for boundary between young gen and old gen -static size_t default_gen_alignment() { +// The alignment used for spaces in young gen and old gen +static size_t default_space_alignment() { return 64 * K * HeapWordSize; } void ParallelArguments::initialize_alignments() { // Initialize card size before initializing alignments CardTable::initialize_card_size(); - SpaceAlignment = GenAlignment = default_gen_alignment(); + SpaceAlignment = default_space_alignment(); HeapAlignment = compute_heap_alignment(); } @@ -123,9 +123,8 @@ void ParallelArguments::initialize_heap_flags_and_sizes() { // Can a page size be something else than a power of two? assert(is_power_of_2((intptr_t)page_sz), "must be a power of 2"); - size_t new_alignment = align_up(page_sz, GenAlignment); - if (new_alignment != GenAlignment) { - GenAlignment = new_alignment; + size_t new_alignment = align_up(page_sz, SpaceAlignment); + if (new_alignment != SpaceAlignment) { SpaceAlignment = new_alignment; // Redo everything from the start initialize_heap_flags_and_sizes_one_pass(); diff --git a/src/hotspot/share/gc/parallel/parallelInitLogger.cpp b/src/hotspot/share/gc/parallel/parallelInitLogger.cpp index 1d9c9f840ba..d7eb265d113 100644 --- a/src/hotspot/share/gc/parallel/parallelInitLogger.cpp +++ b/src/hotspot/share/gc/parallel/parallelInitLogger.cpp @@ -29,10 +29,8 @@ void ParallelInitLogger::print_heap() { log_info_p(gc, init)("Alignments:" " Space " EXACTFMT "," - " Generation " EXACTFMT "," " Heap " EXACTFMT, EXACTFMTARGS(SpaceAlignment), - EXACTFMTARGS(GenAlignment), EXACTFMTARGS(HeapAlignment)); GCInitLogger::print_heap(); } diff --git a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp index 0235864992f..139a5fa52f1 100644 --- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp +++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp @@ -69,8 +69,8 @@ jint ParallelScavengeHeap::initialize() { initialize_reserved_region(heap_rs); // Layout the reserved space for the generations. - ReservedSpace old_rs = heap_rs.first_part(MaxOldSize, GenAlignment); - ReservedSpace young_rs = heap_rs.last_part(MaxOldSize, GenAlignment); + ReservedSpace old_rs = heap_rs.first_part(MaxOldSize, SpaceAlignment); + ReservedSpace young_rs = heap_rs.last_part(MaxOldSize, SpaceAlignment); assert(young_rs.size() == MaxNewSize, "Didn't reserve all of the heap"); PSCardTable* card_table = new PSCardTable(_reserved); @@ -107,7 +107,7 @@ jint ParallelScavengeHeap::initialize() { new PSAdaptiveSizePolicy(eden_capacity, initial_promo_size, young_gen()->to_space()->capacity_in_bytes(), - GenAlignment, + SpaceAlignment, max_gc_pause_sec, GCTimeRatio ); diff --git a/src/hotspot/share/gc/parallel/psOldGen.cpp b/src/hotspot/share/gc/parallel/psOldGen.cpp index 0d1c3b60672..bc25683e00f 100644 --- a/src/hotspot/share/gc/parallel/psOldGen.cpp +++ b/src/hotspot/share/gc/parallel/psOldGen.cpp @@ -41,7 +41,7 @@ PSOldGen::PSOldGen(ReservedSpace rs, size_t initial_size, size_t min_size, _min_gen_size(min_size), _max_gen_size(max_size) { - initialize(rs, initial_size, GenAlignment); + initialize(rs, initial_size, SpaceAlignment); } void PSOldGen::initialize(ReservedSpace rs, size_t initial_size, size_t alignment) { diff --git a/src/hotspot/share/gc/parallel/psYoungGen.cpp b/src/hotspot/share/gc/parallel/psYoungGen.cpp index f9cb067411e..bf77a0dde93 100644 --- a/src/hotspot/share/gc/parallel/psYoungGen.cpp +++ b/src/hotspot/share/gc/parallel/psYoungGen.cpp @@ -47,7 +47,7 @@ PSYoungGen::PSYoungGen(ReservedSpace rs, size_t initial_size, size_t min_size, s _from_counters(nullptr), _to_counters(nullptr) { - initialize(rs, initial_size, GenAlignment); + initialize(rs, initial_size, SpaceAlignment); } void PSYoungGen::initialize_virtual_space(ReservedSpace rs, @@ -746,7 +746,7 @@ size_t PSYoungGen::available_to_live() { } size_t delta_in_bytes = unused_committed + delta_in_survivor; - delta_in_bytes = align_down(delta_in_bytes, GenAlignment); + delta_in_bytes = align_down(delta_in_bytes, SpaceAlignment); return delta_in_bytes; } diff --git a/src/hotspot/share/gc/serial/serialHeap.cpp b/src/hotspot/share/gc/serial/serialHeap.cpp index 27d94593765..fbbaabf618a 100644 --- a/src/hotspot/share/gc/serial/serialHeap.cpp +++ b/src/hotspot/share/gc/serial/serialHeap.cpp @@ -188,8 +188,8 @@ jint SerialHeap::initialize() { initialize_reserved_region(heap_rs); - ReservedSpace young_rs = heap_rs.first_part(MaxNewSize, GenAlignment); - ReservedSpace old_rs = heap_rs.last_part(MaxNewSize, GenAlignment); + ReservedSpace young_rs = heap_rs.first_part(MaxNewSize, SpaceAlignment); + ReservedSpace old_rs = heap_rs.last_part(MaxNewSize, SpaceAlignment); _rem_set = new CardTableRS(_reserved); _rem_set->initialize(young_rs.base(), old_rs.base()); diff --git a/src/hotspot/share/gc/shared/gcArguments.hpp b/src/hotspot/share/gc/shared/gcArguments.hpp index 40b612d75a6..fff41e85d8c 100644 --- a/src/hotspot/share/gc/shared/gcArguments.hpp +++ b/src/hotspot/share/gc/shared/gcArguments.hpp @@ -35,7 +35,7 @@ extern size_t SpaceAlignment; class GCArguments { protected: - // Initialize HeapAlignment, SpaceAlignment, and extra alignments (E.g. GenAlignment) + // Initialize HeapAlignment, SpaceAlignment virtual void initialize_alignments() = 0; virtual void initialize_heap_flags_and_sizes(); virtual void initialize_size_info(); diff --git a/src/hotspot/share/gc/shared/genArguments.cpp b/src/hotspot/share/gc/shared/genArguments.cpp index 90617b1675f..9618c515b7d 100644 --- a/src/hotspot/share/gc/shared/genArguments.cpp +++ b/src/hotspot/share/gc/shared/genArguments.cpp @@ -42,17 +42,15 @@ size_t MaxOldSize = 0; // See more in JDK-8346005 size_t OldSize = ScaleForWordSize(4*M); -size_t GenAlignment = 0; - size_t GenArguments::conservative_max_heap_alignment() { return (size_t)Generation::GenGrain; } static size_t young_gen_size_lower_bound() { // The young generation must be aligned and have room for eden + two survivors - return align_up(3 * SpaceAlignment, GenAlignment); + return 3 * SpaceAlignment; } static size_t old_gen_size_lower_bound() { - return align_up(SpaceAlignment, GenAlignment); + return SpaceAlignment; } size_t GenArguments::scale_by_NewRatio_aligned(size_t base_size, size_t alignment) { @@ -69,23 +67,20 @@ static size_t bound_minus_alignment(size_t desired_size, void GenArguments::initialize_alignments() { // Initialize card size before initializing alignments CardTable::initialize_card_size(); - SpaceAlignment = GenAlignment = (size_t)Generation::GenGrain; + SpaceAlignment = (size_t)Generation::GenGrain; HeapAlignment = compute_heap_alignment(); } void GenArguments::initialize_heap_flags_and_sizes() { GCArguments::initialize_heap_flags_and_sizes(); - assert(GenAlignment != 0, "Generation alignment not set up properly"); - assert(HeapAlignment >= GenAlignment, - "HeapAlignment: %zu less than GenAlignment: %zu", - HeapAlignment, GenAlignment); - assert(GenAlignment % SpaceAlignment == 0, - "GenAlignment: %zu not aligned by SpaceAlignment: %zu", - GenAlignment, SpaceAlignment); - assert(HeapAlignment % GenAlignment == 0, - "HeapAlignment: %zu not aligned by GenAlignment: %zu", - HeapAlignment, GenAlignment); + assert(SpaceAlignment != 0, "Generation alignment not set up properly"); + assert(HeapAlignment >= SpaceAlignment, + "HeapAlignment: %zu less than SpaceAlignment: %zu", + HeapAlignment, SpaceAlignment); + assert(HeapAlignment % SpaceAlignment == 0, + "HeapAlignment: %zu not aligned by SpaceAlignment: %zu", + HeapAlignment, SpaceAlignment); // All generational heaps have a young gen; handle those flags here @@ -106,7 +101,7 @@ void GenArguments::initialize_heap_flags_and_sizes() { // Make sure NewSize allows an old generation to fit even if set on the command line if (FLAG_IS_CMDLINE(NewSize) && NewSize >= InitialHeapSize) { - size_t revised_new_size = bound_minus_alignment(NewSize, InitialHeapSize, GenAlignment); + size_t revised_new_size = bound_minus_alignment(NewSize, InitialHeapSize, SpaceAlignment); log_warning(gc, ergo)("NewSize (%zuk) is equal to or greater than initial heap size (%zuk). A new " "NewSize of %zuk will be used to accomodate an old generation.", NewSize/K, InitialHeapSize/K, revised_new_size/K); @@ -115,8 +110,8 @@ void GenArguments::initialize_heap_flags_and_sizes() { // Now take the actual NewSize into account. We will silently increase NewSize // if the user specified a smaller or unaligned value. - size_t bounded_new_size = bound_minus_alignment(NewSize, MaxHeapSize, GenAlignment); - bounded_new_size = MAX2(smallest_new_size, align_down(bounded_new_size, GenAlignment)); + size_t bounded_new_size = bound_minus_alignment(NewSize, MaxHeapSize, SpaceAlignment); + bounded_new_size = MAX2(smallest_new_size, align_down(bounded_new_size, SpaceAlignment)); if (bounded_new_size != NewSize) { FLAG_SET_ERGO(NewSize, bounded_new_size); } @@ -125,7 +120,7 @@ void GenArguments::initialize_heap_flags_and_sizes() { if (!FLAG_IS_DEFAULT(MaxNewSize)) { if (MaxNewSize >= MaxHeapSize) { // Make sure there is room for an old generation - size_t smaller_max_new_size = MaxHeapSize - GenAlignment; + size_t smaller_max_new_size = MaxHeapSize - SpaceAlignment; if (FLAG_IS_CMDLINE(MaxNewSize)) { log_warning(gc, ergo)("MaxNewSize (%zuk) is equal to or greater than the entire " "heap (%zuk). A new max generation size of %zuk will be used.", @@ -137,8 +132,8 @@ void GenArguments::initialize_heap_flags_and_sizes() { } } else if (MaxNewSize < NewSize) { FLAG_SET_ERGO(MaxNewSize, NewSize); - } else if (!is_aligned(MaxNewSize, GenAlignment)) { - FLAG_SET_ERGO(MaxNewSize, align_down(MaxNewSize, GenAlignment)); + } else if (!is_aligned(MaxNewSize, SpaceAlignment)) { + FLAG_SET_ERGO(MaxNewSize, align_down(MaxNewSize, SpaceAlignment)); } } @@ -166,13 +161,13 @@ void GenArguments::initialize_heap_flags_and_sizes() { // exceed it. Adjust New/OldSize as necessary. size_t calculated_size = NewSize + OldSize; double shrink_factor = (double) MaxHeapSize / calculated_size; - size_t smaller_new_size = align_down((size_t)(NewSize * shrink_factor), GenAlignment); + size_t smaller_new_size = align_down((size_t)(NewSize * shrink_factor), SpaceAlignment); FLAG_SET_ERGO(NewSize, MAX2(young_gen_size_lower_bound(), smaller_new_size)); // OldSize is already aligned because above we aligned MaxHeapSize to // HeapAlignment, and we just made sure that NewSize is aligned to - // GenAlignment. In initialize_flags() we verified that HeapAlignment - // is a multiple of GenAlignment. + // SpaceAlignment. In initialize_flags() we verified that HeapAlignment + // is a multiple of SpaceAlignment. OldSize = MaxHeapSize - NewSize; } else { FLAG_SET_ERGO(MaxHeapSize, align_up(NewSize + OldSize, HeapAlignment)); @@ -200,7 +195,7 @@ void GenArguments::initialize_size_info() { // Determine maximum size of the young generation. if (FLAG_IS_DEFAULT(MaxNewSize)) { - max_young_size = scale_by_NewRatio_aligned(MaxHeapSize, GenAlignment); + max_young_size = scale_by_NewRatio_aligned(MaxHeapSize, SpaceAlignment); // Bound the maximum size by NewSize below (since it historically // would have been NewSize and because the NewRatio calculation could // yield a size that is too small) and bound it by MaxNewSize above. @@ -229,18 +224,18 @@ void GenArguments::initialize_size_info() { // If NewSize is set on the command line, we should use it as // the initial size, but make sure it is within the heap bounds. initial_young_size = - MIN2(max_young_size, bound_minus_alignment(NewSize, InitialHeapSize, GenAlignment)); - MinNewSize = bound_minus_alignment(initial_young_size, MinHeapSize, GenAlignment); + MIN2(max_young_size, bound_minus_alignment(NewSize, InitialHeapSize, SpaceAlignment)); + MinNewSize = bound_minus_alignment(initial_young_size, MinHeapSize, SpaceAlignment); } else { // For the case where NewSize is not set on the command line, use // NewRatio to size the initial generation size. Use the current // NewSize as the floor, because if NewRatio is overly large, the resulting // size can be too small. initial_young_size = - clamp(scale_by_NewRatio_aligned(InitialHeapSize, GenAlignment), NewSize, max_young_size); + clamp(scale_by_NewRatio_aligned(InitialHeapSize, SpaceAlignment), NewSize, max_young_size); // Derive MinNewSize from MinHeapSize - MinNewSize = MIN2(scale_by_NewRatio_aligned(MinHeapSize, GenAlignment), initial_young_size); + MinNewSize = MIN2(scale_by_NewRatio_aligned(MinHeapSize, SpaceAlignment), initial_young_size); } } @@ -252,7 +247,7 @@ void GenArguments::initialize_size_info() { // The maximum old size can be determined from the maximum young // and maximum heap size since no explicit flags exist // for setting the old generation maximum. - MaxOldSize = MAX2(MaxHeapSize - max_young_size, GenAlignment); + MaxOldSize = MAX2(MaxHeapSize - max_young_size, SpaceAlignment); MinOldSize = MIN3(MaxOldSize, InitialHeapSize - initial_young_size, MinHeapSize - MinNewSize); @@ -315,10 +310,10 @@ void GenArguments::assert_flags() { assert(NewSize >= MinNewSize, "Ergonomics decided on a too small young gen size"); assert(NewSize <= MaxNewSize, "Ergonomics decided on incompatible initial and maximum young gen sizes"); assert(FLAG_IS_DEFAULT(MaxNewSize) || MaxNewSize < MaxHeapSize, "Ergonomics decided on incompatible maximum young gen and heap sizes"); - assert(NewSize % GenAlignment == 0, "NewSize alignment"); - assert(FLAG_IS_DEFAULT(MaxNewSize) || MaxNewSize % GenAlignment == 0, "MaxNewSize alignment"); + assert(NewSize % SpaceAlignment == 0, "NewSize alignment"); + assert(FLAG_IS_DEFAULT(MaxNewSize) || MaxNewSize % SpaceAlignment == 0, "MaxNewSize alignment"); assert(OldSize + NewSize <= MaxHeapSize, "Ergonomics decided on incompatible generation and heap sizes"); - assert(OldSize % GenAlignment == 0, "OldSize alignment"); + assert(OldSize % SpaceAlignment == 0, "OldSize alignment"); } void GenArguments::assert_size_info() { @@ -327,19 +322,19 @@ void GenArguments::assert_size_info() { assert(MaxNewSize < MaxHeapSize, "Ergonomics decided on incompatible maximum young and heap sizes"); assert(MinNewSize <= NewSize, "Ergonomics decided on incompatible minimum and initial young gen sizes"); assert(NewSize <= MaxNewSize, "Ergonomics decided on incompatible initial and maximum young gen sizes"); - assert(MinNewSize % GenAlignment == 0, "_min_young_size alignment"); - assert(NewSize % GenAlignment == 0, "_initial_young_size alignment"); - assert(MaxNewSize % GenAlignment == 0, "MaxNewSize alignment"); - assert(MinNewSize <= bound_minus_alignment(MinNewSize, MinHeapSize, GenAlignment), + assert(MinNewSize % SpaceAlignment == 0, "_min_young_size alignment"); + assert(NewSize % SpaceAlignment == 0, "_initial_young_size alignment"); + assert(MaxNewSize % SpaceAlignment == 0, "MaxNewSize alignment"); + assert(MinNewSize <= bound_minus_alignment(MinNewSize, MinHeapSize, SpaceAlignment), "Ergonomics made minimum young generation larger than minimum heap"); - assert(NewSize <= bound_minus_alignment(NewSize, InitialHeapSize, GenAlignment), + assert(NewSize <= bound_minus_alignment(NewSize, InitialHeapSize, SpaceAlignment), "Ergonomics made initial young generation larger than initial heap"); - assert(MaxNewSize <= bound_minus_alignment(MaxNewSize, MaxHeapSize, GenAlignment), + assert(MaxNewSize <= bound_minus_alignment(MaxNewSize, MaxHeapSize, SpaceAlignment), "Ergonomics made maximum young generation lager than maximum heap"); assert(MinOldSize <= OldSize, "Ergonomics decided on incompatible minimum and initial old gen sizes"); assert(OldSize <= MaxOldSize, "Ergonomics decided on incompatible initial and maximum old gen sizes"); - assert(MaxOldSize % GenAlignment == 0, "MaxOldSize alignment"); - assert(OldSize % GenAlignment == 0, "OldSize alignment"); + assert(MaxOldSize % SpaceAlignment == 0, "MaxOldSize alignment"); + assert(OldSize % SpaceAlignment == 0, "OldSize alignment"); assert(MaxHeapSize <= (MaxNewSize + MaxOldSize), "Total maximum heap sizes must be sum of generation maximum sizes"); assert(MinNewSize + MinOldSize <= MinHeapSize, "Minimum generation sizes exceed minimum heap size"); assert(NewSize + OldSize == InitialHeapSize, "Initial generation sizes should match initial heap size"); diff --git a/src/hotspot/share/gc/shared/genArguments.hpp b/src/hotspot/share/gc/shared/genArguments.hpp index ae20c6126fc..80133bd1ec1 100644 --- a/src/hotspot/share/gc/shared/genArguments.hpp +++ b/src/hotspot/share/gc/shared/genArguments.hpp @@ -35,8 +35,6 @@ extern size_t MaxOldSize; extern size_t OldSize; -extern size_t GenAlignment; - class GenArguments : public GCArguments { friend class TestGenCollectorPolicy; // Testing private: diff --git a/src/hotspot/share/gc/z/zAllocator.cpp b/src/hotspot/share/gc/z/zAllocator.cpp index 22f3b6ba112..dd1ab3b712a 100644 --- a/src/hotspot/share/gc/z/zAllocator.cpp +++ b/src/hotspot/share/gc/z/zAllocator.cpp @@ -23,6 +23,7 @@ #include "gc/z/zAllocator.hpp" #include "gc/z/zObjectAllocator.hpp" +#include "gc/z/zPageAge.inline.hpp" ZAllocatorEden* ZAllocator::_eden; ZAllocatorForRelocation* ZAllocator::_relocation[ZAllocator::_relocation_allocators]; @@ -47,7 +48,7 @@ ZPageAge ZAllocatorForRelocation::install() { for (uint i = 0; i < ZAllocator::_relocation_allocators; ++i) { if (_relocation[i] == nullptr) { _relocation[i] = this; - return static_cast(i + 1); + return to_zpageage(i + 1); } } diff --git a/src/hotspot/share/gc/z/zAllocator.hpp b/src/hotspot/share/gc/z/zAllocator.hpp index 45a70888f9d..ec4c0ec1c9c 100644 --- a/src/hotspot/share/gc/z/zAllocator.hpp +++ b/src/hotspot/share/gc/z/zAllocator.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -35,7 +35,7 @@ class ZPage; class ZAllocator { public: - static constexpr uint _relocation_allocators = static_cast(ZPageAge::old); + static constexpr uint _relocation_allocators = ZPageAgeCount - 1; protected: ZObjectAllocator _object_allocator; diff --git a/src/hotspot/share/gc/z/zAllocator.inline.hpp b/src/hotspot/share/gc/z/zAllocator.inline.hpp index ba558a1b0f3..ec64676dbf0 100644 --- a/src/hotspot/share/gc/z/zAllocator.inline.hpp +++ b/src/hotspot/share/gc/z/zAllocator.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -28,13 +28,14 @@ #include "gc/z/zAddress.inline.hpp" #include "gc/z/zHeap.hpp" +#include "gc/z/zPageAge.inline.hpp" inline ZAllocatorEden* ZAllocator::eden() { return _eden; } inline ZAllocatorForRelocation* ZAllocator::relocation(ZPageAge page_age) { - return _relocation[static_cast(page_age) - 1]; + return _relocation[untype(page_age - 1)]; } inline ZAllocatorForRelocation* ZAllocator::old() { diff --git a/src/hotspot/share/gc/z/zGeneration.cpp b/src/hotspot/share/gc/z/zGeneration.cpp index 772c5a0a98b..534f0195c90 100644 --- a/src/hotspot/share/gc/z/zGeneration.cpp +++ b/src/hotspot/share/gc/z/zGeneration.cpp @@ -41,6 +41,7 @@ #include "gc/z/zHeap.inline.hpp" #include "gc/z/zJNICritical.hpp" #include "gc/z/zMark.inline.hpp" +#include "gc/z/zPageAge.inline.hpp" #include "gc/z/zPageAllocator.hpp" #include "gc/z/zRelocationSet.inline.hpp" #include "gc/z/zRelocationSetSelector.inline.hpp" @@ -699,11 +700,10 @@ uint ZGenerationYoung::compute_tenuring_threshold(ZRelocationSetSelectorStats st uint last_populated_age = 0; size_t last_populated_live = 0; - for (uint i = 0; i <= ZPageAgeMax; ++i) { - const ZPageAge age = static_cast(i); + for (ZPageAge age : ZPageAgeRange()) { const size_t young_live = stats.small(age).live() + stats.medium(age).live() + stats.large(age).live(); if (young_live > 0) { - last_populated_age = i; + last_populated_age = untype(age); last_populated_live = young_live; if (young_live_last > 0) { young_life_expectancy_sum += double(young_live) / double(young_live_last); @@ -842,8 +842,8 @@ void ZGenerationYoung::mark_start() { // Retire allocating pages ZAllocator::eden()->retire_pages(); - for (ZPageAge i = ZPageAge::survivor1; i <= ZPageAge::survivor14; i = static_cast(static_cast(i) + 1)) { - ZAllocator::relocation(i)->retire_pages(); + for (ZPageAge age : ZPageAgeRangeSurvivor) { + ZAllocator::relocation(age)->retire_pages(); } // Reset allocated/reclaimed/used statistics diff --git a/src/hotspot/share/gc/z/zPageAge.hpp b/src/hotspot/share/gc/z/zPageAge.hpp index b7b1688b830..3209790c008 100644 --- a/src/hotspot/share/gc/z/zPageAge.hpp +++ b/src/hotspot/share/gc/z/zPageAge.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -24,6 +24,7 @@ #ifndef SHARE_GC_Z_ZPAGEAGE_HPP #define SHARE_GC_Z_ZPAGEAGE_HPP +#include "utilities/enumIterator.hpp" #include "utilities/globalDefinitions.hpp" enum class ZPageAge : uint8_t { @@ -45,6 +46,19 @@ enum class ZPageAge : uint8_t { old }; -constexpr uint ZPageAgeMax = static_cast(ZPageAge::old); +constexpr uint ZPageAgeCount = static_cast(ZPageAge::old) + 1; +constexpr ZPageAge ZPageAgeLastPlusOne = static_cast(ZPageAgeCount); + +ENUMERATOR_RANGE(ZPageAge, + ZPageAge::eden, + ZPageAge::old); + +using ZPageAgeRange = EnumRange; + +constexpr ZPageAgeRange ZPageAgeRangeEden = ZPageAgeRange::create(); +constexpr ZPageAgeRange ZPageAgeRangeYoung = ZPageAgeRange::create(); +constexpr ZPageAgeRange ZPageAgeRangeSurvivor = ZPageAgeRange::create(); +constexpr ZPageAgeRange ZPageAgeRangeRelocation = ZPageAgeRange::create(); +constexpr ZPageAgeRange ZPageAgeRangeOld = ZPageAgeRange::create(); #endif // SHARE_GC_Z_ZPAGEAGE_HPP diff --git a/src/java.base/share/classes/jdk/internal/access/JavaAWTAccess.java b/src/hotspot/share/gc/z/zPageAge.inline.hpp similarity index 51% rename from src/java.base/share/classes/jdk/internal/access/JavaAWTAccess.java rename to src/hotspot/share/gc/z/zPageAge.inline.hpp index a4c170ca918..0944caa69a6 100644 --- a/src/java.base/share/classes/jdk/internal/access/JavaAWTAccess.java +++ b/src/hotspot/share/gc/z/zPageAge.inline.hpp @@ -1,12 +1,10 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 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 * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. + * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or @@ -23,14 +21,32 @@ * questions. */ -package jdk.internal.access; +#ifndef SHARE_GC_Z_ZPAGEAGE_INLINE_HPP +#define SHARE_GC_Z_ZPAGEAGE_INLINE_HPP -public interface JavaAWTAccess { +#include "gc/z/zPageAge.hpp" - // Returns the AppContext used for applet logging isolation, or null if - // no isolation is required. - // If there's no applet, or if the caller is a stand alone application, - // or running in the main app context, returns null. - // Otherwise, returns the AppContext of the calling applet. - public Object getAppletContext(); +#include "utilities/checkedCast.hpp" + +#include + +inline uint untype(ZPageAge age) { + return static_cast(age); } + +inline ZPageAge to_zpageage(uint age) { + assert(age < ZPageAgeCount, "Invalid age"); + return static_cast(age); +} + +inline ZPageAge operator+(ZPageAge age, size_t size) { + const auto size_value = checked_cast>(size); + return to_zpageage(untype(age) + size_value); +} + +inline ZPageAge operator-(ZPageAge age, size_t size) { + const auto size_value = checked_cast>(size); + return to_zpageage(untype(age) - size_value); +} + +#endif // SHARE_GC_Z_ZPAGEAGE_INLINE_HPP diff --git a/src/hotspot/share/gc/z/zRelocate.cpp b/src/hotspot/share/gc/z/zRelocate.cpp index df2dd8a01cb..b45d8b70e72 100644 --- a/src/hotspot/share/gc/z/zRelocate.cpp +++ b/src/hotspot/share/gc/z/zRelocate.cpp @@ -488,11 +488,11 @@ public: } ZPage* shared(ZPageAge age) { - return _shared[static_cast(age) - 1]; + return _shared[untype(age - 1)]; } void set_shared(ZPageAge age, ZPage* page) { - _shared[static_cast(age) - 1] = page; + _shared[untype(age - 1)] = page; } ZPage* alloc_and_retire_target_page(ZForwarding* forwarding, ZPage* target) { @@ -570,11 +570,11 @@ private: ZPage* target(ZPageAge age) { - return _target[static_cast(age) - 1]; + return _target[untype(age - 1)]; } void set_target(ZPageAge age, ZPage* page) { - _target[static_cast(age) - 1] = page; + _target[untype(age - 1)] = page; } size_t object_alignment() const { @@ -1232,12 +1232,12 @@ ZPageAge ZRelocate::compute_to_age(ZPageAge from_age) { return ZPageAge::old; } - const uint age = static_cast(from_age); + const uint age = untype(from_age); if (age >= ZGeneration::young()->tenuring_threshold()) { return ZPageAge::old; } - return static_cast(age + 1); + return to_zpageage(age + 1); } class ZFlipAgePagesTask : public ZTask { diff --git a/src/hotspot/share/gc/z/zRelocationSetSelector.cpp b/src/hotspot/share/gc/z/zRelocationSetSelector.cpp index e9ef66a19dc..aac4fd51271 100644 --- a/src/hotspot/share/gc/z/zRelocationSetSelector.cpp +++ b/src/hotspot/share/gc/z/zRelocationSetSelector.cpp @@ -25,6 +25,7 @@ #include "gc/z/zArray.inline.hpp" #include "gc/z/zForwarding.inline.hpp" #include "gc/z/zPage.inline.hpp" +#include "gc/z/zPageAge.inline.hpp" #include "gc/z/zRelocationSetSelector.inline.hpp" #include "jfr/jfrEvents.hpp" #include "logging/log.hpp" @@ -117,8 +118,8 @@ void ZRelocationSetSelectorGroup::select_inner() { const int npages = _live_pages.length(); int selected_from = 0; int selected_to = 0; - size_t npages_selected[ZPageAgeMax + 1] = { 0 }; - size_t selected_live_bytes[ZPageAgeMax + 1] = { 0 }; + size_t npages_selected[ZPageAgeCount] = { 0 }; + size_t selected_live_bytes[ZPageAgeCount] = { 0 }; size_t selected_forwarding_entries = 0; size_t from_live_bytes = 0; @@ -149,8 +150,8 @@ void ZRelocationSetSelectorGroup::select_inner() { if (diff_reclaimable > _fragmentation_limit) { selected_from = from; selected_to = to; - selected_live_bytes[static_cast(page->age())] += page_live_bytes; - npages_selected[static_cast(page->age())] += 1; + selected_live_bytes[untype(page->age())] += page_live_bytes; + npages_selected[untype(page->age())] += 1; selected_forwarding_entries = from_forwarding_entries; } @@ -172,7 +173,7 @@ void ZRelocationSetSelectorGroup::select_inner() { _forwarding_entries = selected_forwarding_entries; // Update statistics - for (uint i = 0; i <= ZPageAgeMax; ++i) { + for (uint i = 0; i < ZPageAgeCount; ++i) { _stats[i]._relocate = selected_live_bytes[i]; _stats[i]._npages_selected = npages_selected[i]; } @@ -200,7 +201,7 @@ void ZRelocationSetSelectorGroup::select() { } ZRelocationSetSelectorGroupStats s{}; - for (uint i = 0; i <= ZPageAgeMax; ++i) { + for (uint i = 0; i < ZPageAgeCount; ++i) { s._npages_candidates += _stats[i].npages_candidates(); s._total += _stats[i].total(); s._empty += _stats[i].empty(); @@ -239,8 +240,8 @@ void ZRelocationSetSelector::select() { ZRelocationSetSelectorStats ZRelocationSetSelector::stats() const { ZRelocationSetSelectorStats stats; - for (uint i = 0; i <= ZPageAgeMax; ++i) { - const ZPageAge age = static_cast(i); + for (ZPageAge age : ZPageAgeRange()) { + const uint i = untype(age); stats._small[i] = _small.stats(age); stats._medium[i] = _medium.stats(age); stats._large[i] = _large.stats(age); diff --git a/src/hotspot/share/gc/z/zRelocationSetSelector.hpp b/src/hotspot/share/gc/z/zRelocationSetSelector.hpp index b6ec2347153..21772405f25 100644 --- a/src/hotspot/share/gc/z/zRelocationSetSelector.hpp +++ b/src/hotspot/share/gc/z/zRelocationSetSelector.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -62,9 +62,9 @@ class ZRelocationSetSelectorStats { friend class ZRelocationSetSelector; private: - ZRelocationSetSelectorGroupStats _small[ZPageAgeMax + 1]; - ZRelocationSetSelectorGroupStats _medium[ZPageAgeMax + 1]; - ZRelocationSetSelectorGroupStats _large[ZPageAgeMax + 1]; + ZRelocationSetSelectorGroupStats _small[ZPageAgeCount]; + ZRelocationSetSelectorGroupStats _medium[ZPageAgeCount]; + ZRelocationSetSelectorGroupStats _large[ZPageAgeCount]; size_t _has_relocatable_pages; @@ -90,7 +90,7 @@ private: ZArray _live_pages; ZArray _not_selected_pages; size_t _forwarding_entries; - ZRelocationSetSelectorGroupStats _stats[ZPageAgeMax + 1]; + ZRelocationSetSelectorGroupStats _stats[ZPageAgeCount]; bool is_disabled(); bool is_selectable(); diff --git a/src/hotspot/share/gc/z/zRelocationSetSelector.inline.hpp b/src/hotspot/share/gc/z/zRelocationSetSelector.inline.hpp index 7cd0a005aac..7740e0764a6 100644 --- a/src/hotspot/share/gc/z/zRelocationSetSelector.inline.hpp +++ b/src/hotspot/share/gc/z/zRelocationSetSelector.inline.hpp @@ -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 @@ -29,6 +29,7 @@ #include "gc/z/zArray.inline.hpp" #include "gc/z/zGlobals.hpp" #include "gc/z/zPage.inline.hpp" +#include "gc/z/zPageAge.inline.hpp" #include "utilities/powerOfTwo.hpp" inline size_t ZRelocationSetSelectorGroupStats::npages_candidates() const { @@ -60,15 +61,15 @@ inline bool ZRelocationSetSelectorStats::has_relocatable_pages() const { } inline const ZRelocationSetSelectorGroupStats& ZRelocationSetSelectorStats::small(ZPageAge age) const { - return _small[static_cast(age)]; + return _small[untype(age)]; } inline const ZRelocationSetSelectorGroupStats& ZRelocationSetSelectorStats::medium(ZPageAge age) const { - return _medium[static_cast(age)]; + return _medium[untype(age)]; } inline const ZRelocationSetSelectorGroupStats& ZRelocationSetSelectorStats::large(ZPageAge age) const { - return _large[static_cast(age)]; + return _large[untype(age)]; } inline bool ZRelocationSetSelectorGroup::pre_filter_page(const ZPage* page, size_t live_bytes) const { @@ -113,7 +114,7 @@ inline void ZRelocationSetSelectorGroup::register_live_page(ZPage* page) { } const size_t size = page->size(); - const uint age = static_cast(page->age()); + const uint age = untype(page->age()); _stats[age]._npages_candidates++; _stats[age]._total += size; _stats[age]._live += live; @@ -122,7 +123,7 @@ inline void ZRelocationSetSelectorGroup::register_live_page(ZPage* page) { inline void ZRelocationSetSelectorGroup::register_empty_page(ZPage* page) { const size_t size = page->size(); - const uint age = static_cast(page->age()); + const uint age = untype(page->age()); _stats[age]._npages_candidates++; _stats[age]._total += size; _stats[age]._empty += size; @@ -141,7 +142,7 @@ inline size_t ZRelocationSetSelectorGroup::forwarding_entries() const { } inline const ZRelocationSetSelectorGroupStats& ZRelocationSetSelectorGroup::stats(ZPageAge age) const { - return _stats[static_cast(age)]; + return _stats[untype(age)]; } inline void ZRelocationSetSelector::register_live_page(ZPage* page) { @@ -188,8 +189,7 @@ inline void ZRelocationSetSelector::clear_empty_pages() { inline size_t ZRelocationSetSelector::total() const { size_t sum = 0; - for (uint i = 0; i <= ZPageAgeMax; ++i) { - const ZPageAge age = static_cast(i); + for (ZPageAge age : ZPageAgeRange()) { sum += _small.stats(age).total() + _medium.stats(age).total() + _large.stats(age).total(); } return sum; @@ -197,8 +197,7 @@ inline size_t ZRelocationSetSelector::total() const { inline size_t ZRelocationSetSelector::empty() const { size_t sum = 0; - for (uint i = 0; i <= ZPageAgeMax; ++i) { - const ZPageAge age = static_cast(i); + for (ZPageAge age : ZPageAgeRange()) { sum += _small.stats(age).empty() + _medium.stats(age).empty() + _large.stats(age).empty(); } return sum; @@ -206,8 +205,7 @@ inline size_t ZRelocationSetSelector::empty() const { inline size_t ZRelocationSetSelector::relocate() const { size_t sum = 0; - for (uint i = 0; i <= ZPageAgeMax; ++i) { - const ZPageAge age = static_cast(i); + for (ZPageAge age : ZPageAgeRange()) { sum += _small.stats(age).relocate() + _medium.stats(age).relocate() + _large.stats(age).relocate(); } return sum; diff --git a/src/hotspot/share/gc/z/zStat.cpp b/src/hotspot/share/gc/z/zStat.cpp index ec751cbb693..bfde904c1e7 100644 --- a/src/hotspot/share/gc/z/zStat.cpp +++ b/src/hotspot/share/gc/z/zStat.cpp @@ -30,6 +30,7 @@ #include "gc/z/zGeneration.inline.hpp" #include "gc/z/zGlobals.hpp" #include "gc/z/zNMethodTable.hpp" +#include "gc/z/zPageAge.inline.hpp" #include "gc/z/zPageAllocator.inline.hpp" #include "gc/z/zRelocationSetSelector.inline.hpp" #include "gc/z/zStat.hpp" @@ -1499,9 +1500,7 @@ void ZStatRelocation::print_page_summary() { summary.relocate += stats.relocate(); }; - for (uint i = 0; i <= ZPageAgeMax; ++i) { - const ZPageAge age = static_cast(i); - + for (ZPageAge age : ZPageAgeRange()) { account_page_size(small_summary, _selector_stats.small(age)); account_page_size(medium_summary, _selector_stats.medium(age)); account_page_size(large_summary, _selector_stats.large(age)); @@ -1557,13 +1556,13 @@ void ZStatRelocation::print_age_table() { .center("Large") .end()); - size_t live[ZPageAgeMax + 1] = {}; - size_t total[ZPageAgeMax + 1] = {}; + size_t live[ZPageAgeCount] = {}; + size_t total[ZPageAgeCount] = {}; uint oldest_none_empty_age = 0; - for (uint i = 0; i <= ZPageAgeMax; ++i) { - ZPageAge age = static_cast(i); + for (ZPageAge age : ZPageAgeRange()) { + uint i = untype(age); auto summarize_pages = [&](const ZRelocationSetSelectorGroupStats& stats) { live[i] += stats.live(); total[i] += stats.total(); @@ -1579,7 +1578,7 @@ void ZStatRelocation::print_age_table() { } for (uint i = 0; i <= oldest_none_empty_age; ++i) { - ZPageAge age = static_cast(i); + ZPageAge age = to_zpageage(i); FormatBuffer<> age_str(""); if (age == ZPageAge::eden) { @@ -1791,8 +1790,7 @@ void ZStatHeap::at_select_relocation_set(const ZRelocationSetSelectorStats& stat ZLocker locker(&_stat_lock); size_t live = 0; - for (uint i = 0; i <= ZPageAgeMax; ++i) { - const ZPageAge age = static_cast(i); + for (ZPageAge age : ZPageAgeRange()) { live += stats.small(age).live() + stats.medium(age).live() + stats.large(age).live(); } _at_mark_end.live = live; diff --git a/src/hotspot/share/gc/z/z_globals.hpp b/src/hotspot/share/gc/z/z_globals.hpp index e1f525e5372..d818cf9fc3f 100644 --- a/src/hotspot/share/gc/z/z_globals.hpp +++ b/src/hotspot/share/gc/z/z_globals.hpp @@ -113,7 +113,7 @@ \ product(int, ZTenuringThreshold, -1, DIAGNOSTIC, \ "Young generation tenuring threshold, -1 for dynamic computation")\ - range(-1, static_cast(ZPageAgeMax)) \ + range(-1, static_cast(ZPageAgeCount) - 1) \ \ develop(bool, ZVerifyOops, false, \ "Verify accessed oops") \ diff --git a/src/hotspot/share/jvmci/jvmciEnv.cpp b/src/hotspot/share/jvmci/jvmciEnv.cpp index 8c9facf8489..851ead247f1 100644 --- a/src/hotspot/share/jvmci/jvmciEnv.cpp +++ b/src/hotspot/share/jvmci/jvmciEnv.cpp @@ -1463,8 +1463,7 @@ JVMCIPrimitiveArray JVMCIEnv::new_byteArray(int length, JVMCI_TRAPS) { JVMCIObjectArray JVMCIEnv::new_byte_array_array(int length, JVMCI_TRAPS) { JavaThread* THREAD = JavaThread::current(); // For exception macros. if (is_hotspot()) { - Klass* byteArrayArrayKlass = TypeArrayKlass::cast(Universe::byteArrayKlass())->array_klass(CHECK_(JVMCIObject())); - objArrayOop result = ObjArrayKlass::cast(byteArrayArrayKlass) ->allocate(length, CHECK_(JVMCIObject())); + objArrayOop result = oopFactory::new_objArray(Universe::byteArrayKlass(), length, CHECK_(JVMCIObject())); return wrap(result); } else { JNIAccessMark jni(this, THREAD); diff --git a/src/hotspot/share/memory/heap.cpp b/src/hotspot/share/memory/heap.cpp index bcb9d2e6114..b111c61f15a 100644 --- a/src/hotspot/share/memory/heap.cpp +++ b/src/hotspot/share/memory/heap.cpp @@ -189,14 +189,6 @@ static size_t align_to_page_size(size_t size) { } -void CodeHeap::on_code_mapping(char* base, size_t size) { -#ifdef LINUX - extern void linux_wrap_code(char* base, size_t size); - linux_wrap_code(base, size); -#endif -} - - bool CodeHeap::reserve(ReservedSpace rs, size_t committed_size, size_t segment_size) { assert(rs.size() >= committed_size, "reserved < committed"); assert(is_aligned(committed_size, rs.page_size()), "must be page aligned"); @@ -213,7 +205,6 @@ bool CodeHeap::reserve(ReservedSpace rs, size_t committed_size, size_t segment_s return false; } - on_code_mapping(_memory.low(), _memory.committed_size()); _number_of_committed_segments = size_to_segments(_memory.committed_size()); _number_of_reserved_segments = size_to_segments(_memory.reserved_size()); assert(_number_of_reserved_segments >= _number_of_committed_segments, "just checking"); @@ -250,7 +241,6 @@ bool CodeHeap::expand_by(size_t size) { } char* base = _memory.low() + _memory.committed_size(); if (!_memory.expand_by(dm)) return false; - on_code_mapping(base, dm); size_t i = _number_of_committed_segments; _number_of_committed_segments = size_to_segments(_memory.committed_size()); assert(_number_of_reserved_segments == size_to_segments(_memory.reserved_size()), "number of reserved segments should not change"); diff --git a/src/hotspot/share/memory/heap.hpp b/src/hotspot/share/memory/heap.hpp index e54f99c8c54..d0e4230fe2b 100644 --- a/src/hotspot/share/memory/heap.hpp +++ b/src/hotspot/share/memory/heap.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -146,9 +146,6 @@ class CodeHeap : public CHeapObj { void* next_used(HeapBlock* b) const; HeapBlock* block_start(void* p) const; - // to perform additional actions on creation of executable code - void on_code_mapping(char* base, size_t size); - public: CodeHeap(const char* name, const CodeBlobType code_blob_type); diff --git a/src/hotspot/share/memory/oopFactory.cpp b/src/hotspot/share/memory/oopFactory.cpp index 949b4fe134b..b2a468d3a23 100644 --- a/src/hotspot/share/memory/oopFactory.cpp +++ b/src/hotspot/share/memory/oopFactory.cpp @@ -40,41 +40,41 @@ #include "utilities/utf8.hpp" typeArrayOop oopFactory::new_boolArray(int length, TRAPS) { - return Universe::boolArrayKlass()->allocate(length, THREAD); + return Universe::boolArrayKlass()->allocate_instance(length, THREAD); } typeArrayOop oopFactory::new_charArray(int length, TRAPS) { - return Universe::charArrayKlass()->allocate(length, THREAD); + return Universe::charArrayKlass()->allocate_instance(length, THREAD); } typeArrayOop oopFactory::new_floatArray(int length, TRAPS) { - return Universe::floatArrayKlass()->allocate(length, THREAD); + return Universe::floatArrayKlass()->allocate_instance(length, THREAD); } typeArrayOop oopFactory::new_doubleArray(int length, TRAPS) { - return Universe::doubleArrayKlass()->allocate(length, THREAD); + return Universe::doubleArrayKlass()->allocate_instance(length, THREAD); } typeArrayOop oopFactory::new_byteArray(int length, TRAPS) { - return Universe::byteArrayKlass()->allocate(length, THREAD); + return Universe::byteArrayKlass()->allocate_instance(length, THREAD); } typeArrayOop oopFactory::new_shortArray(int length, TRAPS) { - return Universe::shortArrayKlass()->allocate(length, THREAD); + return Universe::shortArrayKlass()->allocate_instance(length, THREAD); } typeArrayOop oopFactory::new_intArray(int length, TRAPS) { - return Universe::intArrayKlass()->allocate(length, THREAD); + return Universe::intArrayKlass()->allocate_instance(length, THREAD); } typeArrayOop oopFactory::new_longArray(int length, TRAPS) { - return Universe::longArrayKlass()->allocate(length, THREAD); + return Universe::longArrayKlass()->allocate_instance(length, THREAD); } // create java.lang.Object[] objArrayOop oopFactory::new_objectArray(int length, TRAPS) { assert(Universe::objectArrayKlass() != nullptr, "Too early?"); - return Universe::objectArrayKlass()->allocate(length, THREAD); + return Universe::objectArrayKlass()->allocate_instance(length, THREAD); } typeArrayOop oopFactory::new_charArray(const char* utf8_str, TRAPS) { @@ -88,7 +88,7 @@ typeArrayOop oopFactory::new_charArray(const char* utf8_str, TRAPS) { typeArrayOop oopFactory::new_typeArray(BasicType type, int length, TRAPS) { TypeArrayKlass* klass = Universe::typeArrayKlass(type); - return klass->allocate(length, THREAD); + return klass->allocate_instance(length, THREAD); } // Create a Java array that points to Symbol. diff --git a/src/hotspot/share/oops/objArrayKlass.cpp b/src/hotspot/share/oops/objArrayKlass.cpp index 7af6b963052..e1fcc25f150 100644 --- a/src/hotspot/share/oops/objArrayKlass.cpp +++ b/src/hotspot/share/oops/objArrayKlass.cpp @@ -44,7 +44,7 @@ #include "runtime/mutexLocker.hpp" #include "utilities/macros.hpp" -ObjArrayKlass* ObjArrayKlass::allocate(ClassLoaderData* loader_data, int n, Klass* k, Symbol* name, TRAPS) { +ObjArrayKlass* ObjArrayKlass::allocate_klass(ClassLoaderData* loader_data, int n, Klass* k, Symbol* name, TRAPS) { assert(ObjArrayKlass::header_size() <= InstanceKlass::header_size(), "array klasses must be same size as InstanceKlass"); @@ -100,7 +100,7 @@ ObjArrayKlass* ObjArrayKlass::allocate_objArray_klass(ClassLoaderData* loader_da } // Initialize instance variables - ObjArrayKlass* oak = ObjArrayKlass::allocate(loader_data, n, element_klass, name, CHECK_NULL); + ObjArrayKlass* oak = ObjArrayKlass::allocate_klass(loader_data, n, element_klass, name, CHECK_NULL); ModuleEntry* module = oak->module(); assert(module != nullptr, "No module entry for array"); @@ -149,7 +149,7 @@ size_t ObjArrayKlass::oop_size(oop obj) const { return objArrayOop(obj)->object_size(); } -objArrayOop ObjArrayKlass::allocate(int length, TRAPS) { +objArrayOop ObjArrayKlass::allocate_instance(int length, TRAPS) { check_array_allocation_length(length, arrayOopDesc::max_array_length(T_OBJECT), CHECK_NULL); size_t size = objArrayOopDesc::object_size(length); return (objArrayOop)Universe::heap()->array_allocate(this, size, length, @@ -160,7 +160,7 @@ oop ObjArrayKlass::multi_allocate(int rank, jint* sizes, TRAPS) { int length = *sizes; ArrayKlass* ld_klass = lower_dimension(); // If length < 0 allocate will throw an exception. - objArrayOop array = allocate(length, CHECK_NULL); + objArrayOop array = allocate_instance(length, CHECK_NULL); objArrayHandle h_array (THREAD, array); if (rank > 1) { if (length != 0) { diff --git a/src/hotspot/share/oops/objArrayKlass.hpp b/src/hotspot/share/oops/objArrayKlass.hpp index c44c8d28f62..11fe4f2a521 100644 --- a/src/hotspot/share/oops/objArrayKlass.hpp +++ b/src/hotspot/share/oops/objArrayKlass.hpp @@ -33,8 +33,10 @@ class ClassLoaderData; // ObjArrayKlass is the klass for objArrays class ObjArrayKlass : public ArrayKlass { - friend class VMStructs; + friend class Deoptimization; friend class JVMCIVMStructs; + friend class oopFactory; + friend class VMStructs; public: static const KlassKind Kind = ObjArrayKlassKind; @@ -47,7 +49,9 @@ class ObjArrayKlass : public ArrayKlass { // Constructor ObjArrayKlass(int n, Klass* element_klass, Symbol* name); - static ObjArrayKlass* allocate(ClassLoaderData* loader_data, int n, Klass* k, Symbol* name, TRAPS); + static ObjArrayKlass* allocate_klass(ClassLoaderData* loader_data, int n, Klass* k, Symbol* name, TRAPS); + + objArrayOop allocate_instance(int length, TRAPS); public: // For dummy objects ObjArrayKlass() {} @@ -78,7 +82,6 @@ class ObjArrayKlass : public ArrayKlass { static ObjArrayKlass* allocate_objArray_klass(ClassLoaderData* loader_data, int n, Klass* element_klass, TRAPS); - objArrayOop allocate(int length, TRAPS); oop multi_allocate(int rank, jint* sizes, TRAPS); // Copying diff --git a/src/hotspot/share/oops/typeArrayKlass.cpp b/src/hotspot/share/oops/typeArrayKlass.cpp index 39385bb0184..bdf37c7db49 100644 --- a/src/hotspot/share/oops/typeArrayKlass.cpp +++ b/src/hotspot/share/oops/typeArrayKlass.cpp @@ -50,7 +50,7 @@ TypeArrayKlass* TypeArrayKlass::create_klass(BasicType type, ClassLoaderData* null_loader_data = ClassLoaderData::the_null_class_loader_data(); - TypeArrayKlass* ak = TypeArrayKlass::allocate(null_loader_data, type, sym, CHECK_NULL); + TypeArrayKlass* ak = TypeArrayKlass::allocate_klass(null_loader_data, type, sym, CHECK_NULL); // Call complete_create_array_klass after all instance variables have been initialized. complete_create_array_klass(ak, ak->super(), ModuleEntryTable::javabase_moduleEntry(), CHECK_NULL); @@ -65,7 +65,7 @@ TypeArrayKlass* TypeArrayKlass::create_klass(BasicType type, return ak; } -TypeArrayKlass* TypeArrayKlass::allocate(ClassLoaderData* loader_data, BasicType type, Symbol* name, TRAPS) { +TypeArrayKlass* TypeArrayKlass::allocate_klass(ClassLoaderData* loader_data, BasicType type, Symbol* name, TRAPS) { assert(TypeArrayKlass::header_size() <= InstanceKlass::header_size(), "array klasses must be same size as InstanceKlass"); @@ -101,7 +101,7 @@ oop TypeArrayKlass::multi_allocate(int rank, jint* last_size, TRAPS) { // For typeArrays this is only called for the last dimension assert(rank == 1, "just checking"); int length = *last_size; - return allocate(length, THREAD); + return allocate_instance(length, THREAD); } diff --git a/src/hotspot/share/oops/typeArrayKlass.hpp b/src/hotspot/share/oops/typeArrayKlass.hpp index fa4e301e3e4..22600702fe2 100644 --- a/src/hotspot/share/oops/typeArrayKlass.hpp +++ b/src/hotspot/share/oops/typeArrayKlass.hpp @@ -33,6 +33,8 @@ class ClassLoaderData; // It contains the type and size of the elements class TypeArrayKlass : public ArrayKlass { + friend class Deoptimization; + friend class oopFactory; friend class VMStructs; public: @@ -43,7 +45,10 @@ class TypeArrayKlass : public ArrayKlass { // Constructor TypeArrayKlass(BasicType type, Symbol* name); - static TypeArrayKlass* allocate(ClassLoaderData* loader_data, BasicType type, Symbol* name, TRAPS); + static TypeArrayKlass* allocate_klass(ClassLoaderData* loader_data, BasicType type, Symbol* name, TRAPS); + + typeArrayOop allocate_common(int length, bool do_zero, TRAPS); + typeArrayOop allocate_instance(int length, TRAPS) { return allocate_common(length, true, THREAD); } public: TypeArrayKlass() {} // For dummy objects. @@ -66,8 +71,6 @@ class TypeArrayKlass : public ArrayKlass { size_t oop_size(oop obj) const; // Allocation - typeArrayOop allocate_common(int length, bool do_zero, TRAPS); - typeArrayOop allocate(int length, TRAPS) { return allocate_common(length, true, THREAD); } oop multi_allocate(int rank, jint* sizes, TRAPS); oop protection_domain() const { return nullptr; } diff --git a/src/hotspot/share/opto/block.hpp b/src/hotspot/share/opto/block.hpp index c5a3a589407..e6a98c28e77 100644 --- a/src/hotspot/share/opto/block.hpp +++ b/src/hotspot/share/opto/block.hpp @@ -464,6 +464,14 @@ class PhaseCFG : public Phase { Node* catch_cleanup_find_cloned_def(Block* use_blk, Node* def, Block* def_blk, int n_clone_idx); void catch_cleanup_inter_block(Node *use, Block *use_blk, Node *def, Block *def_blk, int n_clone_idx); + // Ensure that n happens at b or above, i.e. at a block that dominates b. + // We expect n to be an orphan node without further inputs. + void ensure_node_is_at_block_or_above(Node* n, Block* b); + + // Move node n from its current placement into the end of block b. + // Move also outgoing Mach projections. + void move_node_and_its_projections_to_block(Node* n, Block* b); + // Detect implicit-null-check opportunities. Basically, find null checks // with suitable memory ops nearby. Use the memory op to do the null check. // I can generate a memory op if there is not one nearby. diff --git a/src/hotspot/share/opto/idealGraphPrinter.cpp b/src/hotspot/share/opto/idealGraphPrinter.cpp index 3721394c112..1ecb46eaf5a 100644 --- a/src/hotspot/share/opto/idealGraphPrinter.cpp +++ b/src/hotspot/share/opto/idealGraphPrinter.cpp @@ -155,7 +155,6 @@ void IdealGraphPrinter::init(const char* file_name, bool use_multiple_files, boo // in the mach where kill projections have no users but should // appear in the dump. _traverse_outs = true; - _should_send_method = true; _output = nullptr; buffer[0] = 0; _depth = 0; @@ -300,13 +299,11 @@ void IdealGraphPrinter::print_inline_tree(InlineTree *tree) { void IdealGraphPrinter::print_inlining() { // Print inline tree - if (_should_send_method) { - InlineTree *inlineTree = C->ilt(); - if (inlineTree != nullptr) { - print_inline_tree(inlineTree); - } else { - // print this method only - } + InlineTree *inlineTree = C->ilt(); + if (inlineTree != nullptr) { + print_inline_tree(inlineTree); + } else { + // print this method only } } @@ -382,7 +379,6 @@ void IdealGraphPrinter::begin_method() { tail(PROPERTIES_ELEMENT); - _should_send_method = true; this->_current_method = method; _xml->flush(); @@ -975,7 +971,7 @@ void IdealGraphPrinter::print_graph(const char* name, const frame* fr) { // Print current ideal graph void IdealGraphPrinter::print(const char* name, Node* node, GrowableArray& visible_nodes, const frame* fr) { - if (!_current_method || !_should_send_method || node == nullptr) return; + if (!_current_method || node == nullptr) return; if (name == nullptr) { stringStream graph_name; diff --git a/src/hotspot/share/opto/idealGraphPrinter.hpp b/src/hotspot/share/opto/idealGraphPrinter.hpp index 69ba2841506..7e68ce6c00f 100644 --- a/src/hotspot/share/opto/idealGraphPrinter.hpp +++ b/src/hotspot/share/opto/idealGraphPrinter.hpp @@ -110,7 +110,6 @@ class IdealGraphPrinter : public CHeapObj { ciMethod *_current_method; int _depth; char buffer[2048]; - bool _should_send_method; PhaseChaitin* _chaitin; bool _traverse_outs; Compile *C; diff --git a/src/hotspot/share/opto/lcm.cpp b/src/hotspot/share/opto/lcm.cpp index 4df3bbab731..0fe246a7679 100644 --- a/src/hotspot/share/opto/lcm.cpp +++ b/src/hotspot/share/opto/lcm.cpp @@ -76,6 +76,36 @@ static bool needs_explicit_null_check_for_read(Node *val) { return true; } +void PhaseCFG::move_node_and_its_projections_to_block(Node* n, Block* b) { + assert(!is_CFG(n), "cannot move CFG node"); + Block* old = get_block_for_node(n); + old->find_remove(n); + b->add_inst(n); + map_node_to_block(n, b); + // Check for Mach projections that also need to be moved. + for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { + Node* out = n->fast_out(i); + if (!out->is_MachProj()) { + continue; + } + assert(!n->is_MachProj(), "nested projections are not allowed"); + move_node_and_its_projections_to_block(out, b); + } +} + +void PhaseCFG::ensure_node_is_at_block_or_above(Node* n, Block* b) { + assert(!is_CFG(n), "cannot move CFG node"); + Block* current = get_block_for_node(n); + if (current->dominates(b)) { + return; // n is already placed above b, do nothing. + } + // We only expect nodes without further inputs, like MachTemp or load Base. + assert(n->req() == 0 || (n->req() == 1 && n->in(0) == (Node*)C->root()), + "need for recursive hoisting not expected"); + assert(b->dominates(current), "precondition: can only move n to b if b dominates n"); + move_node_and_its_projections_to_block(n, b); +} + //------------------------------implicit_null_check---------------------------- // Detect implicit-null-check opportunities. Basically, find null checks // with suitable memory ops nearby. Use the memory op to do the null check. @@ -160,12 +190,14 @@ void PhaseCFG::implicit_null_check(Block* block, Node *proj, Node *val, int allo Node *m = val->out(i); if( !m->is_Mach() ) continue; MachNode *mach = m->as_Mach(); - if (mach->barrier_data() != 0) { + if (mach->barrier_data() != 0 && + !mach->is_late_expanded_null_check_candidate()) { // Using memory accesses with barriers to perform implicit null checks is - // not supported. These operations might expand into multiple assembly - // instructions during code emission, including new memory accesses (e.g. - // in G1's pre-barrier), which would invalidate the implicit null - // exception table. + // only supported if these are explicit marked as emitting a candidate + // memory access instruction at their initial address. If not marked as + // such, barrier-tagged operations might expand into one or several memory + // access instructions located at arbitrary offsets from the initial + // address, which would invalidate the implicit null exception table. continue; } was_store = false; @@ -321,6 +353,14 @@ void PhaseCFG::implicit_null_check(Block* block, Node *proj, Node *val, int allo // Ignore DecodeN val which could be hoisted to where needed. if( is_decoden ) continue; } + if (mach->in(j)->is_MachTemp()) { + assert(mach->in(j)->outcnt() == 1, "MachTemp nodes should not be shared"); + // Ignore MachTemp inputs, they can be safely hoisted with the candidate. + // MachTemp nodes have no inputs themselves and are only used to reserve + // a scratch register for the implementation of the node (e.g. in + // late-expanded GC barriers). + continue; + } // Block of memory-op input Block *inb = get_block_for_node(mach->in(j)); Block *b = block; // Start from nul check @@ -388,38 +428,24 @@ void PhaseCFG::implicit_null_check(Block* block, Node *proj, Node *val, int allo // Hoist it up to the end of the test block together with its inputs if they exist. for (uint i = 2; i < val->req(); i++) { // DecodeN has 2 regular inputs + optional MachTemp or load Base inputs. - Node *temp = val->in(i); - Block *tempb = get_block_for_node(temp); - if (!tempb->dominates(block)) { - assert(block->dominates(tempb), "sanity check: temp node placement"); - // We only expect nodes without further inputs, like MachTemp or load Base. - assert(temp->req() == 0 || (temp->req() == 1 && temp->in(0) == (Node*)C->root()), - "need for recursive hoisting not expected"); - tempb->find_remove(temp); - block->add_inst(temp); - map_node_to_block(temp, block); - } - } - valb->find_remove(val); - block->add_inst(val); - map_node_to_block(val, block); - // DecodeN on x86 may kill flags. Check for flag-killing projections - // that also need to be hoisted. - for (DUIterator_Fast jmax, j = val->fast_outs(jmax); j < jmax; j++) { - Node* n = val->fast_out(j); - if( n->is_MachProj() ) { - get_block_for_node(n)->find_remove(n); - block->add_inst(n); - map_node_to_block(n, block); - } + // Inputs of val may already be early enough, but if not move them together with val. + ensure_node_is_at_block_or_above(val->in(i), block); } + move_node_and_its_projections_to_block(val, block); } } + + // Move any MachTemp inputs to the end of the test block. + for (uint i = 0; i < best->req(); i++) { + Node* n = best->in(i); + if (n == nullptr || !n->is_MachTemp()) { + continue; + } + ensure_node_is_at_block_or_above(n, block); + } + // Hoist the memory candidate up to the end of the test block. - Block *old_block = get_block_for_node(best); - old_block->find_remove(best); - block->add_inst(best); - map_node_to_block(best, block); + move_node_and_its_projections_to_block(best, block); // Move the control dependence if it is pinned to not-null block. // Don't change it in other cases: null or dominating control. @@ -429,17 +455,6 @@ void PhaseCFG::implicit_null_check(Block* block, Node *proj, Node *val, int allo best->set_req(0, proj->in(0)->in(0)); } - // Check for flag-killing projections that also need to be hoisted - // Should be DU safe because no edge updates. - for (DUIterator_Fast jmax, j = best->fast_outs(jmax); j < jmax; j++) { - Node* n = best->fast_out(j); - if( n->is_MachProj() ) { - get_block_for_node(n)->find_remove(n); - block->add_inst(n); - map_node_to_block(n, block); - } - } - // proj==Op_True --> ne test; proj==Op_False --> eq test. // One of two graph shapes got matched: // (IfTrue (If (Bool NE (CmpP ptr null)))) diff --git a/src/hotspot/share/opto/loopopts.cpp b/src/hotspot/share/opto/loopopts.cpp index 912d8452d21..ddeb5f84d49 100644 --- a/src/hotspot/share/opto/loopopts.cpp +++ b/src/hotspot/share/opto/loopopts.cpp @@ -1676,6 +1676,10 @@ bool PhaseIdealLoop::safe_for_if_replacement(const Node* dom) const { // like various versions of induction variable+offset. Clone the // computation per usage to allow it to sink out of the loop. void PhaseIdealLoop::try_sink_out_of_loop(Node* n) { + bool is_raw_to_oop_cast = n->is_ConstraintCast() && + n->in(1)->bottom_type()->isa_rawptr() && + !n->bottom_type()->isa_rawptr(); + if (has_ctrl(n) && !n->is_Phi() && !n->is_Bool() && @@ -1685,7 +1689,9 @@ void PhaseIdealLoop::try_sink_out_of_loop(Node* n) { !n->is_OpaqueNotNull() && !n->is_OpaqueInitializedAssertionPredicate() && !n->is_OpaqueTemplateAssertionPredicate() && - !n->is_Type()) { + !is_raw_to_oop_cast && // don't extend live ranges of raw oops + (KillPathsReachableByDeadTypeNode || !n->is_Type()) + ) { Node *n_ctrl = get_ctrl(n); IdealLoopTree *n_loop = get_loop(n_ctrl); diff --git a/src/hotspot/share/opto/machnode.hpp b/src/hotspot/share/opto/machnode.hpp index 5fd262d54e1..3594806b91e 100644 --- a/src/hotspot/share/opto/machnode.hpp +++ b/src/hotspot/share/opto/machnode.hpp @@ -386,6 +386,13 @@ public: // Returns true if this node is a check that can be implemented with a trap. virtual bool is_TrapBasedCheckNode() const { return false; } + + // Whether this node is expanded during code emission into a sequence of + // instructions and the first instruction can perform an implicit null check. + virtual bool is_late_expanded_null_check_candidate() const { + return false; + } + void set_removed() { add_flag(Flag_is_removed_by_peephole); } bool get_removed() { return (flags() & Flag_is_removed_by_peephole) != 0; } diff --git a/src/hotspot/share/opto/macro.cpp b/src/hotspot/share/opto/macro.cpp index c6ed2411fe3..8f21ee13e79 100644 --- a/src/hotspot/share/opto/macro.cpp +++ b/src/hotspot/share/opto/macro.cpp @@ -2407,7 +2407,6 @@ void PhaseMacroExpand::eliminate_macro_nodes() { } } // Next, attempt to eliminate allocations - _has_locks = false; progress = true; while (progress) { progress = false; @@ -2431,7 +2430,6 @@ void PhaseMacroExpand::eliminate_macro_nodes() { case Node::Class_Lock: case Node::Class_Unlock: assert(!n->as_AbstractLock()->is_eliminated(), "sanity"); - _has_locks = true; break; case Node::Class_ArrayCopy: break; diff --git a/src/hotspot/share/opto/macro.hpp b/src/hotspot/share/opto/macro.hpp index 4654789a290..7f27688a57a 100644 --- a/src/hotspot/share/opto/macro.hpp +++ b/src/hotspot/share/opto/macro.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -83,9 +83,6 @@ private: // projections extracted from a call node CallProjections _callprojs; - // Additional data collected during macro expansion - bool _has_locks; - void expand_allocate(AllocateNode *alloc); void expand_allocate_array(AllocateArrayNode *alloc); void expand_allocate_common(AllocateNode* alloc, @@ -199,7 +196,7 @@ private: Node* make_arraycopy_load(ArrayCopyNode* ac, intptr_t offset, Node* ctl, Node* mem, BasicType ft, const Type *ftype, AllocateNode *alloc); public: - PhaseMacroExpand(PhaseIterGVN &igvn) : Phase(Macro_Expand), _igvn(igvn), _has_locks(false) { + PhaseMacroExpand(PhaseIterGVN &igvn) : Phase(Macro_Expand), _igvn(igvn) { _igvn.set_delay_transform(true); } diff --git a/src/hotspot/share/opto/output.cpp b/src/hotspot/share/opto/output.cpp index 930c355fa62..f0a7b742998 100644 --- a/src/hotspot/share/opto/output.cpp +++ b/src/hotspot/share/opto/output.cpp @@ -2015,8 +2015,10 @@ void PhaseOutput::FillExceptionTables(uint cnt, uint *call_returns, uint *inct_s // Handle implicit null exception table updates if (n->is_MachNullCheck()) { - assert(n->in(1)->as_Mach()->barrier_data() == 0, - "Implicit null checks on memory accesses with barriers are not yet supported"); + MachNode* access = n->in(1)->as_Mach(); + assert(access->barrier_data() == 0 || + access->is_late_expanded_null_check_candidate(), + "Implicit null checks on memory accesses with barriers are only supported on nodes explicitly marked as null-check candidates"); uint block_num = block->non_connector_successor(0)->_pre_order; _inc_table.append(inct_starts[inct_cnt++], blk_labels[block_num].loc_pos()); continue; diff --git a/src/hotspot/share/opto/vectorIntrinsics.cpp b/src/hotspot/share/opto/vectorIntrinsics.cpp index 13acc0469eb..5ff2590a190 100644 --- a/src/hotspot/share/opto/vectorIntrinsics.cpp +++ b/src/hotspot/share/opto/vectorIntrinsics.cpp @@ -318,8 +318,10 @@ bool LibraryCallKit::inline_vector_nary_operation(int n) { const TypeInstPtr* elem_klass = gvn().type(argument(3))->isa_instptr(); const TypeInt* vlen = gvn().type(argument(4))->isa_int(); - if (opr == nullptr || vector_klass == nullptr || elem_klass == nullptr || vlen == nullptr || - !opr->is_con() || vector_klass->const_oop() == nullptr || elem_klass->const_oop() == nullptr || !vlen->is_con()) { + if (opr == nullptr || !opr->is_con() || + vector_klass == nullptr || vector_klass->const_oop() == nullptr || + elem_klass == nullptr || elem_klass->const_oop() == nullptr || + vlen == nullptr || !vlen->is_con()) { log_if_needed(" ** missing constant: opr=%s vclass=%s etype=%s vlen=%s", NodeClassNames[argument(0)->Opcode()], NodeClassNames[argument(1)->Opcode()], @@ -587,7 +589,11 @@ bool LibraryCallKit::inline_vector_mask_operation() { const TypeInt* vlen = gvn().type(argument(3))->isa_int(); Node* mask = argument(4); - if (mask_klass == nullptr || elem_klass == nullptr || mask->is_top() || vlen == nullptr) { + if (mask_klass == nullptr || mask_klass->const_oop() == nullptr || + elem_klass == nullptr || elem_klass->const_oop() == nullptr || + vlen == nullptr || !vlen->is_con() || + oper == nullptr || !oper->is_con() || + mask->is_top()) { return false; // dead code } @@ -647,9 +653,11 @@ bool LibraryCallKit::inline_vector_frombits_coerced() { // MODE_BITS_COERCED_LONG_TO_MASK for VectorMask.fromLong operation. const TypeInt* mode = gvn().type(argument(5))->isa_int(); - if (vector_klass == nullptr || elem_klass == nullptr || vlen == nullptr || mode == nullptr || - bits_type == nullptr || vector_klass->const_oop() == nullptr || elem_klass->const_oop() == nullptr || - !vlen->is_con() || !mode->is_con()) { + if (vector_klass == nullptr || vector_klass->const_oop() == nullptr || + elem_klass == nullptr || elem_klass->const_oop() == nullptr || + vlen == nullptr || !vlen->is_con() || + bits_type == nullptr || + mode == nullptr || !mode->is_con()) { log_if_needed(" ** missing constant: vclass=%s etype=%s vlen=%s bitwise=%s", NodeClassNames[argument(0)->Opcode()], NodeClassNames[argument(1)->Opcode()], @@ -775,8 +783,10 @@ bool LibraryCallKit::inline_vector_mem_operation(bool is_store) { const TypeInt* vlen = gvn().type(argument(2))->isa_int(); const TypeInt* from_ms = gvn().type(argument(6))->isa_int(); - if (vector_klass == nullptr || elem_klass == nullptr || vlen == nullptr || !from_ms->is_con() || - vector_klass->const_oop() == nullptr || elem_klass->const_oop() == nullptr || !vlen->is_con()) { + if (vector_klass == nullptr || vector_klass->const_oop() == nullptr || + elem_klass == nullptr || elem_klass->const_oop() == nullptr || + vlen == nullptr || !vlen->is_con() || + from_ms == nullptr || !from_ms->is_con()) { log_if_needed(" ** missing constant: vclass=%s etype=%s vlen=%s from_ms=%s", NodeClassNames[argument(0)->Opcode()], NodeClassNames[argument(1)->Opcode()], @@ -983,9 +993,11 @@ bool LibraryCallKit::inline_vector_mem_masked_operation(bool is_store) { const TypeInt* vlen = gvn().type(argument(3))->isa_int(); const TypeInt* from_ms = gvn().type(argument(7))->isa_int(); - if (vector_klass == nullptr || mask_klass == nullptr || elem_klass == nullptr || vlen == nullptr || - vector_klass->const_oop() == nullptr || mask_klass->const_oop() == nullptr || from_ms == nullptr || - elem_klass->const_oop() == nullptr || !vlen->is_con() || !from_ms->is_con()) { + if (vector_klass == nullptr || vector_klass->const_oop() == nullptr || + mask_klass == nullptr || mask_klass->const_oop() == nullptr || + elem_klass == nullptr || elem_klass->const_oop() == nullptr || + vlen == nullptr || !vlen->is_con() || + from_ms == nullptr || !from_ms->is_con()) { log_if_needed(" ** missing constant: vclass=%s mclass=%s etype=%s vlen=%s from_ms=%s", NodeClassNames[argument(0)->Opcode()], NodeClassNames[argument(1)->Opcode()], @@ -1222,8 +1234,10 @@ bool LibraryCallKit::inline_vector_gather_scatter(bool is_scatter) { const TypeInt* vlen = gvn().type(argument(3))->isa_int(); const TypeInstPtr* vector_idx_klass = gvn().type(argument(4))->isa_instptr(); - if (vector_klass == nullptr || elem_klass == nullptr || vector_idx_klass == nullptr || vlen == nullptr || - vector_klass->const_oop() == nullptr || elem_klass->const_oop() == nullptr || vector_idx_klass->const_oop() == nullptr || !vlen->is_con()) { + if (vector_klass == nullptr || vector_klass->const_oop() == nullptr || + elem_klass == nullptr || elem_klass->const_oop() == nullptr || + vlen == nullptr || !vlen->is_con() || + vector_idx_klass == nullptr || vector_idx_klass->const_oop() == nullptr) { log_if_needed(" ** missing constant: vclass=%s etype=%s vlen=%s viclass=%s", NodeClassNames[argument(0)->Opcode()], NodeClassNames[argument(2)->Opcode()], @@ -1409,8 +1423,10 @@ bool LibraryCallKit::inline_vector_reduction() { const TypeInstPtr* elem_klass = gvn().type(argument(3))->isa_instptr(); const TypeInt* vlen = gvn().type(argument(4))->isa_int(); - if (opr == nullptr || vector_klass == nullptr || elem_klass == nullptr || vlen == nullptr || - !opr->is_con() || vector_klass->const_oop() == nullptr || elem_klass->const_oop() == nullptr || !vlen->is_con()) { + if (opr == nullptr || !opr->is_con() || + vector_klass == nullptr || vector_klass->const_oop() == nullptr || + elem_klass == nullptr || elem_klass->const_oop() == nullptr || + vlen == nullptr || !vlen->is_con()) { log_if_needed(" ** missing constant: opr=%s vclass=%s etype=%s vlen=%s", NodeClassNames[argument(0)->Opcode()], NodeClassNames[argument(1)->Opcode()], @@ -1547,8 +1563,10 @@ bool LibraryCallKit::inline_vector_test() { const TypeInstPtr* elem_klass = gvn().type(argument(2))->isa_instptr(); const TypeInt* vlen = gvn().type(argument(3))->isa_int(); - if (cond == nullptr || vector_klass == nullptr || elem_klass == nullptr || vlen == nullptr || - !cond->is_con() || vector_klass->const_oop() == nullptr || elem_klass->const_oop() == nullptr || !vlen->is_con()) { + if (cond == nullptr || !cond->is_con() || + vector_klass == nullptr || vector_klass->const_oop() == nullptr || + elem_klass == nullptr || elem_klass->const_oop() == nullptr || + vlen == nullptr || !vlen->is_con()) { log_if_needed(" ** missing constant: cond=%s vclass=%s etype=%s vlen=%s", NodeClassNames[argument(0)->Opcode()], NodeClassNames[argument(1)->Opcode()], @@ -2505,10 +2523,10 @@ bool LibraryCallKit::inline_vector_extract() { const TypeInt* vlen = gvn().type(argument(2))->isa_int(); const TypeInt* idx = gvn().type(argument(4))->isa_int(); - if (vector_klass == nullptr || elem_klass == nullptr || vlen == nullptr || idx == nullptr) { - return false; // dead code - } - if (vector_klass->const_oop() == nullptr || elem_klass->const_oop() == nullptr || !vlen->is_con()) { + if (vector_klass == nullptr || vector_klass->const_oop() == nullptr || + elem_klass == nullptr || elem_klass->const_oop() == nullptr || + vlen == nullptr || !vlen->is_con() || + idx == nullptr || !idx->is_con()) { log_if_needed(" ** missing constant: vclass=%s etype=%s vlen=%s", NodeClassNames[argument(0)->Opcode()], NodeClassNames[argument(1)->Opcode()], @@ -2811,9 +2829,11 @@ bool LibraryCallKit::inline_vector_compress_expand() { const TypeInstPtr* elem_klass = gvn().type(argument(3))->isa_instptr(); const TypeInt* vlen = gvn().type(argument(4))->isa_int(); - if (vector_klass == nullptr || elem_klass == nullptr || mask_klass == nullptr || vlen == nullptr || - vector_klass->const_oop() == nullptr || mask_klass->const_oop() == nullptr || - elem_klass->const_oop() == nullptr || !vlen->is_con() || !opr->is_con()) { + if (opr == nullptr || !opr->is_con() || + vector_klass == nullptr || vector_klass->const_oop() == nullptr || + mask_klass == nullptr || mask_klass->const_oop() == nullptr || + elem_klass == nullptr || elem_klass->const_oop() == nullptr || + vlen == nullptr || !vlen->is_con()) { log_if_needed(" ** missing constant: opr=%s vclass=%s mclass=%s etype=%s vlen=%s", NodeClassNames[argument(0)->Opcode()], NodeClassNames[argument(1)->Opcode()], @@ -2892,9 +2912,9 @@ bool LibraryCallKit::inline_index_vector() { const TypeInstPtr* elem_klass = gvn().type(argument(1))->isa_instptr(); const TypeInt* vlen = gvn().type(argument(2))->isa_int(); - if (vector_klass == nullptr || elem_klass == nullptr || vlen == nullptr || - vector_klass->const_oop() == nullptr || !vlen->is_con() || - elem_klass->const_oop() == nullptr) { + if (vector_klass == nullptr || vector_klass->const_oop() == nullptr || + elem_klass == nullptr || elem_klass->const_oop() == nullptr || + vlen == nullptr || !vlen->is_con() ) { log_if_needed(" ** missing constant: vclass=%s etype=%s vlen=%s", NodeClassNames[argument(0)->Opcode()], NodeClassNames[argument(1)->Opcode()], @@ -3026,8 +3046,9 @@ bool LibraryCallKit::inline_index_partially_in_upper_range() { const TypeInstPtr* elem_klass = gvn().type(argument(1))->isa_instptr(); const TypeInt* vlen = gvn().type(argument(2))->isa_int(); - if (mask_klass == nullptr || elem_klass == nullptr || vlen == nullptr || - mask_klass->const_oop() == nullptr || elem_klass->const_oop() == nullptr || !vlen->is_con()) { + if (mask_klass == nullptr || mask_klass->const_oop() == nullptr || + elem_klass == nullptr || elem_klass->const_oop() == nullptr || + vlen == nullptr || !vlen->is_con()) { log_if_needed(" ** missing constant: mclass=%s etype=%s vlen=%s", NodeClassNames[argument(0)->Opcode()], NodeClassNames[argument(1)->Opcode()], diff --git a/src/hotspot/share/prims/jni.cpp b/src/hotspot/share/prims/jni.cpp index 228244bbd05..5a43baeb8d8 100644 --- a/src/hotspot/share/prims/jni.cpp +++ b/src/hotspot/share/prims/jni.cpp @@ -2285,9 +2285,11 @@ JNI_ENTRY(jobjectArray, jni_NewObjectArray(JNIEnv *env, jsize length, jclass ele jobjectArray ret = nullptr; DT_RETURN_MARK(NewObjectArray, jobjectArray, (const jobjectArray&)ret); Klass* ek = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(elementClass)); - Klass* ak = ek->array_klass(CHECK_NULL); - ObjArrayKlass::cast(ak)->initialize(CHECK_NULL); - objArrayOop result = ObjArrayKlass::cast(ak)->allocate(length, CHECK_NULL); + + // Make sure bottom_klass is initialized. + ek->initialize(CHECK_NULL); + objArrayOop result = oopFactory::new_objArray(ek, length, CHECK_NULL); + oop initial_value = JNIHandles::resolve(initialElement); if (initial_value != nullptr) { // array already initialized with null for (int index = 0; index < length; index++) { diff --git a/src/hotspot/share/prims/vectorSupport.cpp b/src/hotspot/share/prims/vectorSupport.cpp index c907ddb4885..002f737e788 100644 --- a/src/hotspot/share/prims/vectorSupport.cpp +++ b/src/hotspot/share/prims/vectorSupport.cpp @@ -28,6 +28,7 @@ #include "code/location.hpp" #include "jni.h" #include "jvm.h" +#include "memory/oopFactory.hpp" #include "oops/klass.inline.hpp" #include "oops/typeArrayOop.inline.hpp" #include "prims/vectorSupport.hpp" @@ -109,9 +110,7 @@ Handle VectorSupport::allocate_vector_payload_helper(InstanceKlass* ik, frame* f int elem_size = type2aelembytes(elem_bt); // On-heap vector values are represented as primitive arrays. - TypeArrayKlass* tak = Universe::typeArrayKlass(elem_bt); - - typeArrayOop arr = tak->allocate(num_elem, CHECK_NH); // safepoint + typeArrayOop arr = oopFactory::new_typeArray(elem_bt, num_elem, CHECK_NH); // safepoint if (location.is_register()) { // Value was in a callee-saved register. diff --git a/src/hotspot/share/prims/whitebox.cpp b/src/hotspot/share/prims/whitebox.cpp index cf3b48c11b5..374e877faa6 100644 --- a/src/hotspot/share/prims/whitebox.cpp +++ b/src/hotspot/share/prims/whitebox.cpp @@ -583,28 +583,6 @@ WB_ENTRY(jboolean, WB_G1HasRegionsToUncommit(JNIEnv* env, jobject o)) THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_G1HasRegionsToUncommit: G1 GC is not enabled"); WB_END -#endif // INCLUDE_G1GC - -#if INCLUDE_PARALLELGC - -WB_ENTRY(jlong, WB_PSVirtualSpaceAlignment(JNIEnv* env, jobject o)) - if (UseParallelGC) { - return GenAlignment; - } - THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_PSVirtualSpaceAlignment: Parallel GC is not enabled"); -WB_END - -WB_ENTRY(jlong, WB_PSHeapGenerationAlignment(JNIEnv* env, jobject o)) - if (UseParallelGC) { - return GenAlignment; - } - THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_PSHeapGenerationAlignment: Parallel GC is not enabled"); -WB_END - -#endif // INCLUDE_PARALLELGC - -#if INCLUDE_G1GC - WB_ENTRY(jobject, WB_G1AuxiliaryMemoryUsage(JNIEnv* env)) if (UseG1GC) { ResourceMark rm(THREAD); @@ -2773,10 +2751,6 @@ static JNINativeMethod methods[] = { {CC"g1MemoryNodeIds", CC"()[I", (void*)&WB_G1MemoryNodeIds }, {CC"g1GetMixedGCInfo", CC"(I)[J", (void*)&WB_G1GetMixedGCInfo }, #endif // INCLUDE_G1GC -#if INCLUDE_PARALLELGC - {CC"psVirtualSpaceAlignment",CC"()J", (void*)&WB_PSVirtualSpaceAlignment}, - {CC"psHeapGenerationAlignment",CC"()J", (void*)&WB_PSHeapGenerationAlignment}, -#endif {CC"NMTMalloc", CC"(J)J", (void*)&WB_NMTMalloc }, {CC"NMTMallocWithPseudoStack", CC"(JI)J", (void*)&WB_NMTMallocWithPseudoStack}, {CC"NMTMallocWithPseudoStackAndType", CC"(JII)J", (void*)&WB_NMTMallocWithPseudoStackAndType}, diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index 7592d233f0c..a49116fd91d 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -528,10 +528,6 @@ static SpecialFlag const special_jvm_flags[] = { { "DynamicDumpSharedSpaces", JDK_Version::jdk(18), JDK_Version::jdk(19), JDK_Version::undefined() }, { "RequireSharedSpaces", JDK_Version::jdk(18), JDK_Version::jdk(19), JDK_Version::undefined() }, { "UseSharedSpaces", JDK_Version::jdk(18), JDK_Version::jdk(19), JDK_Version::undefined() }, -#ifdef LINUX - { "UseLinuxPosixThreadCPUClocks", JDK_Version::jdk(24), JDK_Version::jdk(25), JDK_Version::jdk(26) }, - { "UseOprofile", JDK_Version::jdk(25), JDK_Version::jdk(26), JDK_Version::jdk(27) }, -#endif { "LockingMode", JDK_Version::jdk(24), JDK_Version::jdk(26), JDK_Version::jdk(27) }, #ifdef _LP64 { "UseCompressedClassPointers", JDK_Version::jdk(25), JDK_Version::jdk(26), JDK_Version::undefined() }, @@ -541,7 +537,9 @@ static SpecialFlag const special_jvm_flags[] = { // -------------- Obsolete Flags - sorted by expired_in -------------- - { "PerfDataSamplingInterval", JDK_Version::undefined(), JDK_Version::jdk(25), JDK_Version::jdk(26) }, +#ifdef LINUX + { "UseOprofile", JDK_Version::jdk(25), JDK_Version::jdk(26), JDK_Version::jdk(27) }, +#endif { "MetaspaceReclaimPolicy", JDK_Version::undefined(), JDK_Version::jdk(21), JDK_Version::undefined() }, { "ZGenerational", JDK_Version::jdk(23), JDK_Version::jdk(24), JDK_Version::undefined() }, { "ZMarkStackSpaceLimit", JDK_Version::undefined(), JDK_Version::jdk(25), JDK_Version::undefined() }, diff --git a/src/hotspot/share/runtime/deoptimization.cpp b/src/hotspot/share/runtime/deoptimization.cpp index a0d9dd00339..ed84f2b294f 100644 --- a/src/hotspot/share/runtime/deoptimization.cpp +++ b/src/hotspot/share/runtime/deoptimization.cpp @@ -1274,11 +1274,11 @@ bool Deoptimization::realloc_objects(JavaThread* thread, frame* fr, RegisterMap* assert(sv->field_size() % type2size[ak->element_type()] == 0, "non-integral array length"); int len = sv->field_size() / type2size[ak->element_type()]; InternalOOMEMark iom(THREAD); - obj = ak->allocate(len, THREAD); + obj = ak->allocate_instance(len, THREAD); } else if (k->is_objArray_klass()) { ObjArrayKlass* ak = ObjArrayKlass::cast(k); InternalOOMEMark iom(THREAD); - obj = ak->allocate(sv->field_size(), THREAD); + obj = ak->allocate_instance(sv->field_size(), THREAD); } if (obj == nullptr) { diff --git a/src/hotspot/share/runtime/reflection.cpp b/src/hotspot/share/runtime/reflection.cpp index 9e165f76829..2a0af9d2d09 100644 --- a/src/hotspot/share/runtime/reflection.cpp +++ b/src/hotspot/share/runtime/reflection.cpp @@ -320,9 +320,16 @@ void Reflection::array_set(jvalue* value, arrayOop a, int index, BasicType value } } + +// Conversion +static BasicType basic_type_mirror_to_basic_type(oop basic_type_mirror) { + assert(java_lang_Class::is_primitive(basic_type_mirror), + "just checking"); + return java_lang_Class::primitive_type(basic_type_mirror); +} + static Klass* basic_type_mirror_to_arrayklass(oop basic_type_mirror, TRAPS) { - assert(java_lang_Class::is_primitive(basic_type_mirror), "just checking"); - BasicType type = java_lang_Class::primitive_type(basic_type_mirror); + BasicType type = basic_type_mirror_to_basic_type(basic_type_mirror); if (type == T_VOID) { THROW_NULL(vmSymbols::java_lang_IllegalArgumentException()); } @@ -339,8 +346,11 @@ arrayOop Reflection::reflect_new_array(oop element_mirror, jint length, TRAPS) { THROW_MSG_NULL(vmSymbols::java_lang_NegativeArraySizeException(), err_msg("%d", length)); } if (java_lang_Class::is_primitive(element_mirror)) { - Klass* tak = basic_type_mirror_to_arrayklass(element_mirror, CHECK_NULL); - return TypeArrayKlass::cast(tak)->allocate(length, THREAD); + BasicType type = basic_type_mirror_to_basic_type(element_mirror); + if (type == T_VOID) { + THROW_NULL(vmSymbols::java_lang_IllegalArgumentException()); + } + return oopFactory::new_typeArray(type, length, CHECK_NULL); } else { Klass* k = java_lang_Class::as_Klass(element_mirror); if (k->is_array_klass() && ArrayKlass::cast(k)->dimension() >= MAX_DIM) { @@ -907,13 +917,6 @@ static methodHandle resolve_interface_call(InstanceKlass* klass, return methodHandle(THREAD, info.selected_method()); } -// Conversion -static BasicType basic_type_mirror_to_basic_type(oop basic_type_mirror) { - assert(java_lang_Class::is_primitive(basic_type_mirror), - "just checking"); - return java_lang_Class::primitive_type(basic_type_mirror); -} - // Narrowing of basic types. Used to create correct jvalues for // boolean, byte, char and short return return values from interpreter // which are returned as ints. Throws IllegalArgumentException. diff --git a/src/hotspot/share/utilities/enumIterator.hpp b/src/hotspot/share/utilities/enumIterator.hpp index 6fa7f071f4a..42cc405fcd7 100644 --- a/src/hotspot/share/utilities/enumIterator.hpp +++ b/src/hotspot/share/utilities/enumIterator.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, 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,13 +25,14 @@ #ifndef SHARE_UTILITIES_ENUMITERATOR_HPP #define SHARE_UTILITIES_ENUMITERATOR_HPP -#include -#include #include "memory/allStatic.hpp" #include "metaprogramming/enableIf.hpp" #include "metaprogramming/primitiveConversions.hpp" #include "utilities/debug.hpp" +#include +#include + // Iteration support for enums. // // E is enum type, U is underlying type of E. @@ -147,6 +148,12 @@ public: assert(value <= end, "out of range"); } + template + static constexpr void assert_in_range() { + static_assert(_start <= static_cast(Value), "out of range"); + static_assert(static_cast(Value) <= _end, "out of range"); + } + // Convert an enumerator value to the corresponding underlying type. static constexpr Underlying underlying_value(T value) { return static_cast(value); @@ -229,6 +236,12 @@ class EnumRange { assert(size() > 0, "empty range"); } + struct ConstExprConstructTag {}; + + constexpr EnumRange(T start, T end, ConstExprConstructTag) : + _start(Traits::underlying_value(start)), + _end(Traits::underlying_value(end)) {} + public: using EnumType = T; using Iterator = EnumIterator; @@ -252,6 +265,14 @@ public: assert(start <= end, "invalid range"); } + template + static constexpr EnumRange create() { + Traits::template assert_in_range(); + Traits::template assert_in_range(); + static_assert(Start <= End, "invalid range"); + return EnumRange(Start, End, ConstExprConstructTag{}); + } + // Return an iterator for the start of the range. constexpr Iterator begin() const { return Iterator(Traits::enumerator(_start)); 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/util/Locale.java b/src/java.base/share/classes/java/util/Locale.java index 993495ff5ab..9059d196861 100644 --- a/src/java.base/share/classes/java/util/Locale.java +++ b/src/java.base/share/classes/java/util/Locale.java @@ -48,8 +48,8 @@ import java.io.Serializable; import java.text.NumberFormat; import java.text.MessageFormat; import java.text.ParsePosition; -import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; +import java.util.function.Supplier; import java.util.spi.LocaleNameProvider; import java.util.stream.Stream; @@ -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 createCountryCodeSet() { - return Set.of(Locale.getISOCountries()); - } - }, + PART1_ALPHA2, /** * * PART1_ALPHA3 is used to represent the ISO3166-1 alpha-3 three letter * country codes. */ - PART1_ALPHA3 { - @Override - Set createCountryCodeSet() { - return LocaleISOData.computeISO3166_1Alpha3Countries(); - } - }, + PART1_ALPHA3, /** * PART3 is used to represent the ISO3166-3 four letter country codes. */ - PART3 { - @Override - Set createCountryCodeSet() { - return Set.of(LocaleISOData.ISO3166_3); - } - }; - - /** - * Concrete implementation of this method attempts to compute value - * for iso3166CodesMap for each IsoCountryCode type key. - */ - abstract Set createCountryCodeSet(); - - /** - * Map to hold country codes for each ISO3166 part. - */ - private static final Map> iso3166CodesMap = new ConcurrentHashMap<>(); - - /** - * This method is called from Locale class to retrieve country code set - * for getISOCountries(type) - */ - static Set retrieveISOCountryCodes(IsoCountryCode type) { - return iso3166CodesMap.computeIfAbsent(type, IsoCountryCode::createCountryCodeSet); - } + PART3 } /** @@ -1004,30 +970,28 @@ public final class Locale implements Cloneable, Serializable { return getInstance(baseloc, extensions); } - static Locale getInstance(BaseLocale baseloc, LocaleExtensions extensions) { if (extensions == null) { Locale locale = CONSTANT_LOCALES.get(baseloc); if (locale != null) { return locale; } - return LocaleCache.cache(baseloc); + return LOCALE_CACHE.get().computeIfAbsent(baseloc, LOCALE_CREATOR); } else { LocaleKey key = new LocaleKey(baseloc, extensions); - return LocaleCache.cache(key); + return LOCALE_CACHE.get().computeIfAbsent(key, LOCALE_CREATOR); } } - private static final class LocaleCache implements Function { - private static final ReferencedKeyMap LOCALE_CACHE - = ReferencedKeyMap.create(true, ReferencedKeyMap.concurrentHashMapSupplier()); - - private static final Function LOCALE_CREATOR = new LocaleCache(); - - public static Locale cache(Object key) { - return LOCALE_CACHE.computeIfAbsent(key, LOCALE_CREATOR); - } + private static final Supplier> LOCALE_CACHE = + StableValue.supplier(new Supplier<>() { + @Override + public ReferencedKeyMap get() { + return ReferencedKeyMap.create(true, ReferencedKeyMap.concurrentHashMapSupplier()); + } + }); + private static final Function LOCALE_CREATOR = new Function<>() { @Override public Locale apply(Object key) { if (key instanceof BaseLocale base) { @@ -1036,7 +1000,7 @@ public final class Locale implements Cloneable, Serializable { LocaleKey lk = (LocaleKey)key; return new Locale(lk.base, lk.exts); } - } + }; private static final class LocaleKey { @@ -1301,12 +1265,8 @@ public final class Locale implements Cloneable, Serializable { * @return An array of ISO 3166 two-letter country codes. */ public static String[] getISOCountries() { - if (isoCountries == null) { - isoCountries = getISO2Table(LocaleISOData.isoCountryTable); - } - String[] result = new String[isoCountries.length]; - System.arraycopy(isoCountries, 0, result, 0, isoCountries.length); - return result; + String[] countries = LocaleISOData.ISO_3166_1_ALPHA2.get(); + return Arrays.copyOf(countries, countries.length); } /** @@ -1319,7 +1279,11 @@ public final class Locale implements Cloneable, Serializable { */ public static Set getISOCountries(IsoCountryCode type) { Objects.requireNonNull(type); - return IsoCountryCode.retrieveISOCountryCodes(type); + return switch (type) { + case PART1_ALPHA2 -> Set.of(LocaleISOData.ISO_3166_1_ALPHA2.get()); + case PART1_ALPHA3 -> LocaleISOData.ISO_3166_1_ALPHA3.get(); + case PART3 -> LocaleISOData.ISO_3166_3.get(); + }; } /** @@ -1339,22 +1303,8 @@ public final class Locale implements Cloneable, Serializable { * @return An array of ISO 639 two-letter language codes. */ public static String[] getISOLanguages() { - String[] languages = Locale.isoLanguages; - if (languages == null) { - Locale.isoLanguages = languages = getISO2Table(LocaleISOData.isoLanguageTable); - } - String[] result = new String[languages.length]; - System.arraycopy(languages, 0, result, 0, languages.length); - return result; - } - - private static String[] getISO2Table(String table) { - int len = table.length() / 5; - String[] isoTable = new String[len]; - for (int i = 0, j = 0; i < len; i++, j += 5) { - isoTable[i] = table.substring(j, j + 2); - } - return isoTable; + String[] languages = LocaleISOData.ISO_639.get(); + return Arrays.copyOf(languages, languages.length); } /** @@ -1683,61 +1633,54 @@ public final class Locale implements Cloneable, Serializable { * @since 1.7 */ public String toLanguageTag() { - String lTag = this.languageTag; - if (lTag != null) { - return lTag; - } + return languageTag.get(); + } + private String computeLanguageTag() { LanguageTag tag = LanguageTag.parseLocale(baseLocale, localeExtensions); - StringBuilder buf = new StringBuilder(); + StringBuilder bldr = new StringBuilder(); String subtag = tag.language(); if (!subtag.isEmpty()) { - buf.append(LanguageTag.canonicalizeLanguage(subtag)); + bldr.append(LanguageTag.canonicalizeLanguage(subtag)); } subtag = tag.script(); if (!subtag.isEmpty()) { - buf.append(LanguageTag.SEP); - buf.append(LanguageTag.canonicalizeScript(subtag)); + bldr.append(LanguageTag.SEP); + bldr.append(LanguageTag.canonicalizeScript(subtag)); } subtag = tag.region(); if (!subtag.isEmpty()) { - buf.append(LanguageTag.SEP); - buf.append(LanguageTag.canonicalizeRegion(subtag)); + bldr.append(LanguageTag.SEP); + bldr.append(LanguageTag.canonicalizeRegion(subtag)); } Listsubtags = tag.variants(); for (String s : subtags) { - buf.append(LanguageTag.SEP); + bldr.append(LanguageTag.SEP); // preserve casing - buf.append(s); + bldr.append(s); } subtags = tag.extensions(); for (String s : subtags) { - buf.append(LanguageTag.SEP); - buf.append(LanguageTag.canonicalizeExtension(s)); + bldr.append(LanguageTag.SEP); + bldr.append(LanguageTag.canonicalizeExtension(s)); } subtag = tag.privateuse(); if (!subtag.isEmpty()) { - if (buf.length() > 0) { - buf.append(LanguageTag.SEP); + if (bldr.length() > 0) { + bldr.append(LanguageTag.SEP); } - buf.append(LanguageTag.PRIVATEUSE).append(LanguageTag.SEP); + bldr.append(LanguageTag.PRIVATEUSE).append(LanguageTag.SEP); // preserve casing - buf.append(subtag); + bldr.append(subtag); } - String langTag = buf.toString(); - synchronized (this) { - if (this.languageTag == null) { - this.languageTag = langTag; - } - } - return langTag; + return bldr.toString(); } /** @@ -1961,7 +1904,7 @@ public final class Locale implements Cloneable, Serializable { return lang; } - String language3 = getISO3Code(lang, LocaleISOData.isoLanguageTable); + String language3 = LocaleISOData.getISO3LangCode(lang); if (language3 == null) { throw new MissingResourceException("Couldn't find 3-letter language code for " + lang, "FormatData_" + toString(), "ShortLanguage"); @@ -1983,7 +1926,7 @@ public final class Locale implements Cloneable, Serializable { * three-letter country abbreviation is not available for this locale. */ public String getISO3Country() throws MissingResourceException { - String country3 = getISO3Code(baseLocale.getRegion(), LocaleISOData.isoCountryTable); + String country3 = LocaleISOData.getISO3CtryCode(baseLocale.getRegion()); if (country3 == null) { throw new MissingResourceException("Couldn't find 3-letter country code for " + baseLocale.getRegion(), "FormatData_" + toString(), "ShortCountry"); @@ -1991,27 +1934,6 @@ public final class Locale implements Cloneable, Serializable { return country3; } - private static String getISO3Code(String iso2Code, String table) { - int codeLength = iso2Code.length(); - if (codeLength == 0) { - return ""; - } - - int tableLength = table.length(); - int index = tableLength; - if (codeLength == 2) { - char c1 = iso2Code.charAt(0); - char c2 = iso2Code.charAt(1); - for (index = 0; index < tableLength; index += 5) { - if (table.charAt(index) == c1 - && table.charAt(index + 1) == c2) { - break; - } - } - } - return index < tableLength ? table.substring(index + 2, index + 5) : null; - } - /** * Returns a name for the locale's language that is appropriate for display to the * user. @@ -2393,7 +2315,13 @@ public final class Locale implements Cloneable, Serializable { private static volatile Locale defaultDisplayLocale; private static volatile Locale defaultFormatLocale; - private transient volatile String languageTag; + private final transient Supplier languageTag = + StableValue.supplier(new Supplier<>() { + @Override + public String get() { + return computeLanguageTag(); + } + }); /** * Return an array of the display names of the variant. @@ -2587,10 +2515,6 @@ public final class Locale implements Cloneable, Serializable { baseLocale.getRegion(), baseLocale.getVariant(), localeExtensions); } - private static volatile String[] isoLanguages; - - private static volatile String[] isoCountries; - private static String convertOldISOCodes(String language) { // we accept both the old and the new ISO codes for the languages whose ISO // codes have changed, but we always store the NEW code, unless the property diff --git a/src/java.base/share/classes/java/util/LocaleISOData.java b/src/java.base/share/classes/java/util/LocaleISOData.java index c2090d3be19..29e0b28be01 100644 --- a/src/java.base/share/classes/java/util/LocaleISOData.java +++ b/src/java.base/share/classes/java/util/LocaleISOData.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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,47 @@ package java.util; +import java.util.function.Supplier; + +// Methods and suppliers for producing ISO 639/3166 resources used by Locale. class LocaleISOData { + + static final Supplier ISO_639 = + StableValue.supplier(new Supplier<>() { + @Override + public String[] get() { + return getISO2Table(isoLanguageTable); + } + }); + + static final Supplier ISO_3166_1_ALPHA2 = + StableValue.supplier(new Supplier<>() { + @Override + public String[] get() { + return getISO2Table(isoCountryTable); + } + }); + + static final Supplier> ISO_3166_1_ALPHA3 = + StableValue.supplier(new Supplier<>() { + @Override + public Set get() { + return computeISO3166_1Alpha3Countries(); + } + }); + + static final Supplier> ISO_3166_3 = + StableValue.supplier(new Supplier<>() { + @Override + public Set get() { + return Set.of(ISO3166_3); + } + }); + /** * The 2- and 3-letter ISO 639 language codes. */ - static final String isoLanguageTable = + private static final String isoLanguageTable = "aa" + "aar" // Afar + "ab" + "abk" // Abkhazian + "ae" + "ave" // Avestan @@ -223,7 +259,7 @@ class LocaleISOData { /** * The 2- and 3-letter ISO 3166 country codes. */ - static final String isoCountryTable = + private static final String isoCountryTable = "AD" + "AND" // Andorra, Principality of + "AE" + "ARE" // United Arab Emirates + "AF" + "AFG" // Afghanistan @@ -480,18 +516,60 @@ class LocaleISOData { /** * Array to hold country codes for ISO3166-3. */ - static final String[] ISO3166_3 = { + private static final String[] ISO3166_3 = { "AIDJ", "ANHH", "BQAQ", "BUMM", "BYAA", "CSHH", "CSXX", "CTKI", "DDDE", "DYBJ", "FQHH", "FXFR", "GEHH", "HVBF", "JTUM", "MIUM", "NHVU", "NQAQ", "NTHH", "PCHH", "PUUM", "PZPA", "RHZW", "SKIN", "SUHH", "TPTL", "VDVN", "WKUM", "YDYE", "YUCS", "ZRCD" }; + static String getISO3LangCode(String language) { + return getISO3Code(language, isoLanguageTable); + } + + static String getISO3CtryCode(String country) { + return getISO3Code(country, isoCountryTable); + } + + private static String getISO3Code(String iso2Code, String table) { + int codeLength = iso2Code.length(); + if (codeLength == 0) { + return ""; + } + + int tableLength = table.length(); + int index = tableLength; + if (codeLength == 2) { + char c1 = iso2Code.charAt(0); + char c2 = iso2Code.charAt(1); + for (index = 0; index < tableLength; index += 5) { + if (table.charAt(index) == c1 + && table.charAt(index + 1) == c2) { + break; + } + } + } + return index < tableLength ? table.substring(index + 2, index + 5) : null; + } + + /** + * This method computes an array of alpha-2 codes from either ISO639 or + * ISO3166. + */ + private static String[] getISO2Table(String table) { + int len = table.length() / 5; + String[] isoTable = new String[len]; + for (int i = 0, j = 0; i < len; i++, j += 5) { + isoTable[i] = table.substring(j, j + 2); + } + return isoTable; + } + /** * This method computes a set of ISO3166-1 alpha-3 country codes from * existing isoCountryTable. */ - static Set computeISO3166_1Alpha3Countries() { + private static Set computeISO3166_1Alpha3Countries() { int tableLength = isoCountryTable.length(); String[] isoTable = new String[tableLength / 5]; for (int i = 0, index = 0; index < tableLength; i++, index += 5) { @@ -500,6 +578,5 @@ class LocaleISOData { return Set.of(isoTable); } - private LocaleISOData() { - } + private LocaleISOData() {} } diff --git a/src/java.base/share/classes/java/util/ResourceBundle.java b/src/java.base/share/classes/java/util/ResourceBundle.java index fb88a38903a..b3807ac770a 100644 --- a/src/java.base/share/classes/java/util/ResourceBundle.java +++ b/src/java.base/share/classes/java/util/ResourceBundle.java @@ -54,6 +54,7 @@ import java.net.URL; import java.net.URLConnection; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import java.util.function.Supplier; import java.util.jar.JarEntry; import java.util.spi.ResourceBundleControlProvider; import java.util.spi.ResourceBundleProvider; @@ -487,7 +488,20 @@ public abstract class ResourceBundle { /** * A Set of the keys contained only in this ResourceBundle. */ - private volatile Set keySet; + private final Supplier> keySet = StableValue.supplier( + new Supplier<>() { public Set get() { return keySet0(); }}); + + private Set keySet0() { + final Set keys = new HashSet<>(); + final Enumeration enumKeys = getKeys(); + while (enumKeys.hasMoreElements()) { + final String key = enumKeys.nextElement(); + if (handleGetObject(key) != null) { + keys.add(key); + } + } + return keys; + } /** * Sole constructor. (For invocation by subclass constructors, typically @@ -2298,22 +2312,7 @@ public abstract class ResourceBundle { * @since 1.6 */ protected Set handleKeySet() { - if (keySet == null) { - synchronized (this) { - if (keySet == null) { - Set keys = new HashSet<>(); - Enumeration enumKeys = getKeys(); - while (enumKeys.hasMoreElements()) { - String key = enumKeys.nextElement(); - if (handleGetObject(key) != null) { - keys.add(key); - } - } - keySet = keys; - } - } - } - return keySet; + return keySet.get(); } diff --git a/src/java.base/share/classes/javax/crypto/Cipher.java b/src/java.base/share/classes/javax/crypto/Cipher.java index 3de732c6687..e729a984811 100644 --- a/src/java.base/share/classes/javax/crypto/Cipher.java +++ b/src/java.base/share/classes/javax/crypto/Cipher.java @@ -454,19 +454,25 @@ public class Cipher { String[] parts = tokenizeTransformation(transformation); String alg = parts[0]; - String mode = parts[1]; - String pad = parts[2]; + String mode = (parts[1].length() == 0 ? null : parts[1]); + String pad = (parts[2].length() == 0 ? null : parts[2]); - if ((mode.length() == 0) && (pad.length() == 0)) { + if ((mode == null) && (pad == null)) { // Algorithm only Transform tr = new Transform(alg, "", null, null); return Collections.singletonList(tr); } else { // Algorithm w/ at least mode or padding or both List list = new ArrayList<>(4); - list.add(new Transform(alg, "/" + mode + "/" + pad, null, null)); - list.add(new Transform(alg, "/" + mode, null, pad)); - list.add(new Transform(alg, "//" + pad, mode, null)); + if ((mode != null) && (pad != null)) { + list.add(new Transform(alg, "/" + mode + "/" + pad, null, null)); + } + if (mode != null) { + list.add(new Transform(alg, "/" + mode, null, pad)); + } + if (pad != null) { + list.add(new Transform(alg, "//" + pad, mode, null)); + } list.add(new Transform(alg, "", mode, pad)); return list; } diff --git a/src/java.base/share/classes/jdk/internal/access/SharedSecrets.java b/src/java.base/share/classes/jdk/internal/access/SharedSecrets.java index bc955a76abb..5c6212d0bf6 100644 --- a/src/java.base/share/classes/jdk/internal/access/SharedSecrets.java +++ b/src/java.base/share/classes/jdk/internal/access/SharedSecrets.java @@ -59,7 +59,6 @@ import javax.security.auth.x500.X500Principal; */ public class SharedSecrets { - private static JavaAWTAccess javaAWTAccess; private static JavaAWTFontAccess javaAWTFontAccess; private static JavaBeansAccess javaBeansAccess; private static JavaLangAccess javaLangAccess; @@ -321,16 +320,6 @@ public class SharedSecrets { javaUtilZipFileAccess = access; } - public static void setJavaAWTAccess(JavaAWTAccess jaa) { - javaAWTAccess = jaa; - } - - public static JavaAWTAccess getJavaAWTAccess() { - // this may return null in which case calling code needs to - // provision for. - return javaAWTAccess; - } - public static void setJavaAWTFontAccess(JavaAWTFontAccess jafa) { javaAWTFontAccess = jafa; } diff --git a/src/java.base/share/classes/sun/text/resources/JavaTimeSupplementary.java b/src/java.base/share/classes/sun/text/resources/JavaTimeSupplementary.java index 7b041591c6a..cbcb724d258 100644 --- a/src/java.base/share/classes/sun/text/resources/JavaTimeSupplementary.java +++ b/src/java.base/share/classes/sun/text/resources/JavaTimeSupplementary.java @@ -232,8 +232,8 @@ public class JavaTimeSupplementary extends OpenListResourceBundle { "Sha.", "Ram.", "Shaw.", - "Dhu\u02bbl-Q.", - "Dhu\u02bbl-H.", + "Dhuʻl-Q.", + "Dhuʻl-H.", "", } }, @@ -241,16 +241,16 @@ public class JavaTimeSupplementary extends OpenListResourceBundle { new String[] { "Muharram", "Safar", - "Rabi\u02bb I", - "Rabi\u02bb II", + "Rabiʻ I", + "Rabiʻ II", "Jumada I", "Jumada II", "Rajab", - "Sha\u02bbban", + "Shaʻban", "Ramadan", "Shawwal", - "Dhu\u02bbl-Qi\u02bbdah", - "Dhu\u02bbl-Hijjah", + "Dhuʻl-Qiʻdah", + "Dhuʻl-Hijjah", "", } }, diff --git a/src/java.base/share/classes/sun/util/locale/BaseLocale.java b/src/java.base/share/classes/sun/util/locale/BaseLocale.java index d1fe8d24b72..529ca1b0c13 100644 --- a/src/java.base/share/classes/sun/util/locale/BaseLocale.java +++ b/src/java.base/share/classes/sun/util/locale/BaseLocale.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 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 @@ -38,6 +38,7 @@ import jdk.internal.util.StaticProperty; import jdk.internal.vm.annotation.Stable; import java.util.StringJoiner; +import java.util.function.Supplier; public final class BaseLocale { @@ -90,6 +91,15 @@ public final class BaseLocale { } } + // Interned BaseLocale cache + private static final Supplier> CACHE = + StableValue.supplier(new Supplier<>() { + @Override + public ReferencedKeySet get() { + return ReferencedKeySet.create(true, ReferencedKeySet.concurrentHashMapSupplier()); + } + }); + public static final String SEP = "_"; private final String language; @@ -164,11 +174,7 @@ public final class BaseLocale { // Obtain the "interned" BaseLocale from the cache. The returned // "interned" instance can subsequently be used by the Locale // instance which guarantees the locale components are properly cased/interned. - class InterningCache { // TODO: StableValue - private static final ReferencedKeySet CACHE = - ReferencedKeySet.create(true, ReferencedKeySet.concurrentHashMapSupplier()); - } - return InterningCache.CACHE.intern(new BaseLocale( + return CACHE.get().intern(new BaseLocale( language.intern(), // guaranteed to be lower-case LocaleUtils.toTitleString(script).intern(), region.intern(), // guaranteed to be upper-case diff --git a/src/java.base/share/classes/sun/util/resources/BreakIteratorResourceBundle.java b/src/java.base/share/classes/sun/util/resources/BreakIteratorResourceBundle.java index 3a55e7ccb8c..d7c575962f6 100644 --- a/src/java.base/share/classes/sun/util/resources/BreakIteratorResourceBundle.java +++ b/src/java.base/share/classes/sun/util/resources/BreakIteratorResourceBundle.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -30,6 +30,7 @@ import java.util.Collections; import java.util.Enumeration; import java.util.ResourceBundle; import java.util.Set; +import java.util.function.Supplier; /** * BreakIteratorResourceBundle is an abstract class for loading BreakIterator @@ -49,7 +50,15 @@ public abstract class BreakIteratorResourceBundle extends ResourceBundle { // those keys must be added to NON_DATA_KEYS. private static final Set NON_DATA_KEYS = Set.of("BreakIteratorClasses"); - private volatile Set keys; + private final Supplier> keys = StableValue.supplier( + new Supplier<>() { public Set get() { return keys0(); }}); + + private Set keys0() { + final ResourceBundle info = getBreakIteratorInfo(); + final Set k = info.keySet(); + k.removeAll(NON_DATA_KEYS); + return k; + } /** * Returns an instance of the corresponding {@code BreakIteratorInfo} (basename). @@ -84,16 +93,6 @@ public abstract class BreakIteratorResourceBundle extends ResourceBundle { @Override protected Set handleKeySet() { - if (keys == null) { - ResourceBundle info = getBreakIteratorInfo(); - Set k = info.keySet(); - k.removeAll(NON_DATA_KEYS); - synchronized (this) { - if (keys == null) { - keys = k; - } - } - } - return keys; + return keys.get(); } } diff --git a/src/java.base/share/classes/sun/util/resources/OpenListResourceBundle.java b/src/java.base/share/classes/sun/util/resources/OpenListResourceBundle.java index d375930dde0..0c16f508018 100644 --- a/src/java.base/share/classes/sun/util/resources/OpenListResourceBundle.java +++ b/src/java.base/share/classes/sun/util/resources/OpenListResourceBundle.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -44,8 +44,11 @@ import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Map; +import java.util.Objects; import java.util.ResourceBundle; import java.util.Set; +import java.util.function.Supplier; + import sun.util.ResourceBundleEnumeration; /** @@ -69,12 +72,9 @@ public abstract class OpenListResourceBundle extends ResourceBundle { // Implements java.util.ResourceBundle.handleGetObject; inherits javadoc specification. @Override protected Object handleGetObject(String key) { - if (key == null) { - throw new NullPointerException(); - } - - loadLookupTablesIfNecessary(); - return lookup.get(key); // this class ignores locales + Objects.requireNonNull(key); + return lookup.get() + .get(key); // this class ignores locales } /** @@ -93,26 +93,13 @@ public abstract class OpenListResourceBundle extends ResourceBundle { */ @Override protected Set handleKeySet() { - loadLookupTablesIfNecessary(); - return lookup.keySet(); + return lookup.get() + .keySet(); } @Override public Set keySet() { - if (keyset != null) { - return keyset; - } - Set ks = createSet(); - ks.addAll(handleKeySet()); - if (parent != null) { - ks.addAll(parent.keySet()); - } - synchronized (this) { - if (keyset == null) { - keyset = ks; - } - } - return keyset; + return keyset.get(); } /** @@ -120,38 +107,6 @@ public abstract class OpenListResourceBundle extends ResourceBundle { */ protected abstract Object[][] getContents(); - /** - * Load lookup tables if they haven't been loaded already. - */ - void loadLookupTablesIfNecessary() { - if (lookup == null) { - loadLookup(); - } - } - - /** - * We lazily load the lookup hashtable. This function does the - * loading. - */ - private void loadLookup() { - Object[][] contents = getContents(); - Map temp = createMap(contents.length); - for (int i = 0; i < contents.length; ++i) { - // key must be non-null String, value must be non-null - String key = (String) contents[i][0]; - Object value = contents[i][1]; - if (key == null || value == null) { - throw new NullPointerException(); - } - temp.put(key, value); - } - synchronized (this) { - if (lookup == null) { - lookup = temp; - } - } - } - /** * Lets subclasses provide specialized Map implementations. * Default uses HashMap. @@ -164,6 +119,31 @@ public abstract class OpenListResourceBundle extends ResourceBundle { return new HashSet<>(); } - private volatile Map lookup; - private volatile Set keyset; + private final Supplier> lookup = StableValue.supplier( + new Supplier<>() { public Map get() { return lookup0(); }}); + + private Map lookup0() { + final Object[][] contents = getContents(); + final Map temp = createMap(contents.length); + for (Object[] content : contents) { + // key must be non-null String, value must be non-null + final String key = Objects.requireNonNull((String) content[0]); + final Object value = Objects.requireNonNull(content[1]); + temp.put(key, value); + } + return temp; + } + + private final Supplier> keyset = StableValue.supplier( + new Supplier<>() { public Set get() { return keyset0(); }}); + + private Set keyset0() { + final Set ks = createSet(); + ks.addAll(handleKeySet()); + if (parent != null) { + ks.addAll(parent.keySet()); + } + return ks; + } + } diff --git a/src/java.base/share/data/cacerts/sectigocodesignroote46 b/src/java.base/share/data/cacerts/sectigocodesignroote46 new file mode 100644 index 00000000000..7f13b28a401 --- /dev/null +++ b/src/java.base/share/data/cacerts/sectigocodesignroote46 @@ -0,0 +1,21 @@ +Owner: CN=Sectigo Public Code Signing Root E46, O=Sectigo Limited, C=GB +Issuer: CN=Sectigo Public Code Signing Root E46, O=Sectigo Limited, C=GB +Serial number: 50249ba2ef8ea6bf6c2c1f1a6385d4c3 +Valid from: Mon Mar 22 00:00:00 GMT 2021 until: Wed Mar 21 23:59:59 GMT 2046 +Signature algorithm name: SHA384withECDSA +Subject Public Key Algorithm: 384-bit EC (secp384r1) key +Version: 3 +-----BEGIN CERTIFICATE----- +MIICKDCCAa+gAwIBAgIQUCSbou+Opr9sLB8aY4XUwzAKBggqhkjOPQQDAzBWMQsw +CQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMS0wKwYDVQQDEyRT +ZWN0aWdvIFB1YmxpYyBDb2RlIFNpZ25pbmcgUm9vdCBFNDYwHhcNMjEwMzIyMDAw +MDAwWhcNNDYwMzIxMjM1OTU5WjBWMQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2Vj +dGlnbyBMaW1pdGVkMS0wKwYDVQQDEyRTZWN0aWdvIFB1YmxpYyBDb2RlIFNpZ25p +bmcgUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQIMoEDH487om+BR4zl +e7m6wWmyW0nAKLkUWG8kM85Qm3PZO8FoOZx6Yc5c0iJHRKuAhanllayqrmZYhlan +uIODzLTRDqlR+EtnOX+MubY5aDSPGUq6jiHrQrisVp0J3AejQjBAMB0GA1UdDgQW +BBTPfSygkHqYHd22XoXC4NoVcdLlXjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/ +BAUwAwEB/zAKBggqhkjOPQQDAwNnADBkAjACd++zAerlV83j8HflRwwwlLmgchbs +aGX/4g44dv/oG8KfzCVTRg6sZHMobtK0IqYCMGk5W6+oBFyZMtOebrSwXs8lGjll +/zHz43Zy8DMXO+iiqzSEwWGneZ6KupkGGqfVKw== +-----END CERTIFICATE----- diff --git a/src/java.base/share/data/cacerts/sectigocodesignrootr46 b/src/java.base/share/data/cacerts/sectigocodesignrootr46 new file mode 100644 index 00000000000..38270cb0c52 --- /dev/null +++ b/src/java.base/share/data/cacerts/sectigocodesignrootr46 @@ -0,0 +1,39 @@ +Owner: CN=Sectigo Public Code Signing Root R46, O=Sectigo Limited, C=GB +Issuer: CN=Sectigo Public Code Signing Root R46, O=Sectigo Limited, C=GB +Serial number: 4b2c3b01018bad2abc8c7b5b3eed9057 +Valid from: Mon Mar 22 00:00:00 GMT 2021 until: Wed Mar 21 23:59:59 GMT 2046 +Signature algorithm name: SHA384withRSA +Subject Public Key Algorithm: 4096-bit RSA key +Version: 3 +-----BEGIN CERTIFICATE----- +MIIFeDCCA2CgAwIBAgIQSyw7AQGLrSq8jHtbPu2QVzANBgkqhkiG9w0BAQwFADBW +MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMS0wKwYDVQQD +EyRTZWN0aWdvIFB1YmxpYyBDb2RlIFNpZ25pbmcgUm9vdCBSNDYwHhcNMjEwMzIy +MDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBWMQswCQYDVQQGEwJHQjEYMBYGA1UEChMP +U2VjdGlnbyBMaW1pdGVkMS0wKwYDVQQDEyRTZWN0aWdvIFB1YmxpYyBDb2RlIFNp +Z25pbmcgUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCN +55QSIgQkdC7/FiMCkoq2rjaFrEfUI5ErPtx94jGgUW+shJHjUoq14pbe0IdjJImK +/+8Skzt9u7aKvb0Ffyeba2XTpQxpsbxJOZrxbW6q5KCDJ9qaDStQ6Utbs7hkNqR+ +Sj2pcaths3OzPAsM79szV+W+NDfjlxtd/R8SPYIDdub7P2bSlDFp+m2zNKzBenjc +klDyZMeqLQSrw2rq4C+np9xu1+j/2iGrQL+57g2extmeme/G3h+pDHazJyCh1rr9 +gOcB0u/rgimVcI3/uxXP/tEPNqIuTzKQdEZrRzUTdwUzT2MuuC3hv2WnBGsY2HH6 +zAjybYmZELGt2z4s5KoYsMYHAXVn3m3pY2MeNn9pib6qRT5uWl+PoVvLnTCGMOgD +s0DGDQ84zWeoU4j6uDBl+m/H5x2xg3RpPqzEaDux5mczmrYI4IAFSEDu9oJkRqj1 +c7AGlfJsZZ+/VVscnFcax3hGfHCqlBuCF6yH6bbJDoEcQNYWFyn8XJwYK+pF9e+9 +1WdPKF4F7pBMeufG9ND8+s0+MkYTIDaKBOq3qgdGnA2TOglmmVhcKaO5DKYwODzQ +RjY1fJy67sPV+Qp2+n4FG0DKkjXp1XrRtX8ArqmQqsV/AZwQsRb8zG4Y3G9i/qZQ +p7h7uJ0VP/4gDHXIIloTlRmQAOka1cKG8eOO7F/05QIDAQABo0IwQDAdBgNVHQ4E +FgQUMuuSmv81lkgvKEBCcCA2kVwXheYwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB +/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAHZlwuPXIkrXHYle/2lexhQCTXOm +zc0oyrA36r+nySGqql/av/aDbNCA0QpcAKTL88w5D55BcYjVPOiKe4wXI/fKNHSR +bAauUD8AWbImPDwXg1cDPi3RGj3UzwdUskMLUnKoiPXEF/Jv0Vil0WjkPZgIGO42 +9EhImvpUcPCI1HAWMEJJ0Nk/dUtFcdiuorthDoiFUFe5uhErNikfjyBynlyeidGC +2kWNapnahHFrM6UQu3nwl/Z0gaA/V8eGjDCMDjiVrgHGHqvcqB9vL9f/dh6uF3Nt +5bl1s2EGqJUzwk5vsjfylb6FVBK5yL1iQnb3Kvz1NzEDJlf+0ebb8BYCcoOMCLOE +rKnkB/ihiMQTWlBHVEKm7dBBNCyYsT6iNKEMXb2s9395p79tDFYyhRtLl7jhrOSk +PHHxo+FOY9b0Rrr1CwjhYzztolkvCtQsayOinqFN7tESzRgzUO1Bbst/PUFgC2ML +ePV170MVtzYLEK/cXBipmNk22R3YhLMGioLjexskp0LO7g8+VlwyfexL3lYrOzu6 ++XpY0FG2bNb2WKJSJHpEhqEcYD9J0/z6+YQcBcI0v+Lm8RkqmS9WVzWctfUHw0Yv +3jg9GQ37o/HfE57nqXJYMa+96trX1m13MzOO9Kz9wb9Jh9JwBWd0Bqb2eEAtFgSR +Dx/TFsS4ehcNJMmy +-----END CERTIFICATE----- diff --git a/src/java.base/share/data/cacerts/sectigotlsroote46 b/src/java.base/share/data/cacerts/sectigotlsroote46 new file mode 100644 index 00000000000..60e0b83c97e --- /dev/null +++ b/src/java.base/share/data/cacerts/sectigotlsroote46 @@ -0,0 +1,21 @@ +Owner: CN=Sectigo Public Server Authentication Root E46, O=Sectigo Limited, C=GB +Issuer: CN=Sectigo Public Server Authentication Root E46, O=Sectigo Limited, C=GB +Serial number: 42f2ccda1b6937445f15fe752810b8f4 +Valid from: Mon Mar 22 00:00:00 GMT 2021 until: Wed Mar 21 23:59:59 GMT 2046 +Signature algorithm name: SHA384withECDSA +Subject Public Key Algorithm: 384-bit EC (secp384r1) key +Version: 3 +-----BEGIN CERTIFICATE----- +MIICOjCCAcGgAwIBAgIQQvLM2htpN0RfFf51KBC49DAKBggqhkjOPQQDAzBfMQsw +CQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1T +ZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwHhcN +MjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBfMQswCQYDVQQGEwJHQjEYMBYG +A1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1YmxpYyBT +ZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAAR2+pmpbiDt+dd34wc7qNs9Xzjoq1WmVk/WSOrsfy2qw7LFeeyZYX8QeccC +WvkEN/U0NSt3zn8gj1KjAIns1aeibVvjS5KToID1AZTc8GgHHs3u/iVStSBDHBv+ +6xnOQ6OjQjBAMB0GA1UdDgQWBBTRItpMWfFLXyY4qp3W7usNw/upYTAOBgNVHQ8B +Af8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNnADBkAjAn7qRa +qCG76UeXlImldCBteU/IvZNeWBj7LRoAasm4PdCkT0RHlAFWovgzJQxC36oCMB3q +4S6ILuH5px0CMk7yn2xVdOOurvulGu7t0vzCAxHrRVxgED1cf5kDW21USAGKcw== +-----END CERTIFICATE----- diff --git a/src/java.base/share/data/cacerts/sectigotlsrootr46 b/src/java.base/share/data/cacerts/sectigotlsrootr46 new file mode 100644 index 00000000000..7ec1b263de7 --- /dev/null +++ b/src/java.base/share/data/cacerts/sectigotlsrootr46 @@ -0,0 +1,39 @@ +Owner: CN=Sectigo Public Server Authentication Root R46, O=Sectigo Limited, C=GB +Issuer: CN=Sectigo Public Server Authentication Root R46, O=Sectigo Limited, C=GB +Serial number: 758dfd8bae7c0700faa925a7e1c7ad14 +Valid from: Mon Mar 22 00:00:00 GMT 2021 until: Wed Mar 21 23:59:59 GMT 2046 +Signature algorithm name: SHA384withRSA +Subject Public Key Algorithm: 4096-bit RSA key +Version: 3 +-----BEGIN CERTIFICATE----- +MIIFijCCA3KgAwIBAgIQdY39i658BwD6qSWn4cetFDANBgkqhkiG9w0BAQwFADBf +MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQD +Ey1TZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYw +HhcNMjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBfMQswCQYDVQQGEwJHQjEY +MBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1Ymxp +YyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQCTvtU2UnXYASOgHEdCSe5jtrch/cSV1UgrJnwUUxDa +ef0rty2k1Cz66jLdScK5vQ9IPXtamFSvnl0xdE8H/FAh3aTPaE8bEmNtJZlMKpnz +SDBh+oF8HqcIStw+KxwfGExxqjWMrfhu6DtK2eWUAtaJhBOqbchPM8xQljeSM9xf +iOefVNlI8JhD1mb9nxc4Q8UBUQvX4yMPFF1bFOdLvt30yNoDN9HWOaEhUTCDsG3X +ME6WW5HwcCSrv0WBZEMNvSE6Lzzpng3LILVCJ8zab5vuZDCQOc2TZYEhMbUjUDM3 +IuM47fgxMMxF/mL50V0yeUKH32rMVhlATc6qu/m1dkmU8Sf4kaWD5QazYw6A3OAS +VYCmO2a0OYctyPDQ0RTp5A1NDvZdV3LFOxxHVp3i1fuBYYzMTYCQNFu31xR13NgE +SJ/AwSiItOkcyqex8Va3e0lMWeUgFaiEAin6OJRpmkkGj80feRQXEgyDet4fsZfu ++Zd4KKTIRJLpfSYFplhym3kT2BFfrsU4YjRosoYwjviQYZ4ybPUHNs2iTG7sijbt +8uaZFURww3y8nDnAtOFr94MlI1fZEoDlSfB1D++N6xybVCi0ITz8fAr/73trdf+L +HaAZBav6+CuBQug4urv7qv094PPK306Xlynt8xhW6aWWrL3DkJiy4Pmi1KZHQ3xt +zwIDAQABo0IwQDAdBgNVHQ4EFgQUVnNYZJX5khqwEioEYnmhQBWIIUkwDgYDVR0P +AQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAC9c +mTz8Bl6MlC5w6tIyMY208FHVvArzZJ8HXtXBc2hkeqK5Duj5XYUtqDdFqij0lgVQ +YKlJfp/imTYpE0RHap1VIDzYm/EDMrraQKFz6oOht0SmDpkBm+S8f74TlH7Kph52 +gDY9hAaLMyZlbcp+nv4fjFg4exqDsQ+8FxG75gbMY/qB8oFM2gsQa6H61SilzwZA +Fv97fRheORKkU55+MkIQpiGRqRxOF3yEvJ+M0ejf5lG5Nkc/kLnHvALcWxxPDkjB +JYOcCj+esQMzEhonrPcibCTRAUH4WAP+JWgiH5paPHxsnnVI84HxZmduTILA7rpX +DhjvLpr3Etiga+kFpaHpaPi8TD8SHkXoUsCjvxInebnMMTzD9joiFgOgyY9mpFui +TdaBJQbpdqQACj7LzTWb4OE4y2BThihCQRxEV+ioratF4yUQvNs+ZUH7G6aXD+u5 +dHn5HrwdVw1Hr8Mvn4dGp+smWg9WY7ViYG4A++MnESLn/pmPNPW56MORcr3Ywx65 +LvKRRFHQV80MNNVIIb/bE/FmJUNS0nAiNs2fxBx1IK1jcmMGDw4nztJqDby1ORrp +0XZ60Vzk50lJLVU3aPAaOpg+VBeHVOmmJ1CJeyAvP/+/oYtKR5j/K3tJPsMpRmAY +QqszKbrAKbkTidOIijlBO8n9pu0f9GBj39ItVQGL +-----END CERTIFICATE----- diff --git a/src/java.base/share/man/java.md b/src/java.base/share/man/java.md index bb010e6e1c7..fc8cbb23aff 100644 --- a/src/java.base/share/man/java.md +++ b/src/java.base/share/man/java.md @@ -2917,71 +2917,12 @@ when they're used. ## Removed Java Options -These `java` options have been removed in JDK @@VERSION_SPECIFICATION@@ and using them results in an error of: - -> `Unrecognized VM option` *option-name* - -`-XX:RTMAbortRatio=`*abort\_ratio* -: Specifies the RTM abort ratio is specified as a percentage (%) of all - executed RTM transactions. If a number of aborted transactions becomes - greater than this ratio, then the compiled code is deoptimized. This ratio - is used when the `-XX:+UseRTMDeopt` option is enabled. The default value of - this option is 50. This means that the compiled code is deoptimized if 50% - of all transactions are aborted. - -`-XX:RTMRetryCount=`*number\_of\_retries* -: Specifies the number of times that the RTM locking code is retried, when it - is aborted or busy, before falling back to the normal locking mechanism. - The default value for this option is 5. The `-XX:UseRTMLocking` option must - be enabled. - -`-XX:+UseRTMDeopt` -: Autotunes RTM locking depending on the abort ratio. This ratio is specified - by the `-XX:RTMAbortRatio` option. If the number of aborted transactions - exceeds the abort ratio, then the method containing the lock is deoptimized - and recompiled with all locks as normal locks. This option is disabled by - default. The `-XX:+UseRTMLocking` option must be enabled. - -`-XX:+UseRTMLocking` -: Generates Restricted Transactional Memory (RTM) locking code for all - inflated locks, with the normal locking mechanism as the fallback handler. - This option is disabled by default. Options related to RTM are available - only on x86 CPUs that support Transactional Synchronization Extensions (TSX). - - RTM is part of Intel's TSX, which is an x86 instruction set extension and - facilitates the creation of multithreaded applications. RTM introduces the - new instructions `XBEGIN`, `XABORT`, `XEND`, and `XTEST`. The `XBEGIN` and - `XEND` instructions enclose a set of instructions to run as a transaction. - If no conflict is found when running the transaction, then the memory and - register modifications are committed together at the `XEND` instruction. - The `XABORT` instruction can be used to explicitly abort a transaction and - the `XTEST` instruction checks if a set of instructions is being run in a - transaction. - - A lock on a transaction is inflated when another thread tries to access the - same transaction, thereby blocking the thread that didn't originally - request access to the transaction. RTM requires that a fallback set of - operations be specified in case a transaction aborts or fails. An RTM lock - is a lock that has been delegated to the TSX's system. - - RTM improves performance for highly contended locks with low conflict in a - critical region (which is code that must not be accessed by more than one - thread concurrently). RTM also improves the performance of coarse-grain - locking, which typically doesn't perform well in multithreaded - applications. (Coarse-grain locking is the strategy of holding locks for - long periods to minimize the overhead of taking and releasing locks, while - fine-grained locking is the strategy of trying to achieve maximum - parallelism by locking only when necessary and unlocking as soon as - possible.) Also, for lightly contended locks that are used by different - threads, RTM can reduce false cache line sharing, also known as cache line - ping-pong. This occurs when multiple threads from different processors are - accessing different resources, but the resources share the same cache line. - As a result, the processors repeatedly invalidate the cache lines of other - processors, which forces them to read from main memory instead of their - cache. +No documented java options have been removed in JDK @@VERSION_SPECIFICATION@@. For the lists and descriptions of options removed in previous releases see the *Removed Java Options* section in: +- [The `java` Command, Release 25](https://docs.oracle.com/en/java/javase/25/docs/specs/man/java.html) + - [The `java` Command, Release 24](https://docs.oracle.com/en/java/javase/24/docs/specs/man/java.html) - [The `java` Command, Release 23](https://docs.oracle.com/en/java/javase/23/docs/specs/man/java.html) diff --git a/src/java.desktop/share/classes/sun/awt/AppContext.java b/src/java.desktop/share/classes/sun/awt/AppContext.java index a35d89f6a0c..3b93f1d2755 100644 --- a/src/java.desktop/share/classes/sun/awt/AppContext.java +++ b/src/java.desktop/share/classes/sun/awt/AppContext.java @@ -42,8 +42,6 @@ import java.beans.PropertyChangeSupport; import java.beans.PropertyChangeListener; import java.lang.ref.SoftReference; -import jdk.internal.access.JavaAWTAccess; -import jdk.internal.access.SharedSecrets; import sun.util.logging.PlatformLogger; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; @@ -746,67 +744,6 @@ public final class AppContext { return changeSupport.getPropertyChangeListeners(propertyName); } - // Set up JavaAWTAccess in SharedSecrets - static { - SharedSecrets.setJavaAWTAccess(new JavaAWTAccess() { - private boolean hasRootThreadGroup(final AppContext ecx) { - return ecx.threadGroup.getParent() == null; - } - - /** - * Returns the AppContext used for applet logging isolation, or null if - * the default global context can be used. - * If there's no applet, or if the caller is a stand alone application, - * or running in the main app context, returns null. - * Otherwise, returns the AppContext of the calling applet. - * @return null if the global default context can be used, - * an AppContext otherwise. - **/ - public Object getAppletContext() { - // There's no AppContext: return null. - // No need to call getAppContext() if numAppContext == 0: - // it means that no AppContext has been created yet, and - // we don't want to trigger the creation of a main app - // context since we don't need it. - if (numAppContexts.get() == 0) return null; - - AppContext ecx = null; - - // Not sure we really need to re-check numAppContexts here. - // If all applets have gone away then we could have a - // numAppContexts coming back to 0. So we recheck - // it here because we don't want to trigger the - // creation of a main AppContext in that case. - // This is probably not 100% MT-safe but should reduce - // the window of opportunity in which that issue could - // happen. - if (numAppContexts.get() > 0) { - // Defaults to thread group caching. - // This is probably not required as we only really need - // isolation in a deployed applet environment, in which - // case ecx will not be null when we reach here - // However it helps emulate the deployed environment, - // in tests for instance. - ecx = ecx != null ? ecx : getAppContext(); - } - - // getAppletContext() may be called when initializing the main - // app context - in which case mainAppContext will still be - // null. To work around this issue we simply use - // AppContext.threadGroup.getParent() == null instead, since - // mainAppContext is the only AppContext which should have - // the root TG as its thread group. - // See: JDK-8023258 - final boolean isMainAppContext = ecx == null - || mainAppContext == ecx - || mainAppContext == null && hasRootThreadGroup(ecx); - - return isMainAppContext ? null : ecx; - } - - }); - } - public static T getSoftReferenceValue(Object key, Supplier supplier) { diff --git a/src/java.desktop/share/classes/sun/awt/datatransfer/SunClipboard.java b/src/java.desktop/share/classes/sun/awt/datatransfer/SunClipboard.java index 898cabd2855..edffbf59878 100644 --- a/src/java.desktop/share/classes/sun/awt/datatransfer/SunClipboard.java +++ b/src/java.desktop/share/classes/sun/awt/datatransfer/SunClipboard.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -204,8 +204,9 @@ public abstract class SunClipboard extends Clipboard byte[] data = null; Transferable localeTransferable = null; + openClipboard(null); + try { - openClipboard(null); long[] formats = getClipboardFormats(); Long lFormat = DataTransferer.getInstance(). @@ -318,12 +319,7 @@ public abstract class SunClipboard extends Clipboard * @since 1.5 */ protected long[] getClipboardFormatsOpenClose() { - try { - openClipboard(null); - return getClipboardFormats(); - } finally { - closeClipboard(); - } + return getClipboardFormats(); } /** @@ -356,15 +352,7 @@ public abstract class SunClipboard extends Clipboard flavorListeners.add(listener); if (numberOfFlavorListeners++ == 0) { - long[] currentFormats = null; - try { - openClipboard(null); - currentFormats = getClipboardFormats(); - } catch (final IllegalStateException ignored) { - } finally { - closeClipboard(); - } - this.currentFormats = currentFormats; + this.currentFormats = getClipboardFormats(); registerClipboardViewerChecked(); } diff --git a/src/java.desktop/unix/native/libawt_xawt/awt/screencast_pipewire.c b/src/java.desktop/unix/native/libawt_xawt/awt/screencast_pipewire.c index ec12445c87b..ea921d3f636 100644 --- a/src/java.desktop/unix/native/libawt_xawt/awt/screencast_pipewire.c +++ b/src/java.desktop/unix/native/libawt_xawt/awt/screencast_pipewire.c @@ -1016,6 +1016,7 @@ JNIEXPORT jint JNICALL Java_sun_awt_screencast_ScreencastHelper_getRGBPixelsImpl const gchar *token = jtoken ? (*env)->GetStringUTFChars(env, jtoken, NULL) : NULL; + JNU_CHECK_EXCEPTION_RETURN(env, RESULT_ERROR); isGtkMainThread = gtk->g_main_context_is_owner(gtk->g_main_context_default()); DEBUG_SCREENCAST( @@ -1121,7 +1122,7 @@ JNIEXPORT jint JNICALL Java_sun_awt_screencast_ScreencastHelper_remoteDesktopMou const gchar *token = jtoken ? (*env)->GetStringUTFChars(env, jtoken, NULL) : NULL; - + JNU_CHECK_EXCEPTION_RETURN(env, RESULT_ERROR); DEBUG_SCREENCAST("moving mouse to\n\t%d %d\n\twith token |%s|\n", jx, jy, token); @@ -1151,6 +1152,7 @@ JNIEXPORT jint JNICALL Java_sun_awt_screencast_ScreencastHelper_remoteDesktopMou const gchar *token = jtoken ? (*env)->GetStringUTFChars(env, jtoken, NULL) : NULL; + JNU_CHECK_EXCEPTION_RETURN(env, RESULT_ERROR); gboolean result = initPortal(token, NULL, 0); DEBUG_SCREENCAST("init result %b, mouse pressing %d\n", result, buttons) @@ -1178,6 +1180,7 @@ JNIEXPORT jint JNICALL Java_sun_awt_screencast_ScreencastHelper_remoteDesktopMou const gchar *token = jtoken ? (*env)->GetStringUTFChars(env, jtoken, NULL) : NULL; + JNU_CHECK_EXCEPTION_RETURN(env, RESULT_ERROR); gboolean result = initPortal(token, NULL, 0); DEBUG_SCREENCAST("init result %b, mouse wheel %d\n", result, jWheelAmt) @@ -1206,13 +1209,14 @@ JNIEXPORT jint JNICALL Java_sun_awt_screencast_ScreencastHelper_remoteDesktopKey int key = awt_getX11KeySym(jkey); AWT_UNLOCK(); - if (key == NoSymbol) { + if (key == NoSymbol || (*env)->ExceptionCheck(env)) { return RESULT_ERROR; } const gchar *token = jtoken ? (*env)->GetStringUTFChars(env, jtoken, NULL) : NULL; + JNU_CHECK_EXCEPTION_RETURN(env, RESULT_ERROR); gboolean result = initPortal(token, NULL, 0); DEBUG_SCREENCAST("init result %b, key %d -> %d isPress %b\n", result, jkey, key, isPress) diff --git a/src/java.desktop/windows/classes/sun/awt/windows/WClipboard.java b/src/java.desktop/windows/classes/sun/awt/windows/WClipboard.java index e16b1805295..110dfb8d637 100644 --- a/src/java.desktop/windows/classes/sun/awt/windows/WClipboard.java +++ b/src/java.desktop/windows/classes/sun/awt/windows/WClipboard.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -29,7 +29,9 @@ import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; import java.io.IOException; +import java.lang.System.Logger.Level; import java.util.Map; +import java.util.concurrent.locks.ReentrantLock; import sun.awt.datatransfer.DataTransferer; import sun.awt.datatransfer.SunClipboard; @@ -51,8 +53,12 @@ final class WClipboard extends SunClipboard { private boolean isClipboardViewerRegistered; + private final ReentrantLock clipboardLocked = new ReentrantLock(); + WClipboard() { super("System"); + // Register java side of the clipboard with the native side + registerClipboard(); } @Override @@ -104,18 +110,42 @@ final class WClipboard extends SunClipboard { /** * Call the Win32 OpenClipboard function. If newOwner is non-null, - * we also call EmptyClipboard and take ownership. + * we also call EmptyClipboard and take ownership. If this method call + * succeeds, it must be followed by a call to {@link #closeClipboard()}. * * @throws IllegalStateException if the clipboard has not been opened */ @Override - public native void openClipboard(SunClipboard newOwner) throws IllegalStateException; + public void openClipboard(SunClipboard newOwner) throws IllegalStateException { + if (!clipboardLocked.tryLock()) { + throw new IllegalStateException("Failed to acquire clipboard lock"); + } + try { + openClipboard0(newOwner); + } catch (IllegalStateException ex) { + clipboardLocked.unlock(); + throw ex; + } + } + /** * Call the Win32 CloseClipboard function if we have clipboard ownership, * does nothing if we have not ownership. */ @Override - public native void closeClipboard(); + public void closeClipboard() { + if (clipboardLocked.isLocked()) { + try { + closeClipboard0(); + } finally { + clipboardLocked.unlock(); + } + } + } + + private native void openClipboard0(SunClipboard newOwner) throws IllegalStateException; + private native void closeClipboard0(); + /** * Call the Win32 SetClipboardData function. */ @@ -157,16 +187,12 @@ final class WClipboard extends SunClipboard { return; } - long[] formats = null; try { - openClipboard(null); - formats = getClipboardFormats(); - } catch (IllegalStateException exc) { - // do nothing to handle the exception, call checkChange(null) - } finally { - closeClipboard(); + long[] formats = getClipboardFormats(); + checkChange(formats); + } catch (Throwable ex) { + System.getLogger(WClipboard.class.getName()).log(Level.DEBUG, "Failed to process handleContentsChanged", ex); } - checkChange(formats); } /** @@ -214,4 +240,6 @@ final class WClipboard extends SunClipboard { } }; } + + private native void registerClipboard(); } diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Clipboard.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Clipboard.cpp index 2aadcd5a08c..1232f189ca2 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Clipboard.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_Clipboard.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -69,9 +69,8 @@ void AwtClipboard::RegisterClipboardViewer(JNIEnv *env, jobject jclipboard) { return; } - if (theCurrentClipboard == NULL) { - theCurrentClipboard = env->NewGlobalRef(jclipboard); - } + DASSERT(AwtClipboard::theCurrentClipboard != NULL); + DASSERT(env->IsSameObject(AwtClipboard::theCurrentClipboard, jclipboard)); jclass cls = env->GetObjectClass(jclipboard); AwtClipboard::handleContentsChangedMID = @@ -128,11 +127,13 @@ Java_sun_awt_windows_WClipboard_init(JNIEnv *env, jclass cls) * Signature: (Lsun/awt/windows/WClipboard;)V */ JNIEXPORT void JNICALL -Java_sun_awt_windows_WClipboard_openClipboard(JNIEnv *env, jobject self, +Java_sun_awt_windows_WClipboard_openClipboard0(JNIEnv *env, jobject self, jobject newOwner) { TRY; + DASSERT(AwtClipboard::theCurrentClipboard != NULL); + DASSERT(newOwner == NULL || env->IsSameObject(AwtClipboard::theCurrentClipboard, newOwner)); DASSERT(::GetOpenClipboardWindow() != AwtToolkit::GetInstance().GetHWnd()); if (!::OpenClipboard(AwtToolkit::GetInstance().GetHWnd())) { @@ -142,10 +143,6 @@ Java_sun_awt_windows_WClipboard_openClipboard(JNIEnv *env, jobject self, } if (newOwner != NULL) { AwtClipboard::GetOwnership(); - if (AwtClipboard::theCurrentClipboard != NULL) { - env->DeleteGlobalRef(AwtClipboard::theCurrentClipboard); - } - AwtClipboard::theCurrentClipboard = env->NewGlobalRef(newOwner); } CATCH_BAD_ALLOC; @@ -157,7 +154,7 @@ Java_sun_awt_windows_WClipboard_openClipboard(JNIEnv *env, jobject self, * Signature: ()V */ JNIEXPORT void JNICALL -Java_sun_awt_windows_WClipboard_closeClipboard(JNIEnv *env, jobject self) +Java_sun_awt_windows_WClipboard_closeClipboard0(JNIEnv *env, jobject self) { TRY; @@ -297,23 +294,25 @@ Java_sun_awt_windows_WClipboard_getClipboardFormats { TRY; - DASSERT(::GetOpenClipboardWindow() == AwtToolkit::GetInstance().GetHWnd()); + unsigned int cFormats = 128; // Allocate enough space to hold all + unsigned int pcFormatsOut = 0; + unsigned int lpuiFormats[128] = { 0 }; - jsize nFormats = ::CountClipboardFormats(); - jlongArray formats = env->NewLongArray(nFormats); + VERIFY(::GetUpdatedClipboardFormats(lpuiFormats, 128, &pcFormatsOut)); + + jlongArray formats = env->NewLongArray(pcFormatsOut); if (formats == NULL) { throw std::bad_alloc(); } - if (nFormats == 0) { + if (pcFormatsOut == 0) { return formats; } jboolean isCopy; jlong *lFormats = env->GetLongArrayElements(formats, &isCopy), *saveFormats = lFormats; - UINT num = 0; - for (jsize i = 0; i < nFormats; i++, lFormats++) { - *lFormats = num = ::EnumClipboardFormats(num); + for (unsigned int i = 0; i < pcFormatsOut; i++, lFormats++) { + *lFormats = lpuiFormats[i]; } env->ReleaseLongArrayElements(formats, saveFormats, 0); @@ -478,4 +477,16 @@ Java_sun_awt_windows_WClipboard_getClipboardData CATCH_BAD_ALLOC_RET(NULL); } +/* + * Class: sun_awt_windows_WClipboard + * Method: registerClipboard + * Signature: ()V + */ +JNIEXPORT void JNICALL +Java_sun_awt_windows_WClipboard_registerClipboard(JNIEnv *env, jobject self) +{ + DASSERT(AwtClipboard::theCurrentClipboard == NULL); + AwtClipboard::theCurrentClipboard = env->NewGlobalRef(self); +} + } /* extern "C" */ diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/SocketTube.java b/src/java.net.http/share/classes/jdk/internal/net/http/SocketTube.java index 2aec6ca48ad..ef935b008d3 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/SocketTube.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/SocketTube.java @@ -557,34 +557,15 @@ final class SocketTube implements FlowTube { implements Flow.Publisher> { private final InternalReadSubscription subscriptionImpl = new InternalReadSubscription(); - ConcurrentLinkedQueue pendingSubscriptions = new ConcurrentLinkedQueue<>(); + private final AtomicReference pendingSubscriptions + = new AtomicReference<>(); private volatile ReadSubscription subscription; @Override public void subscribe(Flow.Subscriber> s) { Objects.requireNonNull(s); - - TubeSubscriber sub = FlowTube.asTubeSubscriber(s); - ReadSubscription previous; - while ((previous = pendingSubscriptions.poll()) != null) { - if (debug.on()) - debug.log("read publisher: dropping pending subscriber: " - + previous.subscriber); - previous.errorRef.compareAndSet(null, errorRef.get()); - // make sure no data will be routed to the old subscriber. - previous.stopReading(); - previous.signalOnSubscribe(); - if (subscriptionImpl.completed) { - previous.signalCompletion(); - } else { - previous.subscriber.dropSubscription(); - } - } - ReadSubscription target = new ReadSubscription(subscriptionImpl, sub); - pendingSubscriptions.offer(target); - - if (debug.on()) debug.log("read publisher got new subscriber: " + s); - subscriptionImpl.signalSubscribe(); + if (debug.on()) debug.log("Offering new subscriber: %s", s); + subscriptionImpl.offer(FlowTube.asTubeSubscriber(s)); debugState("leaving read.subscribe: "); } @@ -676,7 +657,6 @@ final class SocketTube implements FlowTube { */ synchronized void stopReading() { stopped = true; - impl.demand.reset(); } synchronized boolean tryDecrementDemand() { @@ -733,14 +713,7 @@ final class SocketTube implements FlowTube { assert client.isSelectorThread(); debug.log("subscribe event raised"); if (Log.channel()) Log.logChannel("Start reading from {0}", channelDescr()); - readScheduler.runOrSchedule(); - if (readScheduler.isStopped() || completed) { - // if already completed or stopped we can handle any - // pending connection directly from here. - if (debug.on()) - debug.log("handling pending subscription when completed"); - handlePending(); - } + handlePending(); } @@ -953,22 +926,46 @@ final class SocketTube implements FlowTube { } } - boolean handlePending() { - ReadSubscription pending; + synchronized void offer(TubeSubscriber sub) { + ReadSubscription target = new ReadSubscription(this, sub); + ReadSubscription previous = pendingSubscriptions.getAndSet(target); + if (previous != null) { + if (debug.on()) + debug.log("read publisher: dropping pending subscriber: " + + previous.subscriber); + previous.errorRef.compareAndSet(null, errorRef.get()); + // make sure no data will be routed to the old subscriber. + previous.stopReading(); + previous.signalOnSubscribe(); + if (completed) { + previous.signalCompletion(); + } else { + previous.subscriber.dropSubscription(); + } + } + if (debug.on()) { + debug.log("read publisher got new subscriber: " + sub); + } + signalSubscribe(); + } + + synchronized boolean handlePending() { boolean subscribed = false; - while ((pending = pendingSubscriptions.poll()) != null) { + ReadSubscription current = subscription; + ReadSubscription pending = pendingSubscriptions.getAndSet(null); + if (pending != null) { subscribed = true; if (debug.on()) debug.log("handling pending subscription for %s", pending.subscriber); - ReadSubscription current = subscription; - if (current != null && current != pending && !completed) { - debug.log("dropping pending subscription for current %s", + if (current != null && !completed) { + debug.log("dropping subscription for current %s", current.subscriber); + current.stopReading(); current.subscriber.dropSubscription(); } if (debug.on()) debug.log("read demand reset to 0"); - subscriptionImpl.demand.reset(); // subscriber will increase demand if it needs to. + demand.reset(); // subscriber will increase demand if it needs to. pending.errorRef.compareAndSet(null, errorRef.get()); if (!readScheduler.isStopped()) { subscription = pending; @@ -1335,7 +1332,6 @@ final class SocketTube implements FlowTube { writePublisher.subscribe(this); } - @Override public String toString() { return dbgString(); diff --git a/src/jdk.localedata/share/classes/sun/text/resources/ext/FormatData_ja.java b/src/jdk.localedata/share/classes/sun/text/resources/ext/FormatData_ja.java index fe210146db8..d9a3ebafe14 100644 --- a/src/jdk.localedata/share/classes/sun/text/resources/ext/FormatData_ja.java +++ b/src/jdk.localedata/share/classes/sun/text/resources/ext/FormatData_ja.java @@ -87,7 +87,7 @@ public class FormatData_ja extends ParallelListResourceBundle { return new Object[][] { { "japanese.FirstYear", new String[] { // first year name - "\u5143", // "Gan"-nen + "元", // "Gan"-nen } }, }; diff --git a/test/hotspot/gtest/gc/shared/test_collectorPolicy.cpp b/test/hotspot/gtest/gc/shared/test_collectorPolicy.cpp index e335a25cb50..b5e9c6de6a0 100644 --- a/test/hotspot/gtest/gc/shared/test_collectorPolicy.cpp +++ b/test/hotspot/gtest/gc/shared/test_collectorPolicy.cpp @@ -117,7 +117,7 @@ class TestGenCollectorPolicy { initial_heap_size = InitialHeapSize; } - size_t expected = scale_by_NewRatio_aligned(initial_heap_size, GenAlignment); + size_t expected = scale_by_NewRatio_aligned(initial_heap_size, SpaceAlignment); ASSERT_EQ(expected, NewSize); } }; diff --git a/test/hotspot/gtest/gc/z/test_zPageAge.cpp b/test/hotspot/gtest/gc/z/test_zPageAge.cpp new file mode 100644 index 00000000000..1c93a380db7 --- /dev/null +++ b/test/hotspot/gtest/gc/z/test_zPageAge.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (c) 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include "gc/z/zPageAge.hpp" +#include "unittest.hpp" + +TEST(ZPageAgeRangeTest, test) { + ZPageAgeRange rangeEden = ZPageAgeRangeEden; + EXPECT_EQ(rangeEden.first(), ZPageAge::eden); + EXPECT_EQ(rangeEden.last(), ZPageAge::eden); + + ZPageAgeRange rangeYoung = ZPageAgeRangeYoung; + EXPECT_EQ(rangeYoung.first(), ZPageAge::eden); + EXPECT_EQ(rangeYoung.last(), ZPageAge::survivor14); + + ZPageAgeRange rangeSurvivor = ZPageAgeRangeSurvivor; + EXPECT_EQ(rangeSurvivor.first(), ZPageAge::survivor1); + EXPECT_EQ(rangeSurvivor.last(), ZPageAge::survivor14); + + ZPageAgeRange rangeRelocation = ZPageAgeRangeRelocation; + EXPECT_EQ(rangeRelocation.first(), ZPageAge::survivor1); + EXPECT_EQ(rangeRelocation.last(), ZPageAge::old); + + ZPageAgeRange rangeOld = ZPageAgeRangeOld; + EXPECT_EQ(rangeOld.first(), ZPageAge::old); + EXPECT_EQ(rangeOld.last(), ZPageAge::old); +} diff --git a/test/hotspot/jtreg/ProblemList-StaticJdk.txt b/test/hotspot/jtreg/ProblemList-StaticJdk.txt index c872a97b301..cb727e470f3 100644 --- a/test/hotspot/jtreg/ProblemList-StaticJdk.txt +++ b/test/hotspot/jtreg/ProblemList-StaticJdk.txt @@ -42,12 +42,3 @@ gtest/MetaspaceGtests.java#no-ccs 8356201 generic-all gtest/NMTGtests.java#nmt-detail 8356201 generic-all gtest/NMTGtests.java#nmt-off 8356201 generic-all gtest/NMTGtests.java#nmt-summary 8356201 generic-all - -# Need CDS archive -runtime/cds/NonJVMVariantLocation.java 8357632 generic-all -runtime/cds/TestCDSVMCrash.java 8357632 generic-all -runtime/cds/TestDefaultArchiveLoading.java#coops_coh 8357632 generic-all -runtime/cds/TestDefaultArchiveLoading.java#coops_nocoh 8357632 generic-all -runtime/cds/TestDefaultArchiveLoading.java#nocoops_coh 8357632 generic-all -runtime/cds/TestDefaultArchiveLoading.java#nocoops_nocoh 8357632 generic-all -serviceability/jvmti/RedefineClasses/RedefineSharedClass.java 8357632 generic-all diff --git a/test/hotspot/jtreg/compiler/c2/Test7046096.java b/test/hotspot/jtreg/compiler/c2/Test7046096.java index 46eb935e2d0..fb73bba4373 100644 --- a/test/hotspot/jtreg/compiler/c2/Test7046096.java +++ b/test/hotspot/jtreg/compiler/c2/Test7046096.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -30,6 +30,18 @@ * compiler.c2.Test7046096 */ + +/* + * @test id=stringConcatInline + * @bug 7046096 8357822 + * @summary The same test with an updated compile directive that produces + * StringBuilder-backed string concatenations. + * + * @compile -XDstringConcat=inline Test7046096.java + * @run main/othervm -Xbatch compiler.c2.Test7046096 + */ + + package compiler.c2; public class Test7046096 { diff --git a/test/hotspot/jtreg/compiler/c2/Test7179138_2.java b/test/hotspot/jtreg/compiler/c2/Test7179138_2.java index 4e89f6aced0..5f96ea942ef 100644 --- a/test/hotspot/jtreg/compiler/c2/Test7179138_2.java +++ b/test/hotspot/jtreg/compiler/c2/Test7179138_2.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * Copyright 2012 Skip Balk. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -32,6 +33,18 @@ * @author Skip Balk */ + +/* + * @test id=stringConcatInline + * @bug 7179138 + * @summary The same test with an updated compile directive that produces + * StringBuilder-backed string concatenations. + * + * @compile -XDstringConcat=inline Test7179138_2.java + * @run main/othervm -Xbatch -XX:-TieredCompilation compiler.c2.Test7179138_2 + */ + + package compiler.c2; public class Test7179138_2 { diff --git a/test/hotspot/jtreg/compiler/gcbarriers/TestImplicitNullChecks.java b/test/hotspot/jtreg/compiler/gcbarriers/TestImplicitNullChecks.java new file mode 100644 index 00000000000..34583b8fea9 --- /dev/null +++ b/test/hotspot/jtreg/compiler/gcbarriers/TestImplicitNullChecks.java @@ -0,0 +1,234 @@ +/* + * Copyright (c) 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.gcbarriers; + +import compiler.lib.ir_framework.*; +import java.lang.invoke.VarHandle; +import java.lang.invoke.MethodHandles; +import java.lang.ref.Reference; +import java.lang.ref.ReferenceQueue; +import java.lang.ref.SoftReference; +import java.lang.ref.WeakReference; +import jdk.test.lib.Asserts; + +/** + * @test + * @summary Test that implicit null checks are generated as expected for + different GC memory accesses. + * @library /test/lib / + * @run driver compiler.gcbarriers.TestImplicitNullChecks + */ + + +public class TestImplicitNullChecks { + + static class Outer { + Object f; + } + + static class OuterWithVolatileField { + volatile Object f; + } + + static final VarHandle fVarHandle; + static { + MethodHandles.Lookup l = MethodHandles.lookup(); + try { + fVarHandle = l.findVarHandle(Outer.class, "f", Object.class); + } catch (Exception e) { + throw new Error(e); + } + } + + public static void main(String[] args) { + TestFramework.runWithFlags("-XX:CompileCommand=inline,java.lang.ref.*::*", + "-XX:-TieredCompilation"); + } + + @Test + // On AIX, implicit null checks are limited because the zero page is + // readable (but not writable). See os::zero_page_read_protected(). + @IR(applyIfPlatform = {"aix", "false"}, + applyIfOr = {"UseZGC", "true", "UseG1GC", "true"}, + counts = {IRNode.NULL_CHECK, "1"}, + phase = CompilePhase.FINAL_CODE) + static Object testLoad(Outer o) { + return o.f; + } + + @Test + // On aarch64, volatile loads always use indirect memory operands, which + // leads to a pattern that cannot be exploited by the current C2 analysis. + // On PPC64, volatile loads are preceded by membar_volatile instructions, + // which also inhibits the current C2 analysis. + @IR(applyIfPlatformAnd = {"aarch64", "false", "ppc", "false"}, + applyIfOr = {"UseZGC", "true", "UseG1GC", "true"}, + counts = {IRNode.NULL_CHECK, "1"}, + phase = CompilePhase.FINAL_CODE) + static Object testLoadVolatile(OuterWithVolatileField o) { + return o.f; + } + + @Run(test = {"testLoad", + "testLoadVolatile"}, + mode = RunMode.STANDALONE) + static void runLoadTests() { + { + Outer o = new Outer(); + // Trigger compilation with implicit null check. + for (int i = 0; i < 10_000; i++) { + testLoad(o); + } + // Trigger null pointer exception. + o = null; + boolean nullPointerException = false; + try { + testLoad(o); + } catch (NullPointerException e) { nullPointerException = true; } + Asserts.assertTrue(nullPointerException); + } + { + OuterWithVolatileField o = new OuterWithVolatileField(); + // Trigger compilation with implicit null check. + for (int i = 0; i < 10_000; i++) { + testLoadVolatile(o); + } + // Trigger null pointer exception. + o = null; + boolean nullPointerException = false; + try { + testLoadVolatile(o); + } catch (NullPointerException e) { nullPointerException = true; } + Asserts.assertTrue(nullPointerException); + } + } + + @Test + // G1 and ZGC stores cannot be currently used to implement implicit null + // checks, because they expand into multiple memory access instructions that + // are not necessarily located at the initial instruction start address. + @IR(applyIfOr = {"UseZGC", "true", "UseG1GC", "true"}, + failOn = IRNode.NULL_CHECK, + phase = CompilePhase.FINAL_CODE) + static void testStore(Outer o, Object o1) { + o.f = o1; + } + + @Run(test = {"testStore"}) + static void runStoreTests() { + { + Outer o = new Outer(); + Object o1 = new Object(); + testStore(o, o1); + } + } + + @Test + // G1 and ZGC compare-and-exchange operations cannot be currently used to + // implement implicit null checks, because they expand into multiple memory + // access instructions that are not necessarily located at the initial + // instruction start address. The same holds for testCompareAndSwap and + // testGetAndSet below. + @IR(applyIfOr = {"UseZGC", "true", "UseG1GC", "true"}, + failOn = IRNode.NULL_CHECK, + phase = CompilePhase.FINAL_CODE) + static Object testCompareAndExchange(Outer o, Object oldVal, Object newVal) { + return fVarHandle.compareAndExchange(o, oldVal, newVal); + } + + @Test + @IR(applyIfOr = {"UseZGC", "true", "UseG1GC", "true"}, + failOn = IRNode.NULL_CHECK, + phase = CompilePhase.FINAL_CODE) + static boolean testCompareAndSwap(Outer o, Object oldVal, Object newVal) { + return fVarHandle.compareAndSet(o, oldVal, newVal); + } + + @Test + @IR(applyIfOr = {"UseZGC", "true", "UseG1GC", "true"}, + failOn = IRNode.NULL_CHECK, + phase = CompilePhase.FINAL_CODE) + static Object testGetAndSet(Outer o, Object newVal) { + return fVarHandle.getAndSet(o, newVal); + } + + @Run(test = {"testCompareAndExchange", + "testCompareAndSwap", + "testGetAndSet"}) + static void runAtomicTests() { + { + Outer o = new Outer(); + Object oldVal = new Object(); + Object newVal = new Object(); + testCompareAndExchange(o, oldVal, newVal); + } + { + Outer o = new Outer(); + Object oldVal = new Object(); + Object newVal = new Object(); + testCompareAndSwap(o, oldVal, newVal); + } + { + Outer o = new Outer(); + Object oldVal = new Object(); + Object newVal = new Object(); + testGetAndSet(o, newVal); + } + } + + @Test + // G1 reference loads use indirect memory operands, which leads to a pattern + // that cannot be exploited by the current C2 analysis. The same holds for + // testLoadWeakReference. + @IR(applyIf = {"UseZGC", "true"}, + counts = {IRNode.NULL_CHECK, "1"}, + phase = CompilePhase.FINAL_CODE) + static Object testLoadSoftReference(SoftReference ref) { + return ref.get(); + } + + @Test + @IR(applyIf = {"UseZGC", "true"}, + counts = {IRNode.NULL_CHECK, "1"}, + phase = CompilePhase.FINAL_CODE) + static Object testLoadWeakReference(WeakReference ref) { + return ref.get(); + } + + @Run(test = {"testLoadSoftReference", + "testLoadWeakReference"}) + static void runReferenceTests() { + { + Object o1 = new Object(); + SoftReference sref = new SoftReference(o1); + Object o2 = testLoadSoftReference(sref); + } + { + Object o1 = new Object(); + WeakReference wref = new WeakReference(o1); + Object o2 = testLoadWeakReference(wref); + } + } + +} diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java index 96b62a2b12a..9388e1a8892 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java @@ -1499,6 +1499,11 @@ public class IRNode { trapNodes(NULL_ASSERT_TRAP, "null_assert"); } + public static final String NULL_CHECK = PREFIX + "NULL_CHECK" + POSTFIX; + static { + machOnlyNameRegex(NULL_CHECK, "NullCheck"); + } + public static final String NULL_CHECK_TRAP = PREFIX + "NULL_CHECK_TRAP" + POSTFIX; static { trapNodes(NULL_CHECK_TRAP, "null_check"); diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/test/IREncodingPrinter.java b/test/hotspot/jtreg/compiler/lib/ir_framework/test/IREncodingPrinter.java index 4ad95ab786f..eef9998ebf8 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/test/IREncodingPrinter.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/test/IREncodingPrinter.java @@ -62,6 +62,7 @@ public class IREncodingPrinter { // as adding non-existent platforms can lead to skipped tests. private static final List irTestingPlatforms = new ArrayList(Arrays.asList( // os.family + "aix", "linux", "mac", "windows", @@ -346,7 +347,9 @@ public class IREncodingPrinter { } String os = ""; - if (Platform.isLinux()) { + if (Platform.isAix()) { + os = "aix"; + } else if (Platform.isLinux()) { os = "linux"; } else if (Platform.isOSX()) { os = "mac"; diff --git a/test/hotspot/jtreg/gc/arguments/TestMinAndInitialSurvivorRatioFlags.java b/test/hotspot/jtreg/gc/arguments/TestMinAndInitialSurvivorRatioFlags.java index 5f585575e7a..6323e5c50cf 100644 --- a/test/hotspot/jtreg/gc/arguments/TestMinAndInitialSurvivorRatioFlags.java +++ b/test/hotspot/jtreg/gc/arguments/TestMinAndInitialSurvivorRatioFlags.java @@ -162,12 +162,12 @@ public class TestMinAndInitialSurvivorRatioFlags { MemoryUsage survivorUsage = HeapRegionUsageTool.getSurvivorUsage(); long alignedNewSize = edenUsage.getMax() + 2 * survivorUsage.getMax(); - long generationAlignment = wb.psHeapGenerationAlignment(); + long spaceAlignment = wb.getHeapSpaceAlignment(); if (survivorRatio >= 0) { // -XX:SurvivorRatio was passed to JVM, actual ratio should be SurvivorRatio + 2 long expectedSize = HeapRegionUsageTool.alignDown(alignedNewSize / (survivorRatio + 2), - generationAlignment); + spaceAlignment); if (survivorUsage.getCommitted() != expectedSize) { throw new RuntimeException("Expected survivor size is: " + expectedSize @@ -177,7 +177,7 @@ public class TestMinAndInitialSurvivorRatioFlags { // In case of initial ratio verification or disabled adaptive size policy // ratio should be equal to InitialSurvivorRatio value long expectedSize = HeapRegionUsageTool.alignDown(alignedNewSize / initRatio, - generationAlignment); + spaceAlignment); if (survivorUsage.getCommitted() != expectedSize) { throw new RuntimeException("Expected survivor size is: " + expectedSize + ", but observed size is: " + survivorUsage.getCommitted()); @@ -186,9 +186,9 @@ public class TestMinAndInitialSurvivorRatioFlags { // In any other case actual survivor ratio should not be lower than MinSurvivorRatio // or is should be equal to InitialSurvivorRatio long expectedMinSize = HeapRegionUsageTool.alignDown(alignedNewSize / minRatio, - generationAlignment); + spaceAlignment); long expectedInitSize = HeapRegionUsageTool.alignDown(alignedNewSize / initRatio, - generationAlignment); + spaceAlignment); if (survivorUsage.getCommitted() != expectedInitSize && survivorUsage.getCommitted() < expectedMinSize) { throw new RuntimeException("Expected survivor size should be " + expectedMinSize diff --git a/test/hotspot/jtreg/gc/arguments/TestNewRatioFlag.java b/test/hotspot/jtreg/gc/arguments/TestNewRatioFlag.java index 86c4c7af8bc..41fa1826799 100644 --- a/test/hotspot/jtreg/gc/arguments/TestNewRatioFlag.java +++ b/test/hotspot/jtreg/gc/arguments/TestNewRatioFlag.java @@ -146,10 +146,8 @@ public class TestNewRatioFlag { long newSize = initEden + 2 * initSurv; // See GenArguments::scale_by_NewRatio_aligned for calculation in the JVM. - long alignedDownNewSize = HeapRegionUsageTool.alignDown(initHeap / (expectedRatio + 1), + long expectedNewSize = HeapRegionUsageTool.alignDown(initHeap / (expectedRatio + 1), wb.getHeapSpaceAlignment()); - long expectedNewSize = HeapRegionUsageTool.alignUp(alignedDownNewSize, - wb.psVirtualSpaceAlignment()); if (expectedNewSize != newSize) { throw new RuntimeException("Expected young gen size is: " + expectedNewSize diff --git a/test/hotspot/jtreg/gc/arguments/TestNewSizeFlags.java b/test/hotspot/jtreg/gc/arguments/TestNewSizeFlags.java index d3152073c55..2f454940863 100644 --- a/test/hotspot/jtreg/gc/arguments/TestNewSizeFlags.java +++ b/test/hotspot/jtreg/gc/arguments/TestNewSizeFlags.java @@ -182,8 +182,6 @@ public class TestNewSizeFlags { private static final GCTypes.YoungGCType YOUNG_GC_TYPE = GCTypes.YoungGCType.getYoungGCType(); private static final long HEAP_SPACE_ALIGNMENT = WB.getHeapSpaceAlignment(); private static final long HEAP_ALIGNMENT = WB.getHeapAlignment(); - private static final long PS_VIRTUAL_SPACE_ALIGNMENT = - (YOUNG_GC_TYPE == GCTypes.YoungGCType.PSNew) ? WB.psVirtualSpaceAlignment() : 0; public static final int ARRAY_LENGTH = 100; public static final int CHUNK_SIZE = 1024; @@ -303,9 +301,7 @@ public class TestNewSizeFlags { case DefNew: return HeapRegionUsageTool.alignDown(value, HEAP_SPACE_ALIGNMENT); case PSNew: - return HeapRegionUsageTool.alignUp(HeapRegionUsageTool.alignDown(value, - HEAP_SPACE_ALIGNMENT), - PS_VIRTUAL_SPACE_ALIGNMENT); + return HeapRegionUsageTool.alignDown(value, HEAP_SPACE_ALIGNMENT); case G1: return HeapRegionUsageTool.alignUp(value, WB.g1RegionSize()); default: diff --git a/test/hotspot/jtreg/gc/arguments/TestSurvivorRatioFlag.java b/test/hotspot/jtreg/gc/arguments/TestSurvivorRatioFlag.java index 90a29e78c12..ea2a20b3dc9 100644 --- a/test/hotspot/jtreg/gc/arguments/TestSurvivorRatioFlag.java +++ b/test/hotspot/jtreg/gc/arguments/TestSurvivorRatioFlag.java @@ -154,7 +154,7 @@ public class TestSurvivorRatioFlag { long youngGenSize = edenUsage.getMax() + 2 * survivorUsage.getMax(); // for Paralle GC Min/InitialSurvivorRatio = SurvivorRatio + 2 long expectedSize = HeapRegionUsageTool.alignDown(youngGenSize / (expectedRatio + 2), - wb.psHeapGenerationAlignment()); + wb.getHeapSpaceAlignment()); if (expectedSize != survivorUsage.getCommitted()) { throw new RuntimeException("Expected survivor size is: " + expectedSize diff --git a/test/hotspot/jtreg/runtime/cds/NonJVMVariantLocation.java b/test/hotspot/jtreg/runtime/cds/NonJVMVariantLocation.java index 81e931e450e..24772d620ad 100644 --- a/test/hotspot/jtreg/runtime/cds/NonJVMVariantLocation.java +++ b/test/hotspot/jtreg/runtime/cds/NonJVMVariantLocation.java @@ -26,6 +26,7 @@ * @test * @summary Test that CDS archive can be loaded if the archive is in a non-JVM variant directory. * @bug 8353504 + * @requires !jdk.static * @requires vm.cds * @requires vm.flagless * @requires vm.flavor == "server" diff --git a/test/hotspot/jtreg/runtime/cds/appcds/LambdaWithUseImplMethodHandle.java b/test/hotspot/jtreg/runtime/cds/appcds/LambdaWithUseImplMethodHandle.java index 0c747168945..6b7a4f68bbf 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/LambdaWithUseImplMethodHandle.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/LambdaWithUseImplMethodHandle.java @@ -28,8 +28,6 @@ * @summary CDS cannot archive lambda proxy with useImplMethodHandle * @requires vm.cds * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds /test/hotspot/jtreg/runtime/cds/appcds/test-classes * @build pkg1.BaseWithProtectedMethod * @build pkg2.Child diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/AOTCacheSupportForCustomLoaders.java b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/AOTCacheSupportForCustomLoaders.java index ae00477e67b..9461957ef2c 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/AOTCacheSupportForCustomLoaders.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/AOTCacheSupportForCustomLoaders.java @@ -27,8 +27,6 @@ * @summary Test AOT cache support for array classes in custom class loaders. * @bug 8353298 8356838 * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds/test-classes * @build ReturnIntegerAsString * @build AOTCacheSupportForCustomLoaders diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/AOTLoggingTag.java b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/AOTLoggingTag.java index 5499063ebbd..896df7ca496 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/AOTLoggingTag.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/AOTLoggingTag.java @@ -34,7 +34,6 @@ * @run driver AOTLoggingTag */ -import java.io.File; import jdk.test.lib.cds.CDSTestUtils; import jdk.test.lib.helpers.ClassFileInstaller; import jdk.test.lib.process.OutputAnalyzer; @@ -59,7 +58,7 @@ public class AOTLoggingTag { "-cp", appJar, helloClass); out = CDSTestUtils.executeAndLog(pb, "train"); - out.shouldContain("[info][aot] Writing binary AOTConfiguration file:"); + out.shouldContain("[aot] Writing binary AOTConfiguration file:"); out.shouldHaveExitValue(0); //---------------------------------------------------------------------- @@ -71,7 +70,7 @@ public class AOTLoggingTag { "-Xlog:aot", "-cp", appJar); out = CDSTestUtils.executeAndLog(pb, "asm"); - out.shouldContain("[info][aot] Opened AOT configuration file hello.aotconfig"); + out.shouldContain("[aot] Opened AOT configuration file hello.aotconfig"); out.shouldHaveExitValue(0); //---------------------------------------------------------------------- @@ -81,7 +80,7 @@ public class AOTLoggingTag { "-Xlog:aot", "-cp", appJar, helloClass); out = CDSTestUtils.executeAndLog(pb, "prod"); - out.shouldContain("[info][aot] Opened AOT cache hello.aot"); + out.shouldContain("[aot] Opened AOT cache hello.aot"); out.shouldHaveExitValue(0); //---------------------------------------------------------------------- @@ -92,7 +91,7 @@ public class AOTLoggingTag { "-cp", appJar, helloClass); out = CDSTestUtils.executeAndLog(pb, "prod"); out.shouldNotContain("No tag set matches selection: aot+heap"); - out.shouldContain("[info][aot,heap] resolve subgraph java.lang.Integer$IntegerCache"); + out.shouldContain("[aot,heap] resolve subgraph java.lang.Integer$IntegerCache"); out.shouldHaveExitValue(0); //---------------------------------------------------------------------- @@ -102,7 +101,7 @@ public class AOTLoggingTag { "-XX:AOTMode=on", "-cp", appJar, helloClass); out = CDSTestUtils.executeAndLog(pb, "prod"); - out.shouldContain("[error][aot] An error has occurred while processing the AOT cache. Run with -Xlog:aot for details."); + out.shouldContain("[aot] An error has occurred while processing the AOT cache. Run with -Xlog:aot for details."); out.shouldNotHaveExitValue(0); } diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/ExcludedClasses.java b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/ExcludedClasses.java index 4f2ff4f0f76..c808cd95bc7 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/ExcludedClasses.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/ExcludedClasses.java @@ -26,8 +26,6 @@ * @test * @summary Test how various AOT optimizations handle classes that are excluded from the AOT cache. * @requires vm.cds.write.archived.java.heap - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/jdk/lib/testlibrary /test/lib * /test/hotspot/jtreg/runtime/cds/appcds/aotCache/test-classes * @build ExcludedClasses CustyWithLoop diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/HelloAOTCache.java b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/HelloAOTCache.java index 007e51004ec..f3326ac1ed6 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/HelloAOTCache.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/HelloAOTCache.java @@ -27,8 +27,6 @@ * @test * @summary Sanity test for AOTCache * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/lib * @build HelloAOTCache * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar HelloAOTCacheApp diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/JavaAgent.java b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/JavaAgent.java index 7965be8d00a..070f6df9834 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/JavaAgent.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/JavaAgent.java @@ -28,8 +28,6 @@ * @summary -javaagent should be allowed in AOT workflow. However, classes transformed/redefined by agents will not * be cached. * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds/test-classes * @build JavaAgent JavaAgentTransformer Util * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar JavaAgentApp JavaAgentApp$ShouldBeTransformed diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/ManagementAgent.java b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/ManagementAgent.java index abbdd3551b7..c558d293b2a 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/ManagementAgent.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/ManagementAgent.java @@ -28,8 +28,6 @@ * @bug 8352187 * @summary ManagementAgent will not be started during AOT cache creation. * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/lib * @build HelloAOTCache * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar HelloAOTCacheApp diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/PackageInfoClass.java b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/PackageInfoClass.java index 0fff74236f1..014524afde6 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/PackageInfoClass.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/PackageInfoClass.java @@ -27,8 +27,6 @@ * @summary AOT cache handling for package-info class loaded by jdk/internal/loader/ClassLoaders$BootClassLoader * @bug 8354558 * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/lib /test/jdk/java/lang/Package/bootclasspath/boot * @build PackageInfoClass foo.Foo foo.MyAnnotation foo.package-info * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar boot.jar foo.Foo foo.package-info foo.MyAnnotation diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/SpecialCacheNames.java b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/SpecialCacheNames.java index 89aa9e441a4..e9d9c70a358 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/SpecialCacheNames.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/SpecialCacheNames.java @@ -27,8 +27,6 @@ * @summary Use special characters in the name of the cache file specified by -XX:AOTCacheOutput * Make sure these characters are passed to the child JVM process that assembles the cache. * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/lib * @build SpecialCacheNames * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar MyTestApp diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/VerifierFailOver.java b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/VerifierFailOver.java index 18caa08c117..50b47e4424d 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/VerifierFailOver.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/VerifierFailOver.java @@ -26,8 +26,6 @@ * @test * @summary Sanity test for AOTCache * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/lib * @build VerifierFailOver_Helper * @build VerifierFailOver diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AOTCacheWithZGC.java b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AOTCacheWithZGC.java index 96f08004fb2..a7c7362b845 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AOTCacheWithZGC.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AOTCacheWithZGC.java @@ -28,8 +28,6 @@ * @bug 8352775 * @requires vm.cds * @requires vm.gc.Z - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/lib * @build AOTCacheWithZGC * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar AOTCacheWithZGCApp diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AOTLoaderConstraintsTest.java b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AOTLoaderConstraintsTest.java index 63be2038907..f82cf2737fb 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AOTLoaderConstraintsTest.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AOTLoaderConstraintsTest.java @@ -26,8 +26,6 @@ * @test Make sure loader constraints are passed from AOT preimage to final image. * @bug 8348426 * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/jdk/lib/testlibrary /test/lib * @build AOTLoaderConstraintsTest BootClass * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar boot.jar BootClass diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AddExports.java b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AddExports.java index 2a63a4837c2..fc3e945cf9d 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AddExports.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AddExports.java @@ -28,8 +28,6 @@ * @bug 8352437 * @requires vm.cds * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds * @run driver AddExports */ diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AddOpens.java b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AddOpens.java index 5ae8c4a6bb8..d3626d30c7e 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AddOpens.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AddOpens.java @@ -26,8 +26,6 @@ * @test * @requires vm.cds * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds * @run driver AddOpens * @summary sanity test the --add-opens option diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AddReads.java b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AddReads.java index c1dbc602755..5c9364aa079 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AddReads.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AddReads.java @@ -27,8 +27,6 @@ * @bug 8354083 * @requires vm.cds * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds * @run driver AddReads * @summary sanity test the --add-reads option diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BulkLoaderTest.java b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BulkLoaderTest.java index 90fd0f33bab..30f7ce12ca0 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BulkLoaderTest.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BulkLoaderTest.java @@ -29,8 +29,6 @@ /* * @test id=static * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/jdk/lib/testlibrary /test/lib /test/hotspot/jtreg/runtime/cds/appcds/test-classes * @build InitiatingLoaderTester BadOldClassA BadOldClassB * @build jdk.test.whitebox.WhiteBox BulkLoaderTest SimpleCusty @@ -45,8 +43,6 @@ /* * @test id=dynamic * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/jdk/lib/testlibrary /test/lib /test/hotspot/jtreg/runtime/cds/appcds/test-classes * @build InitiatingLoaderTester BadOldClassA BadOldClassB * @build jdk.test.whitebox.WhiteBox BulkLoaderTest SimpleCusty @@ -61,8 +57,6 @@ /* * @test id=aot * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/jdk/lib/testlibrary /test/lib /test/hotspot/jtreg/runtime/cds/appcds/test-classes * @build jdk.test.whitebox.WhiteBox InitiatingLoaderTester BadOldClassA BadOldClassB * @build BulkLoaderTest SimpleCusty diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/FakeCodeLocation.java b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/FakeCodeLocation.java index 1ffc904963a..5da2e2754e8 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/FakeCodeLocation.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/FakeCodeLocation.java @@ -26,8 +26,6 @@ * @test Do not cache classes that are loaded from a fake location. * @bug 8352001 * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/jdk/lib/testlibrary /test/lib * @build FakeCodeLocation * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar FakeCodeLocationApp diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/GeneratedInternedString.java b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/GeneratedInternedString.java index dcb1c59c09f..0ee59bf5afd 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/GeneratedInternedString.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/GeneratedInternedString.java @@ -28,8 +28,6 @@ * @requires vm.cds.write.archived.java.heap * @requires vm.cds.supports.aot.class.linking * @requires vm.debug - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/jdk/lib/testlibrary /test/lib /test/hotspot/jtreg/runtime/cds/appcds * @build GeneratedInternedString * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar GeneratedInternedStringApp diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/LambdaInExcludedClass.java b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/LambdaInExcludedClass.java index 9ed2524bff1..c91e999c40f 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/LambdaInExcludedClass.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/LambdaInExcludedClass.java @@ -27,8 +27,6 @@ * @bug 8349888 * @requires vm.cds.supports.aot.class.linking * @requires vm.gc.Epsilon - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/jdk/lib/testlibrary /test/lib * @build LambdaInExcludedClass * @run driver jdk.test.lib.helpers.ClassFileInstaller LambdaInExcludedClassApp diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/MethodHandleTest.java b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/MethodHandleTest.java index f7a26a39db1..972dc287af5 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/MethodHandleTest.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/MethodHandleTest.java @@ -27,8 +27,6 @@ * @requires vm.cds.write.archived.java.heap * @requires vm.cds.supports.aot.class.linking * @requires vm.debug - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/jdk/lib/testlibrary /test/lib /test/hotspot/jtreg/runtime/cds/appcds * @build MethodHandleTest * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar mh.jar diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/NonFinalStaticWithInitVal.java b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/NonFinalStaticWithInitVal.java index ba21f5f98fb..17ff399d23c 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/NonFinalStaticWithInitVal.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/NonFinalStaticWithInitVal.java @@ -27,8 +27,6 @@ * @summary Handling of non-final static string that has an initial value * @bug 8356125 * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/lib * @build NonFinalStaticWithInitVal_Helper * @build NonFinalStaticWithInitVal diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/StringConcatStress.java b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/StringConcatStress.java index 3786c294791..81bf28010b1 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/StringConcatStress.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/StringConcatStress.java @@ -34,8 +34,6 @@ /* * @test id=aot * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/lib * @build StringConcatStress * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar StringConcatStressApp diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/TestSetupAOTTest.java b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/TestSetupAOTTest.java index f88af3caed5..118b4c6af1d 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/TestSetupAOTTest.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/TestSetupAOTTest.java @@ -28,8 +28,6 @@ * is used for running HotSpot tests in the "AOT mode" * (E.g., make test JTREG=AOT_JDK=true TEST=open/test/hotspot/jtreg/runtime/invokedynamic) * @requires vm.cds - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/lib /test/setup_aot * @build TestSetupAOTTest JavacBenchApp TestSetupAOT * @run driver jdk.test.lib.helpers.ClassFileInstaller diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/TrainingRun.java b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/TrainingRun.java index fd896fd6958..df466151f98 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/TrainingRun.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/TrainingRun.java @@ -27,8 +27,6 @@ * @summary -XX:AOTMode=record should not interfere with app execution: (1) thread creation; (2) exit code * @bug 8351327 * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/jdk/lib/testlibrary /test/lib * @build TrainingRun * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar MyTestApp diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/WeakReferenceTest.java b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/WeakReferenceTest.java index ae5cd5b3429..3b33d63b0d2 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/WeakReferenceTest.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/WeakReferenceTest.java @@ -27,8 +27,6 @@ * @requires vm.cds.write.archived.java.heap * @requires vm.cds.supports.aot.class.linking * @requires vm.debug - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/jdk/lib/testlibrary /test/lib /test/hotspot/jtreg/runtime/cds/appcds * @build WeakReferenceTest * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar weakref.jar diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotProfile/AOTProfileFlags.java b/test/hotspot/jtreg/runtime/cds/appcds/aotProfile/AOTProfileFlags.java index e2285a59600..fe9c7e7bbb7 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotProfile/AOTProfileFlags.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotProfile/AOTProfileFlags.java @@ -26,8 +26,6 @@ * @test * @summary Sanity test of combinations of the diagnostic flags [+-]AOTRecordTraining and [+-]AOTReplayTraining * @requires vm.cds - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @requires vm.cds.supports.aot.class.linking * @requires vm.flagless * @library /test/lib /test/setup_aot /test/hotspot/jtreg/runtime/cds/appcds/test-classes diff --git a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/ArchiveHeapTestClass.java b/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/ArchiveHeapTestClass.java index 819db99a549..fed56937f2f 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/ArchiveHeapTestClass.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/ArchiveHeapTestClass.java @@ -28,8 +28,6 @@ * @summary Test for the -XX:ArchiveHeapTestClass flag * @requires vm.debug == true & vm.cds.write.archived.java.heap * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @modules java.logging * @library /test/jdk/lib/testlibrary /test/lib * /test/hotspot/jtreg/runtime/cds/appcds diff --git a/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesAsCollectorTest.java b/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesAsCollectorTest.java index ba7c0def86a..1061207f764 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesAsCollectorTest.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesAsCollectorTest.java @@ -28,8 +28,6 @@ * @summary Run the MethodHandlesAsCollectorTest.java test in CDSAppTester::AOT workflow. * @requires vm.cds & vm.compMode != "Xcomp" * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @comment Some of the tests run excessively slowly with -Xcomp. The original * tests aren't executed with -Xcomp in the CI pipeline, so let's exclude * the generated tests from -Xcomp execution as well. diff --git a/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesCastFailureTest.java b/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesCastFailureTest.java index 3f5008ca8c3..3349d146e10 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesCastFailureTest.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesCastFailureTest.java @@ -28,8 +28,6 @@ * @summary Run the MethodHandlesCastFailureTest.java test in CDSAppTester::AOT workflow. * @requires vm.cds & vm.compMode != "Xcomp" * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @comment Some of the tests run excessively slowly with -Xcomp. The original * tests aren't executed with -Xcomp in the CI pipeline, so let's exclude * the generated tests from -Xcomp execution as well. diff --git a/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesGeneralTest.java b/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesGeneralTest.java index 70f02b9a3d7..bba3f367505 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesGeneralTest.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesGeneralTest.java @@ -28,8 +28,6 @@ * @summary Run the MethodHandlesGeneralTest.java test in CDSAppTester::AOT workflow. * @requires vm.cds & vm.compMode != "Xcomp" * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @comment Some of the tests run excessively slowly with -Xcomp. The original * tests aren't executed with -Xcomp in the CI pipeline, so let's exclude * the generated tests from -Xcomp execution as well. diff --git a/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesInvokersTest.java b/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesInvokersTest.java index 7de76f5e99a..9ce57a9c66b 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesInvokersTest.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesInvokersTest.java @@ -28,8 +28,6 @@ * @summary Run the MethodHandlesInvokersTest.java test in CDSAppTester::AOT workflow. * @requires vm.cds & vm.compMode != "Xcomp" * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @comment Some of the tests run excessively slowly with -Xcomp. The original * tests aren't executed with -Xcomp in the CI pipeline, so let's exclude * the generated tests from -Xcomp execution as well. diff --git a/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesPermuteArgumentsTest.java b/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesPermuteArgumentsTest.java index 1e4bfebce9d..8f75eff0dc7 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesPermuteArgumentsTest.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesPermuteArgumentsTest.java @@ -28,8 +28,6 @@ * @summary Run the MethodHandlesPermuteArgumentsTest.java test in CDSAppTester::AOT workflow. * @requires vm.cds & vm.compMode != "Xcomp" * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @comment Some of the tests run excessively slowly with -Xcomp. The original * tests aren't executed with -Xcomp in the CI pipeline, so let's exclude * the generated tests from -Xcomp execution as well. diff --git a/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesSpreadArgumentsTest.java b/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesSpreadArgumentsTest.java index 19755121282..8b431232825 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesSpreadArgumentsTest.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesSpreadArgumentsTest.java @@ -28,8 +28,6 @@ * @summary Run the MethodHandlesSpreadArgumentsTest.java test in CDSAppTester::AOT workflow. * @requires vm.cds & vm.compMode != "Xcomp" * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @comment Some of the tests run excessively slowly with -Xcomp. The original * tests aren't executed with -Xcomp in the CI pipeline, so let's exclude * the generated tests from -Xcomp execution as well. diff --git a/test/hotspot/jtreg/runtime/cds/appcds/resolvedConstants/AOTLinkedLambdas.java b/test/hotspot/jtreg/runtime/cds/appcds/resolvedConstants/AOTLinkedLambdas.java index e187f408fb4..ecfaa265923 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/resolvedConstants/AOTLinkedLambdas.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/resolvedConstants/AOTLinkedLambdas.java @@ -28,8 +28,6 @@ * @bug 8340836 * @requires vm.cds * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds/test-classes/ * @build AOTLinkedLambdas * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar diff --git a/test/hotspot/jtreg/runtime/cds/appcds/resolvedConstants/AOTLinkedVarHandles.java b/test/hotspot/jtreg/runtime/cds/appcds/resolvedConstants/AOTLinkedVarHandles.java index e262c55beea..4586b94b519 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/resolvedConstants/AOTLinkedVarHandles.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/resolvedConstants/AOTLinkedVarHandles.java @@ -28,8 +28,6 @@ * @bug 8343245 * @requires vm.cds * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/lib * @build AOTLinkedVarHandles * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar diff --git a/test/hotspot/jtreg/serviceability/jvmti/thread/GetCurrentContendedMonitor/contmon01/contmon01.java b/test/hotspot/jtreg/serviceability/jvmti/thread/GetCurrentContendedMonitor/contmon01/contmon01.java index 5bc4d4fd2b2..a4912c7e6d2 100644 --- a/test/hotspot/jtreg/serviceability/jvmti/thread/GetCurrentContendedMonitor/contmon01/contmon01.java +++ b/test/hotspot/jtreg/serviceability/jvmti/thread/GetCurrentContendedMonitor/contmon01/contmon01.java @@ -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 @@ -154,9 +154,9 @@ class contmon01Task implements Runnable { System.out.println("check #2 done"); System.out.println("notifying main thread"); + System.out.println("thread is going to loop while is true ..."); contmon01.startingBarrier = false; - System.out.println("thread is going to loop while is true ..."); int i = 0; int n = 1000; while (flag) { diff --git a/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/GenClassPoolJar.java b/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/GenClassPoolJar.java index fb3fb4d0e8e..cea00fc2efc 100644 --- a/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/GenClassPoolJar.java +++ b/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/GenClassPoolJar.java @@ -187,7 +187,9 @@ public class GenClassPoolJar { StandardJavaFileManager sjfm = compiler.getStandardFileManager(null, null, null); Iterable fileObjects = sjfm.getJavaFileObjects(files); JavaCompiler.CompilationTask task = compiler.getTask(null, null, null, optionList, null, fileObjects); - task.call(); + if (!task.call()) { + throw new AssertionError("test failed due to a compilation error"); + } sjfm.close(); } diff --git a/test/hotspot/jtreg/vmTestbase/vm/compiler/optimizations/stringconcat/implicit/Implicit01/cs_disabled/TestDescription.java b/test/hotspot/jtreg/vmTestbase/vm/compiler/optimizations/stringconcat/implicit/Implicit01/cs_disabled/TestDescription.java index 2eddeafa2c9..13bc3b4d640 100644 --- a/test/hotspot/jtreg/vmTestbase/vm/compiler/optimizations/stringconcat/implicit/Implicit01/cs_disabled/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/vm/compiler/optimizations/stringconcat/implicit/Implicit01/cs_disabled/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -33,3 +33,17 @@ * @run main/othervm -XX:-CompactStrings vm.compiler.optimizations.stringconcat.implicit.Implicit01 */ + +/* + * @test id=stringConcatInline + * + * @summary The same test with an updated compile directive that produces + * StringBuilder-backed string concatenations. + * VM Testbase keywords: [jit, quick] + * + * @library /vmTestbase + * /test/lib + * @compile -XDstringConcat=inline ../../Implicit01.java + * @run main/othervm -XX:-CompactStrings vm.compiler.optimizations.stringconcat.implicit.Implicit01 + */ + diff --git a/test/hotspot/jtreg/vmTestbase/vm/compiler/optimizations/stringconcat/implicit/Implicit01/cs_enabled/TestDescription.java b/test/hotspot/jtreg/vmTestbase/vm/compiler/optimizations/stringconcat/implicit/Implicit01/cs_enabled/TestDescription.java index 7e7295f5108..87e8bdcbcc7 100644 --- a/test/hotspot/jtreg/vmTestbase/vm/compiler/optimizations/stringconcat/implicit/Implicit01/cs_enabled/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/vm/compiler/optimizations/stringconcat/implicit/Implicit01/cs_enabled/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -33,3 +33,17 @@ * @run main/othervm -XX:+CompactStrings vm.compiler.optimizations.stringconcat.implicit.Implicit01 */ + +/* + * @test id=stringConcatInline + * + * @summary The same test with an updated compile directive that produces + * StringBuilder-backed string concatenations. + * VM Testbase keywords: [jit, quick] + * + * @library /vmTestbase + * /test/lib + * @compile -XDstringConcat=inline ../../Implicit01.java + * @run main/othervm -XX:+CompactStrings vm.compiler.optimizations.stringconcat.implicit.Implicit01 + */ + diff --git a/test/hotspot/jtreg/vmTestbase/vm/compiler/optimizations/stringconcat/implicit/Merge01/cs_disabled/TestDescription.java b/test/hotspot/jtreg/vmTestbase/vm/compiler/optimizations/stringconcat/implicit/Merge01/cs_disabled/TestDescription.java index c56a554b1da..cbbe4d97ee4 100644 --- a/test/hotspot/jtreg/vmTestbase/vm/compiler/optimizations/stringconcat/implicit/Merge01/cs_disabled/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/vm/compiler/optimizations/stringconcat/implicit/Merge01/cs_disabled/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -33,3 +33,17 @@ * @run main/othervm -XX:-CompactStrings vm.compiler.optimizations.stringconcat.implicit.Merge01 */ + +/* + * @test id=stringConcatInline + * + * @summary The same test with an updated compile directive that produces + * StringBuilder-backed string concatenations. + * VM Testbase keywords: [jit, quick] + * + * @library /vmTestbase + * /test/lib + * @compile -XDstringConcat=inline ../../Merge01.java + * @run main/othervm -XX:-CompactStrings vm.compiler.optimizations.stringconcat.implicit.Merge01 + */ + diff --git a/test/hotspot/jtreg/vmTestbase/vm/compiler/optimizations/stringconcat/implicit/Merge01/cs_enabled/TestDescription.java b/test/hotspot/jtreg/vmTestbase/vm/compiler/optimizations/stringconcat/implicit/Merge01/cs_enabled/TestDescription.java index 3c082fefd25..c6fc8d67de6 100644 --- a/test/hotspot/jtreg/vmTestbase/vm/compiler/optimizations/stringconcat/implicit/Merge01/cs_enabled/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/vm/compiler/optimizations/stringconcat/implicit/Merge01/cs_enabled/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -33,3 +33,17 @@ * @run main/othervm -XX:+CompactStrings vm.compiler.optimizations.stringconcat.implicit.Merge01 */ + +/* + * @test id=stringConcatInline + * + * @summary The same test with an updated compile directive that produces + * StringBuilder-backed string concatenations. + * VM Testbase keywords: [jit, quick] + * + * @library /vmTestbase + * /test/lib + * @compile -XDstringConcat=inline ../../Merge01.java + * @run main/othervm -XX:+CompactStrings vm.compiler.optimizations.stringconcat.implicit.Merge01 + */ + diff --git a/test/jdk/java/awt/Clipboard/ConcurrentClipboardAccessTest.java b/test/jdk/java/awt/Clipboard/ConcurrentClipboardAccessTest.java new file mode 100644 index 00000000000..db98b06ea9d --- /dev/null +++ b/test/jdk/java/awt/Clipboard/ConcurrentClipboardAccessTest.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + /* + @test + @bug 8332271 + @summary tests that concurrent access to the clipboard does not crash the JVM + @key headful + @requires (os.family == "windows") + @run main ConcurrentClipboardAccessTest + */ +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.DataFlavor; + +public class ConcurrentClipboardAccessTest { + + public static void main(String[] args) { + Thread clipboardLoader1 = new Thread(new ClipboardLoader()); + clipboardLoader1.setDaemon(true); + clipboardLoader1.start(); + Thread clipboardLoader2 = new Thread(new ClipboardLoader()); + clipboardLoader2.setDaemon(true); + clipboardLoader2.start(); + long start = System.currentTimeMillis(); + while (true) { + try { + Thread.sleep(1000); + } catch (InterruptedException ignored) { + } + long now = System.currentTimeMillis(); + if ((now - start) > (10L * 1000L)) { + break; + } + } + // Test is considered successful if the concurrent repeated reading + // from clipboard succeeds for the allotted time and the JVM does not + // crash. + System.out.println("Shutdown normally"); + } + + public static class ClipboardLoader implements Runnable { + + @Override + public void run() { + final Clipboard systemClipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + while (true) { + try { + if (systemClipboard.isDataFlavorAvailable(DataFlavor.stringFlavor)) { + systemClipboard.getData(DataFlavor.stringFlavor); + } + } catch (Exception ignored) { + } + } + } + } +} diff --git a/test/jdk/java/awt/Frame/MultiScreenTest.java b/test/jdk/java/awt/Frame/MultiScreenTest.java index 845f601138b..cbd781f94dd 100644 --- a/test/jdk/java/awt/Frame/MultiScreenTest.java +++ b/test/jdk/java/awt/Frame/MultiScreenTest.java @@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,6 +43,7 @@ import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.TextField; +import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -74,7 +75,7 @@ public class MultiScreenTest { ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); gs = ge.getScreenDevices(); if (gs.length < 2) { - throw new SkippedException("You have only one monitor in your system - test passed"); + throw new SkippedException("You have only one monitor in your system"); } MultiScreenTest obj = new MultiScreenTest(); String INSTRUCTIONS = @@ -82,38 +83,42 @@ public class MultiScreenTest { "You have " + gs.length + " monitors in your system.\n" + "Actively drag the DitherTest frames on the secondary screen and " + "if you see garbage appearing on your primary screen " + - "test failed otherwise it passed.";; + "test failed otherwise it passed."; PassFailJFrame.builder() - .title("MultiScreenTest Instruction") .instructions(INSTRUCTIONS) - .rows((int) INSTRUCTIONS.lines().count() + 2) .columns(40) .testUI(obj::init) + .positionTestUI(MultiScreenTest::positionTestWindows) .build() .awaitAndCheck(); } + private static void positionTestWindows(List windows, PassFailJFrame.InstructionUI instructionUI) { + // Do nothing - the location of each window is set when they're created + } + public List init() { List list = new ArrayList<>(); for (int j = 0; j < gs.length; j++) { GraphicsConfiguration[] gc = gs[j].getConfigurations(); if (gc.length > 0) { - for (int i = 0; i < gc.length / 2; i++) { - JFrame f = new JFrame(gc[i]); //test JFrame( gc ) - GCCanvas c = new GCCanvas(gc[i]);//test canvas( gc ) - Rectangle gcBounds = gc[i].getBounds(); //test getBounds() + for (int i = 0; i < gc.length && i < 10; i++) { + JFrame f = new JFrame(gc[i]); + GCCanvas c = new GCCanvas(gc[i]); + Rectangle gcBounds = gc[i].getBounds(); int xoffs = gcBounds.x; int yoffs = gcBounds.y; f.getContentPane().add(c); - f.setTitle("Screen# " + Integer.toString(j) + ", GC#" + Integer.toString(i)); + f.setTitle("Screen# " + j + ", GC#" + i); f.setSize(300, 200); - f.setLocation(400 + xoffs, (i * 150) + yoffs);//test displaying in right location + // test displaying in right location + f.setLocation(400 + xoffs, (i * 150) + yoffs); list.add(f); - Frame ditherfs = new Frame("DitherTest GC#" + Integer.toString(i), gc[i]); - ditherfs.setLayout(new BorderLayout()); //showDitherTest + Frame ditherfs = new Frame("DitherTest GC#" + i, gc[i]); + ditherfs.setLayout(new BorderLayout()); DitherTest ditherTest = new DitherTest(gc[i]); ditherfs.add("Center", ditherTest); ditherfs.setBounds(300, 200, 300, 200); @@ -126,360 +131,368 @@ public class MultiScreenTest { } return list; } -} -class GCCanvas extends Canvas { - GraphicsConfiguration gc; - Rectangle bounds; - Graphics g = this.getGraphics(); - Dimension size = getSize(); + static class GCCanvas extends Canvas { - public GCCanvas(GraphicsConfiguration gc) { - super(gc); - this.gc = gc; - bounds = gc.getBounds(); - } + GraphicsConfiguration gc; + Rectangle bounds; + Dimension size = getSize(); - public void paint( Graphics _g ) { + public GCCanvas(GraphicsConfiguration gc) { + super(gc); + this.gc = gc; + bounds = gc.getBounds(); + } - Graphics2D g = (Graphics2D) _g; + @Override + public void paint( Graphics _g ) { - g.drawRect(0, 0, size.width-1, size.height-1); - g.setColor(Color.lightGray); - g.draw3DRect(1, 1, size.width-3, size.height-3, true); + Graphics2D g = (Graphics2D) _g; - g.setColor(Color.red); - g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g.drawRect(0, 0, size.width-1, size.height-1); + g.setColor(Color.lightGray); + g.draw3DRect(1, 1, size.width-3, size.height-3, true); - g.drawString("HELLO!", 110, 10); + g.setColor(Color.red); + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - g.setColor(Color.blue); - g.drawString("ScreenSize="+Integer.toString(bounds.width)+"X"+ - Integer.toString(bounds.height), 10, 20); - g.setColor(Color.green); - g.drawString(gc.toString(), 10, 30); - g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); + g.drawString("HELLO!", 110, 10); - g.setColor(Color.orange); - g.fillRect(40, 20, 50, 50); + g.setColor(Color.blue); + g.drawString("ScreenSize="+Integer.toString(bounds.width)+"X"+ + Integer.toString(bounds.height), 10, 20); + g.setColor(Color.green); + g.drawString(gc.toString(), 10, 30); + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); - g.setColor(Color.red); - g.drawRect(100, 20, 30, 30); + g.setColor(Color.orange); + g.fillRect(40, 20, 50, 50); - g.setColor(Color.gray); - g.drawLine(220, 20, 280, 40); + g.setColor(Color.red); + g.drawRect(100, 20, 30, 30); - g.setColor(Color.cyan); - g.fillArc(150, 30, 30, 30, 0, 200); - } + g.setColor(Color.gray); + g.drawLine(220, 20, 280, 40); - public Dimension getPreferredSize(){ - return new Dimension(300, 200); - } -} + g.setColor(Color.cyan); + g.fillArc(150, 30, 30, 30, 0, 200); + } -class DitherCanvas extends Canvas { - Image img; - static String calcString = "Calculating..."; - - GraphicsConfiguration mGC; - - public DitherCanvas(GraphicsConfiguration gc) { - super(gc); - mGC = gc; - } - - public GraphicsConfiguration getGraphicsConfig() { - return mGC; - } - - public void paint(Graphics g) { - int w = getSize().width; - int h = getSize().height; - if (img == null) { - super.paint(g); - g.setColor(Color.black); - FontMetrics fm = g.getFontMetrics(); - int x = (w - fm.stringWidth(calcString)) / 2; - int y = h / 2; - g.drawString(calcString, x, y); - } else { - g.drawImage(img, 0, 0, w, h, this); + @Override + public Dimension getPreferredSize(){ + return new Dimension(300, 200); } } - public void update(Graphics g) { - paint(g); - } + static class DitherCanvas extends Canvas { + Image img; + static String calcString = "Calculating..."; - public Dimension getMinimumSize() { - return new Dimension(20, 20); - } + GraphicsConfiguration mGC; - public Dimension getPreferredSize() { - return new Dimension(200, 200); - } - - public Image getImage() { - return img; - } - - public void setImage(Image img) { - this.img = img; - paint(getGraphics()); - } -} - -class DitherTest extends Panel implements Runnable { - final static int NOOP = 0; - final static int RED = 1; - final static int GREEN = 2; - final static int BLUE = 3; - final static int ALPHA = 4; - final static int SATURATION = 5; - - Thread runner; - - DitherControls XControls; - DitherControls YControls; - DitherCanvas canvas; - - public DitherTest(GraphicsConfiguration gc) { - String xspec, yspec; - int xvals[] = new int[2]; - int yvals[] = new int[2]; - - xspec = "red"; - yspec = "blue"; - int xmethod = colormethod(xspec, xvals); - int ymethod = colormethod(yspec, yvals); - - setLayout(new BorderLayout()); - XControls = new DitherControls(this, xvals[0], xvals[1], - xmethod, false); - YControls = new DitherControls(this, yvals[0], yvals[1], - ymethod, true); - YControls.addRenderButton(); - add("North", XControls); - add("South", YControls); - add("Center", canvas = new DitherCanvas(gc)); - } - - public void start() { - runner = new Thread(this); - runner.start(); - } - - int colormethod(String s, int vals[]) { - int method = NOOP; - - if (s == null) { - s = ""; + public DitherCanvas(GraphicsConfiguration gc) { + super(gc); + mGC = gc; } - String lower = s.toLowerCase(); - int len = 0; - if (lower.startsWith("red")) { - method = RED; - lower = lower.substring(3); - } else if (lower.startsWith("green")) { - method = GREEN; - lower = lower.substring(5); - } else if (lower.startsWith("blue")) { - method = BLUE; - lower = lower.substring(4); - } else if (lower.startsWith("alpha")) { - method = ALPHA; - lower = lower.substring(4); - } else if (lower.startsWith("saturation")) { - method = SATURATION; - lower = lower.substring(10); + public GraphicsConfiguration getGraphicsConfig() { + return mGC; } - if (method == NOOP) { - vals[0] = 0; - vals[1] = 0; + @Override + public void paint(Graphics g) { + int w = getSize().width; + int h = getSize().height; + if (img == null) { + super.paint(g); + g.setColor(Color.black); + FontMetrics fm = g.getFontMetrics(); + int x = (w - fm.stringWidth(calcString)) / 2; + int y = h / 2; + g.drawString(calcString, x, y); + } else { + g.drawImage(img, 0, 0, w, h, this); + } + } + + @Override + public void update(Graphics g) { + paint(g); + } + + @Override + public Dimension getMinimumSize() { + return new Dimension(20, 20); + } + + @Override + public Dimension getPreferredSize() { + return new Dimension(200, 200); + } + + public Image getImage() { + return img; + } + + public void setImage(Image img) { + this.img = img; + paint(getGraphics()); + } + } + + static class DitherTest extends Panel implements Runnable { + final static int NOOP = 0; + final static int RED = 1; + final static int GREEN = 2; + final static int BLUE = 3; + final static int ALPHA = 4; + final static int SATURATION = 5; + + Thread runner; + + DitherControls XControls; + DitherControls YControls; + DitherCanvas canvas; + + public DitherTest(GraphicsConfiguration gc) { + String xspec, yspec; + int xvals[] = new int[2]; + int yvals[] = new int[2]; + + xspec = "red"; + yspec = "blue"; + int xmethod = colormethod(xspec, xvals); + int ymethod = colormethod(yspec, yvals); + + setLayout(new BorderLayout()); + XControls = new DitherControls(this, xvals[0], xvals[1], + xmethod, false); + YControls = new DitherControls(this, yvals[0], yvals[1], + ymethod, true); + YControls.addRenderButton(); + add("North", XControls); + add("South", YControls); + add("Center", canvas = new DitherCanvas(gc)); + } + + public void start() { + runner = new Thread(this); + runner.start(); + } + + int colormethod(String s, int vals[]) { + int method = NOOP; + + if (s == null) { + s = ""; + } + + String lower = s.toLowerCase(); + int len = 0; + if (lower.startsWith("red")) { + method = RED; + lower = lower.substring(3); + } else if (lower.startsWith("green")) { + method = GREEN; + lower = lower.substring(5); + } else if (lower.startsWith("blue")) { + method = BLUE; + lower = lower.substring(4); + } else if (lower.startsWith("alpha")) { + method = ALPHA; + lower = lower.substring(4); + } else if (lower.startsWith("saturation")) { + method = SATURATION; + lower = lower.substring(10); + } + + if (method == NOOP) { + vals[0] = 0; + vals[1] = 0; + return method; + } + + int begval = 0; + int endval = 255; + + try { + int dash = lower.indexOf('-'); + if (dash < 0) { + begval = endval = Integer.parseInt(lower); + } else { + begval = Integer.parseInt(lower.substring(0, dash)); + endval = Integer.parseInt(lower.substring(dash + 1)); + } + } catch (Exception e) { + } + + if (begval < 0) { + begval = 0; + } + if (endval < 0) { + endval = 0; + } + if (begval > 255) { + begval = 255; + } + if (endval > 255) { + endval = 255; + } + + vals[0] = begval; + vals[1] = endval; + return method; } - int begval = 0; - int endval = 255; - - try { - int dash = lower.indexOf('-'); - if (dash < 0) { - begval = endval = Integer.parseInt(lower); - } else { - begval = Integer.parseInt(lower.substring(0, dash)); - endval = Integer.parseInt(lower.substring(dash + 1)); - } - } catch (Exception e) { - } - - if (begval < 0) { - begval = 0; - } - if (endval < 0) { - endval = 0; - } - if (begval > 255) { - begval = 255; - } - if (endval > 255) { - endval = 255; - } - - vals[0] = begval; - vals[1] = endval; - - return method; - } - - void applymethod(int c[], int method, int step, int total, int vals[]) { - if (method == NOOP) - return; - int val = ((total < 2) - ? vals[0] - : vals[0] + ((vals[1] - vals[0]) * step / (total - 1))); - switch (method) { - case RED: - c[0] = val; - break; - case GREEN: - c[1] = val; - break; - case BLUE: - c[2] = val; - break; - case ALPHA: - c[3] = val; - break; - case SATURATION: - int max = Math.max(Math.max(c[0], c[1]), c[2]); - int min = max * (255 - val) / 255; - if (c[0] == 0) { - c[0] = min; - } - if (c[1] == 0) { - c[1] = min; - } - if (c[2] == 0) { - c[2] = min; - } - break; - } - } - - public void run() { - canvas.setImage(null); // Wipe previous image - Image img = calculateImage(); - synchronized (this) { - if (img != null && runner == Thread.currentThread()) { - canvas.setImage(img); - } - } - } - - /** - * Calculates and returns the image. Halts the calculation and returns - * null if stopped during the calculation. - */ - Image calculateImage() { - Thread me = Thread.currentThread(); - - int width = canvas.getSize().width; - int height = canvas.getSize().height; - int xvals[] = new int[2]; - int yvals[] = new int[2]; - int xmethod = XControls.getParams(xvals); - int ymethod = YControls.getParams(yvals); - int pixels[] = new int[width * height]; - int c[] = new int[4]; - int index = 0; - - for (int j = 0; j < height; j++) { - for (int i = 0; i < width; i++) { - c[0] = c[1] = c[2] = 0; - c[3] = 255; - if (xmethod < ymethod) { - applymethod(c, xmethod, i, width, xvals); - applymethod(c, ymethod, j, height, yvals); - } else { - applymethod(c, ymethod, j, height, yvals); - applymethod(c, xmethod, i, width, xvals); - } - pixels[index++] = ((c[3] << 24) | - (c[0] << 16) | - (c[1] << 8) | - (c[2] << 0)); - - } - // Poll once per row to see if we've been told to stop. - if (runner != me) { - return null; + void applymethod(int c[], int method, int step, int total, int vals[]) { + if (method == NOOP) + return; + int val = ((total < 2) + ? vals[0] + : vals[0] + ((vals[1] - vals[0]) * step / (total - 1))); + switch (method) { + case RED: + c[0] = val; + break; + case GREEN: + c[1] = val; + break; + case BLUE: + c[2] = val; + break; + case ALPHA: + c[3] = val; + break; + case SATURATION: + int max = Math.max(Math.max(c[0], c[1]), c[2]); + int min = max * (255 - val) / 255; + if (c[0] == 0) { + c[0] = min; + } + if (c[1] == 0) { + c[1] = min; + } + if (c[2] == 0) { + c[2] = min; + } + break; } } - return createImage(new MemoryImageSource(width, height, - ColorModel.getRGBdefault(), pixels, 0, width)); + @Override + public void run() { + canvas.setImage(null); // Wipe previous image + Image img = calculateImage(); + synchronized (this) { + if (img != null && runner == Thread.currentThread()) { + canvas.setImage(img); + } + } + } + + /** + * Calculates and returns the image. Halts the calculation and returns + * null if stopped during the calculation. + */ + Image calculateImage() { + Thread me = Thread.currentThread(); + + int width = canvas.getSize().width; + int height = canvas.getSize().height; + int xvals[] = new int[2]; + int yvals[] = new int[2]; + int xmethod = XControls.getParams(xvals); + int ymethod = YControls.getParams(yvals); + int pixels[] = new int[width * height]; + int c[] = new int[4]; + int index = 0; + + for (int j = 0; j < height; j++) { + for (int i = 0; i < width; i++) { + c[0] = c[1] = c[2] = 0; + c[3] = 255; + if (xmethod < ymethod) { + applymethod(c, xmethod, i, width, xvals); + applymethod(c, ymethod, j, height, yvals); + } else { + applymethod(c, ymethod, j, height, yvals); + applymethod(c, xmethod, i, width, xvals); + } + pixels[index++] = ((c[3] << 24) | + (c[0] << 16) | + (c[1] << 8) | + (c[2] << 0)); + + } + // Poll once per row to see if we've been told to stop. + if (runner != me) { + return null; + } + } + + return createImage(new MemoryImageSource(width, height, + ColorModel.getRGBdefault(), pixels, 0, width)); + } + + public String getInfo() { + return "An interactive demonstration of dithering."; + } + + public String[][] getParameterInfo() { + String[][] info = { + {"xaxis", "{RED, GREEN, BLUE, PINK, ORANGE, MAGENTA, CYAN, WHITE, YELLOW, GRAY, DARKGRAY}", + "The color of the Y axis. Default is RED."}, + {"yaxis", "{RED, GREEN, BLUE, PINK, ORANGE, MAGENTA, CYAN, WHITE, YELLOW, GRAY, DARKGRAY}", + "The color of the X axis. Default is BLUE."} + }; + return info; + } } - public String getInfo() { - return "An interactive demonstration of dithering."; - } + static class DitherControls extends Panel implements ActionListener { + TextField start; + TextField end; + Button button; + Choice choice; + DitherTest dt; - public String[][] getParameterInfo() { - String[][] info = { - {"xaxis", "{RED, GREEN, BLUE, PINK, ORANGE, MAGENTA, CYAN, WHITE, YELLOW, GRAY, DARKGRAY}", - "The color of the Y axis. Default is RED."}, - {"yaxis", "{RED, GREEN, BLUE, PINK, ORANGE, MAGENTA, CYAN, WHITE, YELLOW, GRAY, DARKGRAY}", - "The color of the X axis. Default is BLUE."} - }; - return info; - } -} + static LayoutManager dcLayout = new FlowLayout(FlowLayout.CENTER, 10, 5); -class DitherControls extends Panel implements ActionListener { - TextField start; - TextField end; - Button button; - Choice choice; - DitherTest dt; + public DitherControls(DitherTest app, int s, int e, int type, + boolean vertical) { + dt = app; + setLayout(dcLayout); + add(new Label(vertical ? "Vertical" : "Horizontal")); + add(choice = new Choice()); + choice.addItem("Noop"); + choice.addItem("Red"); + choice.addItem("Green"); + choice.addItem("Blue"); + choice.addItem("Alpha"); + choice.addItem("Saturation"); + choice.select(type); + add(start = new TextField(Integer.toString(s), 4)); + add(end = new TextField(Integer.toString(e), 4)); + } - static LayoutManager dcLayout = new FlowLayout(FlowLayout.CENTER, 10, 5); + public void addRenderButton() { + add(button = new Button("New Image")); + button.addActionListener(this); + } - public DitherControls(DitherTest app, int s, int e, int type, - boolean vertical) { - dt = app; - setLayout(dcLayout); - add(new Label(vertical ? "Vertical" : "Horizontal")); - add(choice = new Choice()); - choice.addItem("Noop"); - choice.addItem("Red"); - choice.addItem("Green"); - choice.addItem("Blue"); - choice.addItem("Alpha"); - choice.addItem("Saturation"); - choice.select(type); - add(start = new TextField(Integer.toString(s), 4)); - add(end = new TextField(Integer.toString(e), 4)); - } + public int getParams(int vals[]) { + vals[0] = Integer.parseInt(start.getText()); + vals[1] = Integer.parseInt(end.getText()); + return choice.getSelectedIndex(); + } - public void addRenderButton() { - add(button = new Button("New Image")); - button.addActionListener(this); - } - - public int getParams(int vals[]) { - vals[0] = Integer.parseInt(start.getText()); - vals[1] = Integer.parseInt(end.getText()); - return choice.getSelectedIndex(); - } - - public void actionPerformed(ActionEvent e) { - if (e.getSource() == button) { - dt.start(); + @Override + public void actionPerformed(ActionEvent e) { + if (e.getSource() == button) { + dt.start(); + } } } } diff --git a/test/jdk/java/net/HttpURLConnection/HttpURLConnectionExpectContinueTest.java b/test/jdk/java/net/HttpURLConnection/HttpURLConnectionExpectContinueTest.java index c9b8bc85b70..e701e234d83 100644 --- a/test/jdk/java/net/HttpURLConnection/HttpURLConnectionExpectContinueTest.java +++ b/test/jdk/java/net/HttpURLConnection/HttpURLConnectionExpectContinueTest.java @@ -429,7 +429,7 @@ public class HttpURLConnectionExpectContinueTest { .port(control.serverSocket.getLocalPort()) .toURL(); - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(Proxy.NO_PROXY); connection.setDoOutput(true); connection.setReadTimeout(5000); connection.setUseCaches(false); diff --git a/test/jdk/java/security/PEM/PEMData.java b/test/jdk/java/security/PEM/PEMData.java index e1f32cdbb7c..2c8c60fcccc 100644 --- a/test/jdk/java/security/PEM/PEMData.java +++ b/test/jdk/java/security/PEM/PEMData.java @@ -27,6 +27,7 @@ import javax.crypto.EncryptedPrivateKeyInfo; import java.security.DEREncodable; import java.security.KeyPair; import java.security.PEMRecord; +import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.security.interfaces.*; import java.util.ArrayList; @@ -45,7 +46,7 @@ class PEMData { KwDdi3cNwu7YYD/QtJ+9+AEBdoqhRANCAASL+REY4vvAI9M3gonaml5K3lRgHq5w +OO4oO0VNduC44gUN1nrk7/wdNSpL+xXNEX52Dsff+2RD/fop224ANvB -----END PRIVATE KEY----- - """, KeyPair.class); + """, KeyPair.class, "SunEC"); public static final Entry rsapriv = new Entry("rsapriv", """ @@ -65,7 +66,68 @@ class PEMData { 6onPAs4hkm+63dfzCojvEkALevO8J3OVX7YS5q9J1r75wDn60Ob0Zh+iiorpx8Ob WqcWcoJqfdLEyBT+ -----END PRIVATE KEY----- - """, RSAPrivateKey.class); + """, RSAPrivateKey.class, "SunRsaSign"); + + public static final Entry rsaCrtCoefZeroPriv = new Entry("rsaCrtCoefZeroPriv", + """ + -----BEGIN RSA PRIVATE KEY----- + MIIEIwIBAAKCAQEAuZAPiPMlA5R0oOIbxbq+gOmBRcvptIT+0pmG6rZ6H//r7A/Z + MRwen0iO2GuhlyUgOk9Fja/TMBrNX99boVDEZtL4oxRTJibdLNjfQqPeFhs3NNvv + CJJEGD91Dq/fGbWv1TMZcEywqqYSdERDEA7yluw87I7YZc9kXVBwRw5AedvoXOL/ + z5yPjK8W7FTCLHSVKiD/X3P3ZX9TmFjTIbRH15Do5sRxsPdrZczYjWdXFXNQEUuF + sVFGHFbB/AJiZlGYqMU+hEIErE35sHrKpZYkj9YovYQe0SBJyuROPl8wmz0Cd69s + rhg142Qf23RPhclBuCNAQQOkefeCppg4IFFh7QIDAQABAoIBADlKHlm4Q7m2uElB + dbSWwqEXNnefjJBUrT3E84/8dXjysNppTDNqzJN9uchcdn+tESWfeshTO97yr2yF + j4se3fwm72ed60vwnMFvVYKECBmIHoO90S8yxT49PT0jFDyiSN6IT7bJnpOZAUKP + HqtTCheJaQfZ1DqejIx4vKlbX5GfShwPQV0Q7KeKnfxhryhAbM5Y5UT8grQGBQU7 + aQUZuasQV10APVRaz39VU8/hzBc081LR3O0tjnZcrMAQ7ANsP9Gu3My04cnQ5WBo + P8uCCaSPSkrzCvjd9YYkdnwXMbVCfALOa+MxBddMi4IQG0qI28Bpw6dkKziPxage + KcAQnAsCgYEA0/CwzUlyrG6f+FF3uAvPVn/jEhWatJb7Me7lkhO3suV92brb1pQo + 1W1jHdx0OqMuCVfIJ4bXkTwKuvLQGcWJzNWUVh4Tij/ZAV0Ssw2cKbBSCQGNIFsx + Ux0V9tDSYJsEdk+Y5grloDNJokYYCCpF5bz/6QYmX+t3yzjyVSvcNeMCgYEA4COU + ezUXKLSWD+jJZXpS5yopB7oXAg7mmonlc1DRuaIxspwBrbXPLQ/neN8Sefpz9Nxn + 4ksPxGbLnJh0wGCnxSu0Qfn4eNVSsulag4IQmbCO2UBsdXNCJB5KlDpRlVhvvviH + Zpz2Dkdx+itLf1EV841MCtPAHZJwrs6i6JntEe8CgYEAgJYdjs+rJXcQ04YKDr4L + k72PtR8qd7rKuObqnhAcegvGqV03mB7YD3WIl0tzsUfj3INHysOC8njtQbOkEp7J + Fl/W2dDxpgVK0gr4F26AesKhYxlv2Fu7t2OEOfVETpx+vpFYgOnHm8TCPhQs7HdJ + ZTOgSG8UxUmFquToEkjEGGUCgYB6AMP8wKxHeuzH4iVl+EySCa/lxdRqSWQasH7V + 4yMVkYTNvP9o57LKy4Jql7n97Wca3LIrSkJd3LpuFcpPQQ1xVNW8p+0pEK0AN+cN + +ElC7wkCln+y+rcA5AAiaRApY8cHw04oe72vjhIrY0+oEKILPVkr95D2R9TQQigI + xmh1vwIBAA== + -----END RSA PRIVATE KEY----- + """, RSAPrivateKey.class, "SunRsaSign"); + + public static final Entry rsapsspriv = new Entry("rsapsspriv", + """ + -----BEGIN PRIVATE KEY----- + MIIEugIBADALBgkqhkiG9w0BAQoEggSmMIIEogIBAAKCAQEAn3qFQtvj9JVqVPRh + mMMRyT17GiUY+NWOwUHx5bHqfhlHJoCllctSU/YXzrH4Da1w7sSeaMmAKYMW4X5k + rn9hnKOhgHnm2nkZBaVNQeyrseuDnfwWtLXjnj8rEKpgf9UPRUeXGRSoAb1qpwBf + epFtLSKZrzswZY2u2UEUGJERABi6Qp+cIZ8uXzBkIsMgrhb50xsdysZ9+qq95z0i + N1vh/V+Yi2fYpSYVDE8aMWdpvs0oWGvoLQjRgElJx/SknndAfLD42HPYZyyXevyJ + RgUf+NP0V7c+UtE7m7pgMs1hhxHSmUNdfH9GnOSg9m3+L3WqhaNNWB4aKMqFyhlM + EsAuawIDAQABAoIBAAMJ9yXIgeYEaN54j67fsg7nJIQ228HLc/5xGWvFQaYofidu + K87twm0GKKWlf4gR24U5QEQtPst2YNu9fav+PRJv4yEgcYqNOdxWg4veN4Fa7wr2 + JZ/zmARJHjLMRFgl67YSwKmCMBdkZXa24PA5et6cJQM7+gFIELe5b+lt7j3VsxQ7 + JpTJyp3I73lXcJrzcb/OCTxobFPLtkVSgKUNwae26xlNqXX4fQfLp99LHGnkmG3k + Wlzjs6dUi4fl4yLAJYMxEwxQbSbmY66ZKnM4SkT/YHx67gyJw2CMRp4FQDg94Sor + 0IDDKiSMGzcjuCuUl27/qTuv+iMgCqNB7CSPXtECgYEAvqN8ZuZXeUKz4tn6wxJk + k1utCl3pSM5PLMF4J43uvX49HF1i3svXrwxzJqug6kPXvB7cuB6U2DFIM3lh2jNE + u2w0U/5zVz2yEI9EaRjnOXePLsSWjOiC+5MGTafJWy5vZ8+zaWL9tjtUH5hsg1cB + ZMlXtWrI+AmAUAv6FFDZaHECgYEA1igXzRMGgXAT+YX0wdZQcRMy9jD5WIYIiCex + 6/WRE2LDM855ZBwTU5gyqZC2MWC3yn1ASDraxKdH1m3872Q0NVJfsOaLvBk1HuPk + dlSHRKO2GeO9m5/YzrZm9jpGs0IH6DKOah/t0aCd2CFxt6qef2wOUmXTCK6tyCXN + EiUmEpsCgYAMue85E1Ftl+VYVILn+Ndb+ve/RGupX5RrgXLa+R+h6MZ9mUJbazI3 + zlX1k+mHGgZR2aGUbP40vH18ajL9FQUWme+YV9ktTsIPVvETLwVokbGuRpNiTrdH + whXeoz/O5Xesb3Ijq+cR/j3sagl8bxd5ufMv+jP2UvQM4+/K4WbSEQKBgGuZeVvw + UzR1u5ODWpaJt6EYpGJN+PohXegLCbokh9/Vn35IH3XNJWi677mCnAfzMGTsyX+B + Eqn74nw6hvtAvXqNCMc5DrxTbf03Q3KwxcYW+0fGxV2L0sMJonHUlfE7G/3uaN+p + azQIH0aYhypg74HWKNv9jSqvmWEWnRKg16BBAoGAGLAqCRCP8wxqRVZZjhUJ+5JN + b6PrykDxCKhlA6JqZKuCYzvXhLABq/7miNDg0CmRREl+yKXlkEoFl4g9LtP7wfjX + n4us/WNmh+GPZYxlCJSNRTjgk7pm5TjVH5YWURDEnjIHZ7yxbAFlvNUhI1mF5g97 + KVcB4fjBitP1h8P+MoY= + -----END PRIVATE KEY----- + """, RSAPrivateKey.class, "SunRsaSign"); public static final Entry rsaprivbc = new Entry("rsaprivbc", """ @@ -85,14 +147,14 @@ class PEMData { 6onPAs4hkm+63dfzCojvEkALevO8J3OVX7YS5q9J1r75wDn60Ob0Zh+iiorpx8Ob WqcWcoJqfdLEyBT+ -----END PRIVATE KEY----- - """, RSAPrivateKey.class); + """, RSAPrivateKey.class, "SunRsaSign"); public static final Entry ec25519priv = new Entry("ed25519priv", """ -----BEGIN PRIVATE KEY----- MC4CAQAwBQYDK2VwBCIEIFFZsmD+OKk67Cigc84/2fWtlKsvXWLSoMJ0MHh4jI4I -----END PRIVATE KEY----- - """, EdECPrivateKey.class); + """, EdECPrivateKey.class, "SunEC"); public static final Entry rsapub = new Entry("rsapub", """ @@ -102,7 +164,20 @@ class PEMData { MtJpIPIXynEqRy2mIw2GrKTtu3dqrW+ndarbD6D4yRY1hWHluiuOtzhxuueCuf9h XCYEHZS1cqd8wokFPwIDAQAB -----END PUBLIC KEY----- - """, RSAPublicKey.class); + """, RSAPublicKey.class, "SunRsaSign"); + + public static final Entry rsapsspub = new Entry("rsapsspub", + """ + -----BEGIN PUBLIC KEY----- + MIIBIDALBgkqhkiG9w0BAQoDggEPADCCAQoCggEBAJ96hULb4/SValT0YZjDEck9 + exolGPjVjsFB8eWx6n4ZRyaApZXLUlP2F86x+A2tcO7EnmjJgCmDFuF+ZK5/YZyj + oYB55tp5GQWlTUHsq7Hrg538FrS1454/KxCqYH/VD0VHlxkUqAG9aqcAX3qRbS0i + ma87MGWNrtlBFBiREQAYukKfnCGfLl8wZCLDIK4W+dMbHcrGffqqvec9Ijdb4f1f + mItn2KUmFQxPGjFnab7NKFhr6C0I0YBJScf0pJ53QHyw+Nhz2Gcsl3r8iUYFH/jT + 9Fe3PlLRO5u6YDLNYYcR0plDXXx/RpzkoPZt/i91qoWjTVgeGijKhcoZTBLALmsC + AwEAAQ== + -----END PUBLIC KEY----- + """, RSAPublicKey.class, "SunRsaSign"); public static final Entry rsapubbc = new Entry("rsapubbc", """ @@ -112,14 +187,14 @@ class PEMData { MtJpIPIXynEqRy2mIw2GrKTtu3dqrW+ndarbD6D4yRY1hWHluiuOtzhxuueCuf9h XCYEHZS1cqd8wokFPwIDAQAB -----END PUBLIC KEY----- - """, RSAPublicKey.class); + """, RSAPublicKey.class, "SunRsaSign"); public static final Entry ecsecp256pub = new Entry("ecsecp256pub", """ -----BEGIN PUBLIC KEY----- MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEi/kRGOL7wCPTN4KJ2ppeSt5UYB6u cPjjuKDtFTXbguOIFDdZ65O/8HTUqS/sVzRF+dg7H3/tkQ/36KdtuADbwQ== -----END PUBLIC KEY----- - """, ECPublicKey.class); + """, ECPublicKey.class, "SunEC"); // EC key with explicit parameters -- Not currently supported by SunEC public static final String pubec_explicit = """ @@ -152,7 +227,7 @@ class PEMData { P4c4mySRy5N3plFQUp3pIB7wqshi1t6hkdg7gRGjMtJpIPIXynEqRy2mIw2GrKTtu3dqrW+ndarb D6D4yRY1hWHluiuOtzhxuueCuf9hXCYEHZS1cqd8wokFPwIDAQAB -----END PRIVATE KEY----- - """, KeyPair.class); + """, KeyPair.class, "SunRsaSign"); public static final Entry oasrfc8410 = new Entry("oasrfc8410", """ @@ -161,7 +236,24 @@ class PEMData { oB8wHQYKKoZIhvcNAQkJFDEPDA1DdXJkbGUgQ2hhaXJzgSEAGb9ECWmEzf6FQbrB Z9w7lshQhqowtrbLDFw4rXAxZuE= -----END PRIVATE KEY----- - """, KeyPair.class); + """, KeyPair.class, "SunEC"); + + public static final Entry oasxdh = new Entry("oasxdh", + """ + -----BEGIN PRIVATE KEY----- + MFECAQEwBQYDK2VuBCIEIIrMS7w5YxuBTyPFiaFvp6ILiGET7wY9ybk7Qqhe3hSq + gSEAB7ODPxRePrPnJMaj3f47blVx6c5bfxcllQzLp4bW5x4= + -----END PRIVATE KEY----- + """, KeyPair.class, "SunEC"); + + public static final Entry oasec = new Entry("oasec", + """ + -----BEGIN PRIVATE KEY----- + MIGFAgEBMBMGByqGSM49AgEGCCqGSM49AwEHBCcwJQIBAQQgkGEVbZE1yAiO11Ya + eepcrBQL+HpVE4fy0V6jbpJcmkiBQgAERCqYYmN9uNT9Z1O2Z2VC3Zag9eUAhz7G + p8DqC21VrIgpqVQ4BrcWsieNg9fSd4N2hgfMpk9PCQwJQ8ifCMiBVQ== + -----END PRIVATE KEY----- + """, KeyPair.class, "SunEC"); public static final Entry rsaOpenSSL = new Entry("rsaOpenSSL", """ @@ -192,7 +284,7 @@ class PEMData { EcgIOtkvoTrJ9Cquvuj+O7/d2yNoH0SZQ4IYJKq47/Z4kKhwXzJnBCCCBKgkjfub RTQSNnSEgTaBD29l7FrhNRHX9lIKFZ23caCTBS6o3q3+KgPbq7ao -----END RSA PRIVATE KEY----- - """, RSAPrivateKey.class); + """, RSAPrivateKey.class, "SunRsaSign"); static final Entry ed25519ep8 = new Entry("ed25519ep8", """ @@ -202,11 +294,11 @@ class PEMData { vdMyi46+Dw7cOjwEQLtx5ME0NOOo7vlCGm3H/4j+Tf5UXrMb1UrkPjqc8OiLbC0n IycFtI70ciPjgwDSjtCcPxR8fSxJPrm2yOJsRVo= -----END ENCRYPTED PRIVATE KEY----- - """, EdECPrivateKey.class, "fish".toCharArray()); + """, EdECPrivateKey.class, "SunEC", "fish".toCharArray()); // This is not meant to be decrypted and to stay as an EKPI static final Entry ed25519ekpi = new Entry("ed25519ekpi", - ed25519ep8.pem(), EncryptedPrivateKeyInfo.class, null); + ed25519ep8.pem(), EncryptedPrivateKeyInfo.class, "SunEC", null); static final Entry rsaCert = new Entry("rsaCert", """ @@ -237,7 +329,7 @@ class PEMData { 8gOYV33zkPhziWJt4uFMFIi7N2DLEk5UVZv1KTLZlfPl55DRs7j/Sb4vKHpB17AO meVknxVvifDVY0TIz57t28Accsk6ClBCxNPluPU/8YLGAZJYsdDXjGcndQ13s5G7 -----END CERTIFICATE----- - """, X509Certificate.class); + """, X509Certificate.class, "SUN"); static final Entry ecCert = new Entry("ecCert", """ @@ -249,7 +341,68 @@ class PEMData { lU3G9QAwCgYIKoZIzj0EAwIDSAAwRQIgMwYld7aBzkcRt9mn27YOed5+n0xN1y8Q VEcFjLI/tBYCIQDU3szDZ/PK2mUZwtgQxLqHdh+f1JY0UwQS6M8QUvoDHw== -----END CERTIFICATE----- - """, X509Certificate.class); + """, X509Certificate.class, "SUN"); + + private static final Entry rsaCrl = new Entry("rsaCrl", + """ + -----BEGIN X509 CRL----- + MIIBRTCBrwIBATANBgkqhkiG9w0BAQUFADBMMQswCQYDVQQGEwJVUzEaMBgGA1UE + ChMRVGVzdCBDZXJ0aWZpY2F0ZXMxITAfBgNVBAMTGEJhc2ljIEhUVFAgVVJJIFBl + ZXIgMSBDQRcNMDUwNjAzMjE0NTQ3WhcNMTUwNjAxMjE0NTQ3WqAvMC0wHwYDVR0j + BBgwFoAUa+bxcvx1zVdUhvIEd9hcfbmFdw4wCgYDVR0UBAMCAQEwDQYJKoZIhvcN + AQEFBQADgYEAZ+21yt1pJn2FU6vBwpFtAKVeBCCCqJVFiRxT84XbUw0BpLrCFvlk + FOo6tC95aoV7vPGwOEyUNbKJJOCzLliIwV1PPfgZQV20xohSIPISHdUjmlyttglv + AuEvltGnbP7ENxw18HxvM20XmHz+akuFu6npI6MkBjfoxvlq1bcdTrI= + -----END X509 CRL----- + """, X509CRL.class, "SUN"); + + // Few random manipulated Base64 characters in PEM content + private static final Entry invalidDer = new Entry("invalidDER", """ + -----BEGIN PRIVATE KEY----- + MIICeAIBADANBhkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAOtjMnCzPy4jCeZb + OdOvmvU3jl7+cvPFgL5MfqDCM5a8yI0yImg/hzibJJHLk3emUVBSnekgHvCqyGLW + 3qGR2DuBEaMy0mkg8hfKcSpHLaYjDYaspO27d2qtb6d1qtsPoPjJFjWFYeW6K463 + OHG654K5/2FcJgQdlLVyp3zCiQU/AgMBAAECgYEAwNkDkTv5rlX8nWLuLJV5kh/T + H9a93SRZxw8qy5Bv7bZ7ZNfHP7uUkHbi7iPojKWRhwo43692SdzR0dCSk7LGgN9q + CYvndsYR6gifVGBi0WF+St4+NdtcQ3VlNdsojy2BdIx0oC+r7i3bn+zc968O/kI+ + EgdgrMcjjFqyx6tMHpECQQD8TYPKGHyN7Jdy28llCoUX/sL/yZ2vIi5mnDAFE5ae + KZQSkNAXG+8i9Qbs/Wdd5S3oZDqu+6DBn9gib80pYY05AkEA7tY59Oy8ka7nBlGP + g6Wo1usF2bKqk8vjko9ioZQay7f86aB10QFcAjCr+cCUm16Lc9DwzWl02nNggRZa + Jz8eNwJBAO+1zfLjFOPb14F/JHdlaVKE8EwKCFDuztsapd0M4Vtf8Zk6ERsDpU63 + Ml9T2zOwnM9g+whpdjDAZ59ATdJ1JrECQQDReJQ2SxeL0lGPCiOLu9RcQp7L81aF + 79G1bgp8WlAyEjlAkloiqEWRKiz7DDuKFR7Lwhognng9S+n87aS+PS57AkBh75t8 + 6onPAs4hkm+63dfzCojvEkALevO8J3OVX7YS5q9J1r75wDn60Ob0Zh+iiorpx8Ob + WqcWcoJqfdLEyBT+ + -----END PRIVATE KEY----- + """, DEREncodable.class, null); + + private static final Entry invalidPEM = new Entry("invalidPEM", """ + -----BEGIN INVALID PEM----- + MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDBVS52ZSKZ0oES7twD2 + GGwRIVu3uHlGIwlu0xzFe7sgIPntca2bHfYMhgGxrlCm0q+hZANiAAQNWgwWfLX8 + 8pYVjvwbfvDF9f+Oa9w6JjrfpWwFAUI6b1OPgrNUh+yXtUXnQNXnfUcIu0Os53bM + """, DEREncodable.class, null); + + private static final Entry invalidHeader = new Entry("invalidHeader", """ + ---BEGIN PRIVATE KEY--- + MC4CAQAwBQYDK2VwBCIEIFFZsmD+OKk67Cigc84/2fWtlKsvXWLSoMJ0MHh4jI4I + -----END PRIVATE KEY----- + """, DEREncodable.class, null); + + private static final Entry invalidFooter = new Entry("invalidFooter", """ + -----BEGIN PRIVATE KEY----- + MC4CAQAwBQYDK2VwBCIEIFFZsmD+OKk67Cigc84/2fWtlKsvXWLSoMJ0MHh4jI4I + ---END PRIVATE KEY--- + """, DEREncodable.class, null); + + private static final Entry incorrectFooter = new Entry("incorrectFooter", """ + -----BEGIN PRIVATE KEY----- + MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDBVS52ZSKZ0oES7twD2 + GGwRIVu3uHlGIwlu0xzFe7sgIPntca2bHfYMhgGxrlCm0q+hZANiAAQNWgwWfLX8 + 8pYVjvwbfvDF9f+Oa9w6JjrfpWwFAUI6b1OPgrNUh+yXtUXnQNXnfUcIu0Os53bM + 8fTqPkQl6RyWEDHeXqJK8zTBHMeBq9nLfDPSbzQgLDyC64Orn0D8exM= + -----END PUBLIC KEY----- + """, DEREncodable.class, null); // EC cert with explicit parameters -- Not currently supported by SunEC static final String ecCertEX = """ @@ -280,7 +433,7 @@ class PEMData { 8pYVjvwbfvDF9f+Oa9w6JjrfpWwFAUI6b1OPgrNUh+yXtUXnQNXnfUcIu0Os53bM 8fTqPkQl6RyWEDHeXqJK8zTBHMeBq9nLfDPSbzQgLDyC64Orn0D8exM= -----END PRIVATE KEY----- - """, KeyPair.class); + """, KeyPair.class, "SunEC"); public static final Entry ecCSR = new Entry("ecCSR", """ @@ -297,7 +450,7 @@ class PEMData { MQYMBGZpc2gwCgYIKoZIzj0EAwIDRwAwRAIgUBTdrMDE4BqruYRh1rRyKQBf48WR kIX8R4dBK9h1VRcCIEBR2Mzvku/huTbWTwKVlXBZeEmwIlxKwpRepPtViXcW -----END CERTIFICATE REQUEST----- - """, PEMRecord.class); + """, PEMRecord.class, "SunEC"); public static final String preData = "TEXT BLAH TEXT BLAH" + System.lineSeparator(); @@ -318,39 +471,41 @@ class PEMData { MQYMBGZpc2gwCgYIKoZIzj0EAwIDRwAwRAIgUBTdrMDE4BqruYRh1rRyKQBf48WR kIX8R4dBK9h1VRcCIEBR2Mzvku/huTbWTwKVlXBZeEmwIlxKwpRepPtViXcW -----END CERTIFICATE REQUEST----- - """ + postData, PEMRecord.class); + """ + postData, PEMRecord.class, "SunEC"); final static Pattern CR = Pattern.compile("\r"); final static Pattern LF = Pattern.compile("\n"); final static Pattern LSDEFAULT = Pattern.compile(System.lineSeparator()); - public record Entry(String name, String pem, Class clazz, char[] password, + public record Entry(String name, String pem, Class clazz, String provider, char[] password, byte[] der) { - public Entry(String name, String pem, Class clazz, char[] password, + public Entry(String name, String pem, Class clazz, String provider, char[] password, byte[] der) { this.name = name; this.pem = pem; this.clazz = clazz; + this.provider = provider; this.password = password; - if (pem != null && pem.length() > 0) { + if (pem != null && pem.length() > 0 && + !name.contains("incorrect") && !name.contains("invalid")) { String[] pemtext = pem.split("-----"); this.der = Base64.getMimeDecoder().decode(pemtext[2]); } else { this.der = null; } } - Entry(String name, String pem, Class clazz, char[] password) { - this(name, pem, clazz, password, null); + Entry(String name, String pem, Class clazz, String provider, char[] password) { + this(name, pem, clazz, provider, password, null); } - Entry(String name, String pem, Class clazz) { - this(name, pem, clazz, null, null); + Entry(String name, String pem, Class clazz, String provider) { + this(name, pem, clazz, provider, null, null); } public Entry newClass(String name, Class c) { - return new Entry(name, pem, c, password); + return new Entry(name, pem, c, provider, password); } public Entry newClass(Class c) { @@ -360,20 +515,20 @@ class PEMData { Entry makeCRLF(String name) { return new Entry(name, Pattern.compile(System.lineSeparator()).matcher(pem).replaceAll("\r\n"), - clazz, password()); + clazz, provider, password()); } Entry makeCR(String name) { return new Entry(name, Pattern.compile(System.lineSeparator()).matcher(pem).replaceAll("\r"), - clazz, password()); + clazz, provider, password()); } Entry makeNoCRLF(String name) { return new Entry(name, LF.matcher(CR.matcher(pem).replaceAll("")). replaceAll(""), - clazz, password()); + clazz, provider, password()); } } @@ -401,10 +556,12 @@ class PEMData { static { pubList.add(rsapub); + pubList.add(rsapsspub); pubList.add(rsapubbc); pubList.add(ecsecp256pub.makeCR("ecsecp256pub-r")); pubList.add(ecsecp256pub.makeCRLF("ecsecp256pub-rn")); privList.add(rsapriv); + privList.add(rsapsspriv); privList.add(rsaprivbc); privList.add(ecsecp256); privList.add(ecsecp384); @@ -413,9 +570,12 @@ class PEMData { privList.add(rsaOpenSSL); oasList.add(oasrfc8410); oasList.add(oasbcpem); + oasList.add(oasec); + oasList.add(oasxdh); certList.add(rsaCert); certList.add(ecCert); + certList.add(rsaCrl); entryList.addAll(pubList); entryList.addAll(privList); @@ -429,6 +589,11 @@ class PEMData { failureEntryList.add(new Entry("emptyPEM", "", DEREncodable.class, null)); failureEntryList.add(new Entry("nullPEM", null, DEREncodable.class, null)); + failureEntryList.add(incorrectFooter); + failureEntryList.add(invalidPEM); + failureEntryList.add(invalidDer); + failureEntryList.add(invalidHeader); + failureEntryList.add(invalidFooter); } static void checkResults(PEMData.Entry entry, String result) { diff --git a/test/jdk/java/security/PEM/PEMDecoderTest.java b/test/jdk/java/security/PEM/PEMDecoderTest.java index 2ee9d1a69b3..90d67af2f8d 100644 --- a/test/jdk/java/security/PEM/PEMDecoderTest.java +++ b/test/jdk/java/security/PEM/PEMDecoderTest.java @@ -26,6 +26,7 @@ /* * @test * @bug 8298420 + * @library /test/lib * @modules java.base/sun.security.pkcs * java.base/sun.security.util * @summary Testing basic PEM API decoding @@ -37,23 +38,27 @@ import java.io.*; import java.lang.Class; import java.nio.charset.StandardCharsets; import java.security.*; +import java.security.cert.CertificateEncodingException; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.security.interfaces.*; -import java.security.spec.PKCS8EncodedKeySpec; -import java.security.spec.X509EncodedKeySpec; +import java.security.spec.*; import java.util.*; import java.util.Arrays; +import jdk.test.lib.Asserts; +import sun.security.pkcs.PKCS8Key; import sun.security.util.Pem; public class PEMDecoderTest { static HexFormat hex = HexFormat.of(); - public static void main(String[] args) throws IOException { + public static void main(String[] args) throws Exception { System.out.println("Decoder test:"); - PEMData.entryList.forEach(PEMDecoderTest::test); + PEMData.entryList.forEach(entry -> test(entry, false)); + System.out.println("Decoder test withFactory:"); + PEMData.entryList.forEach(entry -> test(entry, true)); System.out.println("Decoder test returning DEREncodable class:"); PEMData.entryList.forEach(entry -> test(entry, DEREncodable.class)); System.out.println("Decoder test with encrypted PEM:"); @@ -95,7 +100,11 @@ public class PEMDecoderTest { System.out.println("Check a Signature/Verify op is successful:"); PEMData.privList.forEach(PEMDecoderTest::testSignature); - PEMData.oasList.forEach(PEMDecoderTest::testSignature); + PEMData.oasList.stream().filter(e -> !e.name().endsWith("xdh")) + .forEach(PEMDecoderTest::testSignature); + + System.out.println("Checking if decode() returns a PKCS8Key and can generate a pub"); + PEMData.oasList.forEach(PEMDecoderTest::testPKCS8Key); System.out.println("Checking if ecCSR:"); test(PEMData.ecCSR); @@ -182,6 +191,10 @@ public class PEMDecoderTest { } catch (Exception e) { throw new AssertionError("error getting key", e); } + testCertTypeConverter(PEMData.ecCert); + + System.out.println("Decoder test testCoefZero:"); + testCoefZero(PEMData.rsaCrtCoefZeroPriv); } static void testInputStream() throws IOException { @@ -231,6 +244,24 @@ public class PEMDecoderTest { throw new AssertionError("Failed"); } + // test that X509 CERTIFICATE is converted to CERTIFICATE in PEM + static void testCertTypeConverter(PEMData.Entry entry) throws CertificateEncodingException { + String certPem = entry.pem().replace("CERTIFICATE", "X509 CERTIFICATE"); + Asserts.assertEqualsByteArray(entry.der(), + PEMDecoder.of().decode(certPem, X509Certificate.class).getEncoded()); + + certPem = entry.pem().replace("CERTIFICATE", "X.509 CERTIFICATE"); + Asserts.assertEqualsByteArray(entry.der(), + PEMDecoder.of().decode(certPem, X509Certificate.class).getEncoded()); + } + + // test that when the crtCoeff is zero, the key is decoded but only the modulus and private + // exponent are used resulting in a different der + static void testCoefZero(PEMData.Entry entry) { + RSAPrivateKey decoded = PEMDecoder.of().decode(entry.pem(), RSAPrivateKey.class); + Asserts.assertNotEqualsByteArray(decoded.getEncoded(), entry.der()); + } + static void testPEMRecord(PEMData.Entry entry) { PEMRecord r = PEMDecoder.of().decode(entry.pem(), PEMRecord.class); String expected = entry.pem().split("-----")[2].replace(System.lineSeparator(), ""); @@ -333,13 +364,26 @@ public class PEMDecoderTest { // Change the Entry to use the given class as the expected class returned static DEREncodable test(PEMData.Entry entry, Class c) { - return test(entry.newClass(c)); + return test(entry.newClass(c), false); } // Run test with a given Entry static DEREncodable test(PEMData.Entry entry) { + return test(entry, false); + } + + // Run test with a given Entry + static DEREncodable test(PEMData.Entry entry, boolean withFactory) { + System.out.printf("Testing %s %s%n", entry.name(), entry.provider()); try { - DEREncodable r = test(entry.pem(), entry.clazz(), PEMDecoder.of()); + PEMDecoder pemDecoder; + if (withFactory) { + Provider provider = Security.getProvider(entry.provider()); + pemDecoder = PEMDecoder.of().withFactory(provider); + } else { + pemDecoder = PEMDecoder.of(); + } + DEREncodable r = test(entry.pem(), entry.clazz(), pemDecoder); System.out.println("PASS (" + entry.name() + ")"); return r; } catch (Exception | AssertionError e) { @@ -412,6 +456,19 @@ public class PEMDecoderTest { } } + private static void testPKCS8Key(PEMData.Entry entry) { + try { + PKCS8Key key = PEMDecoder.of().decode(entry.pem(), PKCS8Key.class); + PKCS8EncodedKeySpec spec = + new PKCS8EncodedKeySpec(key.getEncoded()); + + KeyFactory kf = KeyFactory.getInstance(key.getAlgorithm()); + kf.generatePublic(spec); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } + static void testClass(PEMData.Entry entry, Class clazz) throws IOException { var pk = PEMDecoder.of().decode(entry.pem(), clazz); } @@ -472,9 +529,15 @@ public class PEMDecoderTest { "should not be null"); } + AlgorithmParameterSpec spec = null; String algorithm = switch(privateKey.getAlgorithm()) { case "EC" -> "SHA256withECDSA"; case "EdDSA" -> "EdDSA"; + case "RSASSA-PSS" -> { + spec = new PSSParameterSpec( + "SHA-256", "MGF1", MGF1ParameterSpec.SHA256, 32, 1); + yield "RSASSA-PSS"; + } case null -> { System.out.println("Algorithm is null " + entry.name()); @@ -487,6 +550,9 @@ public class PEMDecoderTest { try { if (d instanceof PrivateKey) { s = Signature.getInstance(algorithm); + if (spec != null) { + s.setParameter(spec); + } s.initSign(privateKey); s.update(data); s.sign(); diff --git a/test/jdk/java/security/PEM/PEMEncoderTest.java b/test/jdk/java/security/PEM/PEMEncoderTest.java index c8b19c313a5..3d1948ba2fe 100644 --- a/test/jdk/java/security/PEM/PEMEncoderTest.java +++ b/test/jdk/java/security/PEM/PEMEncoderTest.java @@ -26,9 +26,15 @@ /* * @test * @bug 8298420 + * @library /test/lib * @summary Testing basic PEM API encoding * @enablePreview * @modules java.base/sun.security.util + * @run main PEMEncoderTest PBEWithHmacSHA256AndAES_128 + * @run main/othervm -Djava.security.properties=${test.src}/java.security-anotherAlgo + * PEMEncoderTest PBEWithHmacSHA512AndAES_256 + * @run main/othervm -Djava.security.properties=${test.src}/java.security-emptyAlgo + * PEMEncoderTest PBEWithHmacSHA256AndAES_128 */ import sun.security.util.Pem; @@ -39,13 +45,22 @@ import javax.crypto.spec.PBEParameterSpec; import java.nio.charset.StandardCharsets; import java.security.*; import java.security.spec.InvalidParameterSpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; import java.util.*; +import jdk.test.lib.security.SecurityUtils; + +import static jdk.test.lib.Asserts.assertEquals; +import static jdk.test.lib.Asserts.assertThrows; + public class PEMEncoderTest { static Map keymap; + static String pkcs8DefaultAlgExpect; public static void main(String[] args) throws Exception { + pkcs8DefaultAlgExpect = args[0]; PEMEncoder encoder = PEMEncoder.of(); // These entries are removed @@ -63,7 +78,12 @@ public class PEMEncoderTest { System.out.println("New instance re-encode testToString:"); keymap.keySet().stream().forEach(key -> testToString(key, PEMEncoder.of())); - + System.out.println("Same instance Encoder testEncodedKeySpec:"); + testEncodedKeySpec(encoder); + System.out.println("New instance Encoder testEncodedKeySpec:"); + testEncodedKeySpec(PEMEncoder.of()); + System.out.println("Same instance Encoder testEmptyKey:"); + testEmptyAndNullKey(encoder); keymap = generateObjKeyMap(PEMData.encryptedList); System.out.println("Same instance Encoder match test:"); keymap.keySet().stream().forEach(key -> testEncryptedMatch(key, encoder)); @@ -86,6 +106,13 @@ public class PEMEncoderTest { PEMRecord pemRecord = d.decode(PEMData.ed25519ep8.pem(), PEMRecord.class); PEMData.checkResults(PEMData.ed25519ep8, pemRecord.toString()); + + // test PemRecord is encapsulated with PEM header and footer on encoding + String[] pemLines = PEMData.ed25519ep8.pem().split("\n"); + String[] pemNoHeaderFooter = Arrays.copyOfRange(pemLines, 1, pemLines.length - 1); + PEMRecord pemR = new PEMRecord("ENCRYPTED PRIVATE KEY", String.join("\n", + pemNoHeaderFooter)); + PEMData.checkResults(PEMData.ed25519ep8.pem(), encoder.encodeToString(pemR)); } static Map generateObjKeyMap(List list) { @@ -145,10 +172,12 @@ public class PEMEncoderTest { static void testEncrypted(String key, PEMEncoder encoder) { PEMData.Entry entry = PEMData.getEntry(key); try { - encoder.withEncryption( + String pem = encoder.withEncryption( (entry.password() != null ? entry.password() : "fish".toCharArray())) .encodeToString(keymap.get(key)); + + verifyEncriptionAlg(pem); } catch (RuntimeException e) { throw new AssertionError("Encrypted encoder failed with " + entry.name(), e); @@ -157,6 +186,11 @@ public class PEMEncoderTest { System.out.println("PASS: " + entry.name()); } + private static void verifyEncriptionAlg(String pem) { + var epki = PEMDecoder.of().decode(pem, EncryptedPrivateKeyInfo.class); + assertEquals(epki.getAlgName(), pkcs8DefaultAlgExpect); + } + /* Test cannot verify PEM was the same as known PEM because we have no public access to the AlgoritmID.params and PBES2Parameters. @@ -195,5 +229,42 @@ public class PEMEncoderTest { PEMData.checkResults(entry, result); System.out.println("PASS: " + entry.name()); } -} + static void testEncodedKeySpec(PEMEncoder encoder) throws NoSuchAlgorithmException { + KeyPair kp = getKeyPair(); + encoder.encodeToString(new X509EncodedKeySpec(kp.getPublic().getEncoded())); + encoder.encodeToString(new PKCS8EncodedKeySpec(kp.getPrivate().getEncoded())); + System.out.println("PASS: testEncodedKeySpec"); + } + private static void testEmptyAndNullKey(PEMEncoder encoder) throws NoSuchAlgorithmException { + KeyPair kp = getKeyPair(); + assertThrows(IllegalArgumentException.class, () -> encoder.encode( + new KeyPair(kp.getPublic(), new EmptyKey()))); + assertThrows(IllegalArgumentException.class, () -> encoder.encode( + new KeyPair(kp.getPublic(), null))); + + assertThrows(IllegalArgumentException.class, () -> encoder.encode( + new KeyPair(new EmptyKey(), kp.getPrivate()))); + assertThrows(IllegalArgumentException.class, () -> encoder.encode( + new KeyPair(null, kp.getPrivate()))); + System.out.println("PASS: testEmptyKey"); + } + + private static KeyPair getKeyPair() throws NoSuchAlgorithmException { + Provider provider = Security.getProvider("SunRsaSign"); + KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", provider); + kpg.initialize(SecurityUtils.getTestKeySize("RSA")); + return kpg.generateKeyPair(); + } + + private static class EmptyKey implements PublicKey, PrivateKey { + @Override + public String getAlgorithm() { return "Test"; } + + @Override + public String getFormat() { return "Test"; } + + @Override + public byte[] getEncoded() { return new byte[0]; } + } +} diff --git a/test/jdk/java/security/PEM/PEMMultiThreadTest.java b/test/jdk/java/security/PEM/PEMMultiThreadTest.java new file mode 100644 index 00000000000..f345a3c129d --- /dev/null +++ b/test/jdk/java/security/PEM/PEMMultiThreadTest.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8298420 + * @library /test/lib + * @summary Testing PEM API is thread safe + * @enablePreview + * @modules java.base/sun.security.util + */ + +import java.security.*; +import java.util.*; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import jdk.test.lib.security.SecurityUtils; + +public class PEMMultiThreadTest { + static final int THREAD_COUNT = 5; + static final int KEYS_COUNT = 50; + + public static void main(String[] args) throws Exception { + PEMEncoder encoder = PEMEncoder.of(); + try (ExecutorService ex = Executors.newFixedThreadPool(THREAD_COUNT)) { + Map keys = new HashMap<>(); + Map encoded = Collections.synchronizedMap(new HashMap<>()); + Map decoded = Collections.synchronizedMap(new HashMap<>()); + final CountDownLatch encodingComplete = new CountDownLatch(KEYS_COUNT); + final CountDownLatch decodingComplete = new CountDownLatch(KEYS_COUNT); + + // Generate keys and encode them in parallel + for (int i = 0; i < KEYS_COUNT; i++) { + final int finalI = i; + KeyPair kp = getKeyPair(); + keys.put(finalI, kp.getPublic()); + + ex.submit(() -> { + encoded.put(finalI, encoder.encodeToString(kp.getPublic())); + encodingComplete.countDown(); + }); + } + encodingComplete.await(); + + // Decode keys in parallel + PEMDecoder decoder = PEMDecoder.of(); + for (Map.Entry entry : encoded.entrySet()) { + ex.submit(() -> { + decoded.put(entry.getKey(), decoder.decode(entry.getValue(), PublicKey.class) + .toString()); + decodingComplete.countDown(); + }); + } + decodingComplete.await(); + + // verify all keys were properly encoded and decoded comparing with the original key map + for (Map.Entry kp : keys.entrySet()) { + if (!decoded.get(kp.getKey()).equals(kp.getValue().toString())) { + throw new RuntimeException("a key was not properly encoded and decoded: " + decoded); + } + } + } + + System.out.println("PASS: testThreadSafety"); + } + + private static KeyPair getKeyPair() throws NoSuchAlgorithmException { + String alg = "EC"; + KeyPairGenerator kpg = KeyPairGenerator.getInstance(alg); + kpg.initialize(SecurityUtils.getTestKeySize(alg)); + return kpg.generateKeyPair(); + } +} diff --git a/test/jdk/java/security/PEM/java.security-anotherAlgo b/test/jdk/java/security/PEM/java.security-anotherAlgo new file mode 100644 index 00000000000..c084f465fa2 --- /dev/null +++ b/test/jdk/java/security/PEM/java.security-anotherAlgo @@ -0,0 +1 @@ +jdk.epkcs8.defaultAlgorithm=PBEWithHmacSHA512AndAES_256 diff --git a/test/jdk/java/security/PEM/java.security-emptyAlgo b/test/jdk/java/security/PEM/java.security-emptyAlgo new file mode 100644 index 00000000000..deb2ab7aa45 --- /dev/null +++ b/test/jdk/java/security/PEM/java.security-emptyAlgo @@ -0,0 +1 @@ +jdk.epkcs8.defaultAlgorithm= diff --git a/test/jdk/java/util/logging/LogManagerAppContextDeadlock.java b/test/jdk/java/util/logging/LogManagerAppContextDeadlock.java deleted file mode 100644 index f39b46b43d1..00000000000 --- a/test/jdk/java/util/logging/LogManagerAppContextDeadlock.java +++ /dev/null @@ -1,381 +0,0 @@ -/* - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.lang.management.ManagementFactory; -import java.lang.management.ThreadInfo; -import java.security.CodeSource; -import java.security.Permission; -import java.security.PermissionCollection; -import java.security.Permissions; -import java.security.Policy; -import java.security.ProtectionDomain; -import java.util.Enumeration; -import java.util.concurrent.Semaphore; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.logging.LogManager; -import java.util.logging.Logger; -import jdk.internal.access.JavaAWTAccess; -import jdk.internal.access.SharedSecrets; - -/** - * @test - * @bug 8065991 - * @summary check that when LogManager is initialized, a deadlock similar - * to that described in 8065709 will not occur. - * @modules java.base/jdk.internal.access - * java.logging - * java.management - * @run main/othervm LogManagerAppContextDeadlock UNSECURE - * @run main/othervm LogManagerAppContextDeadlock SECURE - * - * @author danielfuchs - */ -public class LogManagerAppContextDeadlock { - - public static final Semaphore sem = new Semaphore(0); - public static final Semaphore sem2 = new Semaphore(0); - public static final Semaphore sem3 = new Semaphore(-2); - public static volatile boolean goOn = true; - public static volatile Exception thrown; - - // Emulate EventQueue - static class FakeEventQueue { - static final Logger logger = Logger.getLogger("foo"); - } - - // Emulate AppContext - static class FakeAppContext { - - static final AtomicInteger numAppContexts = new AtomicInteger(0); - static final class FakeAppContextLock {} - static final FakeAppContextLock lock = new FakeAppContextLock(); - static volatile FakeAppContext appContext; - - final FakeEventQueue queue; - FakeAppContext() { - appContext = this; - numAppContexts.incrementAndGet(); - // release sem2 to let Thread t2 call Logger.getLogger(). - sem2.release(); - try { - // Wait until we JavaAWTAccess is called by LogManager. - // Thread 2 will call Logger.getLogger() which will - // trigger a call to JavaAWTAccess - which will release - // sem, thus ensuring that Thread #2 is where we want it. - sem.acquire(); - System.out.println("Sem acquired: Thread #2 has called JavaAWTAccess"); - } catch(InterruptedException x) { - Thread.interrupted(); - } - queue = new FakeEventQueue(); - } - - static FakeAppContext getAppContext() { - synchronized (lock) { - if (numAppContexts.get() == 0) { - return new FakeAppContext(); - } - return appContext; - } - } - - static { - SharedSecrets.setJavaAWTAccess(new JavaAWTAccess() { - @Override - public Object getAppletContext() { - if (numAppContexts.get() == 0) return null; - // We are in JavaAWTAccess, we can release sem and let - // FakeAppContext constructor proceeed. - System.out.println("Releasing Sem"); - sem.release(); - return getAppContext(); - } - - }); - } - - } - - - // Test with or without a security manager - public static enum TestCase { - UNSECURE, SECURE; - public void run() throws Exception { - System.out.println("Running test case: " + name()); - Configure.setUp(this); - test(this); - } - } - - public static void test(TestCase test) throws Exception { - Thread t1 = new Thread() { - @Override - public void run() { - sem3.release(); - System.out.println("FakeAppContext.getAppContext()"); - FakeAppContext.getAppContext(); - System.out.println("Done: FakeAppContext.getAppContext()"); - } - }; - t1.setDaemon(true); - t1.start(); - Thread t2 = new Thread() { - public Object logger; - public void run() { - sem3.release(); - try { - // Wait until Thread1 is in FakeAppContext constructor - sem2.acquire(); - System.out.println("Sem2 acquired: Thread #1 will be waiting to acquire Sem"); - } catch (InterruptedException ie) { - Thread.interrupted(); - } - System.out.println("Logger.getLogger(name).info(name)"); - // stick the logger in an instance variable to prevent it - // from being garbage collected before the main thread - // calls LogManager.getLogger() below. - logger = Logger.getLogger(test.name());//.info(name); - System.out.println("Done: Logger.getLogger(name).info(name)"); - } - }; - t2.setDaemon(true); - t2.start(); - System.out.println("Should exit now..."); - Thread detector = new DeadlockDetector(); - detector.start(); - - // Wait for the 3 threads to start - sem3.acquire(); - - // Now wait for t1 & t2 to finish, or for a deadlock to be detected. - while (goOn && (t1.isAlive() || t2.isAlive())) { - if (t2.isAlive()) t2.join(1000); - if (test == TestCase.UNSECURE && System.getSecurityManager() == null) { - // if there's no security manager, AppContext.getAppContext() is - // not called - so Thread t2 will not end up calling - // sem.release(). In that case we must release the semaphore here - // so that t1 can proceed. - if (LogManager.getLogManager().getLogger(TestCase.UNSECURE.name()) != null) { - // means Thread t2 has created the logger - sem.release(); - } - } - if (t1.isAlive()) t1.join(1000); - } - if (thrown != null) { - throw thrown; - } - } - - // Thrown by the deadlock detector - static final class DeadlockException extends RuntimeException { - public DeadlockException(String message) { - super(message); - } - @Override - public void printStackTrace() { - } - } - - public static void main(String[] args) throws Exception { - - if (args.length == 0) { - args = new String[] { "SECURE" }; - } - - // If we don't initialize LogManager here, there will be - // a deadlock. - // See - // for more details. - Logger.getLogger("main").info("starting..."); - try { - TestCase.valueOf(args[0]).run(); - System.out.println("Test "+args[0]+" Passed"); - } catch(Throwable t) { - System.err.println("Test " + args[0] +" failed: " + t); - t.printStackTrace(); - } - } - - // Called by the deadlock detector when a deadlock is found. - static void fail(Exception x) { - x.printStackTrace(); - if (thrown == null) { - thrown = x; - } - goOn = false; - } - - // A thread that detect deadlocks. - static final class DeadlockDetector extends Thread { - - public DeadlockDetector() { - this.setDaemon(true); - } - - @Override - public void run() { - sem3.release(); - Configure.doPrivileged(this::loop); - } - public void loop() { - while(goOn) { - try { - long[] ids = ManagementFactory.getThreadMXBean().findDeadlockedThreads(); - ids = ids == null ? new long[0] : ids; - if (ids.length == 1) { - throw new RuntimeException("Found 1 deadlocked thread: "+ids[0]); - } else if (ids.length > 0) { - ThreadInfo[] infos = ManagementFactory.getThreadMXBean().getThreadInfo(ids, Integer.MAX_VALUE); - System.err.println("Found "+ids.length+" deadlocked threads: "); - for (ThreadInfo inf : infos) { - System.err.println(inf); - } - throw new DeadlockException("Found "+ids.length+" deadlocked threads"); - } - Thread.sleep(100); - } catch(InterruptedException | RuntimeException x) { - fail(x); - } - } - } - - } - - // A helper class to configure the security manager for the test, - // and bypass it when needed. - static class Configure { - static Policy policy = null; - static final ThreadLocal allowAll = new ThreadLocal() { - @Override - protected AtomicBoolean initialValue() { - return new AtomicBoolean(false); - } - }; - static void setUp(TestCase test) { - switch (test) { - case SECURE: - if (policy == null && System.getSecurityManager() != null) { - throw new IllegalStateException("SecurityManager already set"); - } else if (policy == null) { - policy = new SimplePolicy(TestCase.SECURE, allowAll); - Policy.setPolicy(policy); - System.setSecurityManager(new SecurityManager()); - } - if (System.getSecurityManager() == null) { - throw new IllegalStateException("No SecurityManager."); - } - if (policy == null) { - throw new IllegalStateException("policy not configured"); - } - break; - case UNSECURE: - if (System.getSecurityManager() != null) { - throw new IllegalStateException("SecurityManager already set"); - } - break; - default: - new InternalError("No such testcase: " + test); - } - } - static void doPrivileged(Runnable run) { - allowAll.get().set(true); - try { - run.run(); - } finally { - allowAll.get().set(false); - } - } - } - - // A Helper class to build a set of permissions. - static final class PermissionsBuilder { - final Permissions perms; - public PermissionsBuilder() { - this(new Permissions()); - } - public PermissionsBuilder(Permissions perms) { - this.perms = perms; - } - public PermissionsBuilder add(Permission p) { - perms.add(p); - return this; - } - public PermissionsBuilder addAll(PermissionCollection col) { - if (col != null) { - for (Enumeration e = col.elements(); e.hasMoreElements(); ) { - perms.add(e.nextElement()); - } - } - return this; - } - public Permissions toPermissions() { - final PermissionsBuilder builder = new PermissionsBuilder(); - builder.addAll(perms); - return builder.perms; - } - } - - // Policy for the test... - public static class SimplePolicy extends Policy { - - static final Policy DEFAULT_POLICY = Policy.getPolicy(); - - final Permissions permissions; - final Permissions allPermissions; - final ThreadLocal allowAll; // actually: this should be in a thread locale - public SimplePolicy(TestCase test, ThreadLocal allowAll) { - this.allowAll = allowAll; - // we don't actually need any permission to create our - // FileHandlers because we're passing invalid parameters - // which will make the creation fail... - permissions = new Permissions(); - permissions.add(new RuntimePermission("accessClassInPackage.jdk.internal.access")); - - // these are used for configuring the test itself... - allPermissions = new Permissions(); - allPermissions.add(new java.security.AllPermission()); - - } - - @Override - public boolean implies(ProtectionDomain domain, Permission permission) { - if (allowAll.get().get()) return allPermissions.implies(permission); - return permissions.implies(permission) || DEFAULT_POLICY.implies(domain, permission); - } - - @Override - public PermissionCollection getPermissions(CodeSource codesource) { - return new PermissionsBuilder().addAll(allowAll.get().get() - ? allPermissions : permissions).toPermissions(); - } - - @Override - public PermissionCollection getPermissions(ProtectionDomain domain) { - return new PermissionsBuilder().addAll(allowAll.get().get() - ? allPermissions : permissions).toPermissions(); - } - } - -} diff --git a/test/jdk/java/util/logging/TestGetLoggerNPE.java b/test/jdk/java/util/logging/TestGetLoggerNPE.java deleted file mode 100644 index 02c57b75067..00000000000 --- a/test/jdk/java/util/logging/TestGetLoggerNPE.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -import java.io.PrintStream; -import java.util.logging.LogManager; -import java.util.logging.Logger; -import jdk.internal.access.JavaAWTAccess; -import jdk.internal.access.SharedSecrets; - -/* - * @test - * @bug 8025512 - * - * @summary NPE with logging while launching webstart - * - * @modules java.base/jdk.internal.access - * java.logging - * @build TestGetLoggerNPE - * @run main/othervm TestGetLoggerNPE getLogger - * @run main/othervm TestGetLoggerNPE getLogManager - */ -public class TestGetLoggerNPE { - static volatile Throwable thrown = null; - public static void main(String[] args) throws Exception { - final String testCase = args.length == 0 ? "getLogger" : args[0]; - final JavaAWTAccessStub access = new JavaAWTAccessStub(); - SharedSecrets.setJavaAWTAccess(access); - final ThreadGroup tg = new ThreadGroup("TestGroup"); - Thread t = new Thread(tg, "test") { - public void run() { - try { - access.setContext(Context.ONE); - final PrintStream out = System.out; - System.setOut(null); - try { - if ("getLogger".equals(testCase)) { - Logger.getLogger("sun.plugin"); - } else { - LogManager.getLogManager(); - } - } finally { - System.setOut(out); - } - - System.out.println(Logger.global); - } catch (Throwable x) { - x.printStackTrace(); - thrown = x; - } - } - }; - t.start(); - t.join(); - if (thrown == null) { - System.out.println("PASSED: " + testCase); - } else { - System.err.println("FAILED: " + testCase); - throw new Error("Test failed: " + testCase + " - " + thrown, thrown); - } - - } - - static enum Context { ONE, TWO }; - - static final class JavaAWTAccessStub implements JavaAWTAccess { - private static final InheritableThreadLocal context = new InheritableThreadLocal<>(); - - - public void setContext(Context context) { - JavaAWTAccessStub.context.set(context); - } - - @Override - public Object getAppletContext() { - return context.get(); - } - - } - -} diff --git a/test/jdk/java/util/logging/TestUILoggerContext.java b/test/jdk/java/util/logging/TestUILoggerContext.java deleted file mode 100644 index d5e170a1100..00000000000 --- a/test/jdk/java/util/logging/TestUILoggerContext.java +++ /dev/null @@ -1,520 +0,0 @@ -/* - * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.util.EnumSet; -import java.util.HashMap; -import java.util.Map; -import java.util.logging.LogManager; -import java.util.logging.Logger; -import jdk.internal.access.JavaAWTAccess; -import jdk.internal.access.SharedSecrets; - -/* - * @test - * @bug 8017174 8010727 8019945 - * @summary NPE when using Logger.getAnonymousLogger or - * LogManager.getLogManager().getLogger - * - * @modules java.base/jdk.internal.access - * java.logging - * @run main/othervm TestUILoggerContext LoadingUIContext - * @run main/othervm TestUILoggerContext LoadingMain - * @run main/othervm TestUILoggerContext One - * @run main/othervm TestUILoggerContext Two - * @run main/othervm TestUILoggerContext Three - * @run main/othervm TestUILoggerContext Four - * @run main/othervm TestUILoggerContext Five - * @run main/othervm TestUILoggerContext Six - * @run main/othervm TestUILoggerContext Seven - * @run main/othervm TestUILoggerContext - */ - -// NOTE: We run in other VM in order to cause LogManager class to be loaded anew. -public class TestUILoggerContext { - - // The bridge class initializes the logging system. - // It stubs the UI context in order to simulate context changes. - // - public static class Bridge { - - private static class JavaAWTAccessStub implements JavaAWTAccess { - boolean active = true; - - private static class TestExc { - private final Map map = new HashMap<>(); - void put(Object key, Object v) { map.put(key, v); } - Object get(Object key) { return map.get(key); } - void remove(Object o) { map.remove(o); } - public static TestExc exc(Object o) { - return TestExc.class.cast(o); - } - } - - TestExc exc; - - @Override - public Object getAppletContext() { return active ? exc : null; } - } - - static final JavaAWTAccessStub javaAwtAccess = new JavaAWTAccessStub(); - public static void init() { - SharedSecrets.setJavaAWTAccess(javaAwtAccess); - } - - public static void changeContext() { - System.out.println("... Switching to a new UI context ..."); - javaAwtAccess.active = true; - javaAwtAccess.exc = new JavaAWTAccessStub.TestExc(); - } - - public static void desactivate() { - System.out.println("... Running with no UI context ..."); - javaAwtAccess.exc = null; - javaAwtAccess.active = false; - } - - public static class CustomAnonymousLogger extends Logger { - public CustomAnonymousLogger() { - this(""); - } - public CustomAnonymousLogger(String name) { - super(null, null); - System.out.println( " LogManager: " +LogManager.getLogManager()); - System.out.println( " getLogger: " +LogManager.getLogManager().getLogger(name)); - setParent(LogManager.getLogManager().getLogger(name)); - } - } - - public static class CustomLogger extends Logger { - CustomLogger(String name) { - super(name, null); - } - } - } - - public static enum TestCase { - LoadingUIContext, LoadingMain, One, Two, Three, Four, Five, Six, Seven; - public void test() { - switch(this) { - // When run - each of these two tests must be - // run before any other tests and before each other. - case LoadingUIContext: testLoadingUIContext(); break; - case LoadingMain: testLoadingMain(); break; - case One: testOne(); break; - case Two: testTwo(); break; - case Three: testThree(); break; - case Four: testFour(); break; - case Five: testFive(); break; - case Six: testSix(); break; - case Seven: testSeven(); break; - } - } - public String describe() { - switch(this) { - case LoadingUIContext: - return "Test that when the LogManager class is" - + " loaded with UI context first," - + "\n all LoggerContexts are correctly initialized"; - case LoadingMain: - return "Test that when the LogManager class is" - + " loaded in the main thread first," - + "\n all LoggerContexts are correctly initialized"; - case One: - return "Test that Logger.getAnonymousLogger()" - + " and new CustomAnonymousLogger() don't throw NPE"; - case Two: - return "Test that Logger.getLogger(\"\")" - + " does not return null nor throws NPE"; - case Three: - return "Test that LogManager.getLogManager().getLogger(\"\")" - + " does not return null nor throws NPE"; - case Four: - return "Test that Logger.getLogger(Logger.GLOBAL_LOGGER_NAME)" - + " does not return null,\n and that" - + " new CustomAnonymousLogger(Logger.GLOBAL_LOGGER_NAME)" - + " does not throw NPE"; - case Five: - return "Test that LogManager.getLogManager().getLogger(Logger.GLOBAL_LOGGER_NAME)" - + "\n does not return null nor throws NPE"; - case Six: - return "Test that manager.getLogger(Logger.GLOBAL_LOGGER_NAME)" - + " returns null\n when manager is not the default" - + " LogManager instance.\n" - + "Test adding a new logger named \"global\" in that" - + " non default instance."; - case Seven: return "Test that manager.getLogger(\"\")" - + " returns null\n when manager is not the default" - + " LogManager instance.\n" - + "Test adding a new logger named \"\" in that" - + " non default instance."; - default: return "Undefined"; - } - } - }; - - /** - * @param args the command line arguments - */ - public static void main(String[] args) { - Bridge.init(); - EnumSet tests = EnumSet.noneOf(TestCase.class); - for (String arg : args) { - tests.add(TestCase.valueOf(arg)); - } - if (args.length == 0) { - tests = EnumSet.complementOf(EnumSet.of(TestCase.LoadingMain)); - } - final EnumSet loadingTests = - EnumSet.of(TestCase.LoadingUIContext, TestCase.LoadingMain); - int testrun = 0; - for (TestCase test : tests) { - if (loadingTests.contains(test)) { - if (testrun > 0) { - throw new UnsupportedOperationException("Test case " - + test + " must be executed first!"); - } - } - System.out.println("Testing "+ test+": "); - System.out.println(test.describe()); - try { - test.test(); - } catch (Exception x) { - throw new Error(String.valueOf(test) - + "failed: "+x+"\n "+"FAILED: "+test.describe()+"\n", x); - } finally { - testrun++; - } - Bridge.changeContext(); - System.out.println("PASSED: "+ test); - } - } - - public static void testLoadingUIContext() { - Bridge.changeContext(); - - Logger bar = new Bridge.CustomLogger("com.foo.Bar"); - LogManager.getLogManager().addLogger(bar); - assertNotNull(bar.getParent()); - testParent(bar); - testParent(LogManager.getLogManager().getLogger("global")); - testParent(LogManager.getLogManager().getLogger(bar.getName())); - - Bridge.desactivate(); - - Logger foo = new Bridge.CustomLogger("com.foo.Foo"); - boolean b = LogManager.getLogManager().addLogger(foo); - assertEquals(Boolean.TRUE, Boolean.valueOf(b)); - assertNotNull(foo.getParent()); - testParent(foo); - testParent(LogManager.getLogManager().getLogger("global")); - testParent(LogManager.getLogManager().getLogger(foo.getName())); - } - - public static void testLoadingMain() { - Bridge.desactivate(); - - Logger bar = new Bridge.CustomLogger("com.foo.Bar"); - LogManager.getLogManager().addLogger(bar); - assertNotNull(bar.getParent()); - testParent(bar); - testParent(LogManager.getLogManager().getLogger("global")); - testParent(LogManager.getLogManager().getLogger(bar.getName())); - - Bridge.changeContext(); - - Logger foo = new Bridge.CustomLogger("com.foo.Foo"); - boolean b = LogManager.getLogManager().addLogger(foo); - assertEquals(Boolean.TRUE, Boolean.valueOf(b)); - assertNotNull(foo.getParent()); - testParent(foo); - testParent(LogManager.getLogManager().getLogger("global")); - testParent(LogManager.getLogManager().getLogger(foo.getName())); - - } - - public static void testOne() { - for (int i=0; i<3 ; i++) { - Logger logger1 = Logger.getAnonymousLogger(); - Logger logger1b = Logger.getAnonymousLogger(); - Bridge.changeContext(); - Logger logger2 = Logger.getAnonymousLogger(); - Logger logger2b = Logger.getAnonymousLogger(); - Bridge.changeContext(); - Logger logger3 = new Bridge.CustomAnonymousLogger(); - Logger logger3b = new Bridge.CustomAnonymousLogger(); - Bridge.changeContext(); - Logger logger4 = new Bridge.CustomAnonymousLogger(); - Logger logger4b = new Bridge.CustomAnonymousLogger(); - } - } - - - public static void testTwo() { - for (int i=0; i<3 ; i++) { - Logger logger1 = Logger.getLogger(""); - Logger logger1b = Logger.getLogger(""); - assertNotNull(logger1); - assertNotNull(logger1b); - assertEquals(logger1, logger1b); - Bridge.changeContext(); - Logger logger2 = Logger.getLogger(""); - Logger logger2b = Logger.getLogger(""); - assertNotNull(logger2); - assertNotNull(logger2b); - assertEquals(logger2, logger2b); - assertEquals(logger1, logger2); - } - } - - public static void testThree() { - for (int i=0; i<3 ; i++) { - Logger logger1 = LogManager.getLogManager().getLogger(""); - Logger logger1b = LogManager.getLogManager().getLogger(""); - assertNotNull(logger1); - assertNotNull(logger1b); - assertEquals(logger1, logger1b); - Bridge.changeContext(); - Logger logger2 = LogManager.getLogManager().getLogger(""); - Logger logger2b = LogManager.getLogManager().getLogger(""); - assertNotNull(logger2); - assertNotNull(logger2b); - assertEquals(logger2, logger2b); - assertEquals(logger1, logger2); - } - } - - public static void testFour() { - for (int i=0; i<3 ; i++) { - Logger logger1 = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME); - Logger logger1b = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME); - assertNotNull(logger1); - assertNotNull(logger1b); - assertEquals(logger1, logger1b); - Bridge.changeContext(); - - Logger logger2 = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME); - Logger logger2b = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME); - assertNotNull(logger2); - assertNotNull(logger2b); - assertEquals(logger2, logger2b); - - assertEquals(logger1, logger2); - - Bridge.changeContext(); - Logger logger3 = new Bridge.CustomAnonymousLogger(Logger.GLOBAL_LOGGER_NAME); - Logger logger3b = new Bridge.CustomAnonymousLogger(Logger.GLOBAL_LOGGER_NAME); - Bridge.changeContext(); - Logger logger4 = new Bridge.CustomAnonymousLogger(Logger.GLOBAL_LOGGER_NAME); - Logger logger4b = new Bridge.CustomAnonymousLogger(Logger.GLOBAL_LOGGER_NAME); - } - } - - public static void testFive() { - for (int i=0; i<3 ; i++) { - Logger logger1 = LogManager.getLogManager().getLogger(Logger.GLOBAL_LOGGER_NAME); - Logger logger1b = LogManager.getLogManager().getLogger(Logger.GLOBAL_LOGGER_NAME); - assertNotNull(logger1); - assertNotNull(logger1b); - assertEquals(logger1, logger1b); - - Bridge.changeContext(); - - Logger logger2 = LogManager.getLogManager().getLogger(Logger.GLOBAL_LOGGER_NAME); - Logger logger2b = LogManager.getLogManager().getLogger(Logger.GLOBAL_LOGGER_NAME); - assertNotNull(logger2); - assertNotNull(logger2b); - assertEquals(logger2, logger2b); - - assertEquals(logger1, logger2); - } - } - - /** - * This test is designed to test the behavior of additional LogManager instances. - * It must be noted that if the security manager is off, then calling - * Bridge.changeContext() has actually no effect. - * off. - **/ - public static void testSix() { - for (int i=0; i<3 ; i++) { - Bridge.desactivate(); - LogManager manager = new LogManager() {}; - Logger logger1 = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); - Logger logger1b = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); - assertNull(logger1); - assertNull(logger1b); - Logger global = new Bridge.CustomLogger(Logger.GLOBAL_LOGGER_NAME); - manager.addLogger(global); - Logger logger2 = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); - Logger logger2b = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); - assertNotNull(logger2); - assertNotNull(logger2b); - assertEquals(logger2, global); - assertEquals(logger2b, global); - assertNull(manager.getLogger("")); - assertNull(manager.getLogger("")); - - for (int j = 0; j<3; j++) { - Bridge.changeContext(); - - // this is not a supported configuration: - // We are in an UI context with several log managers. - // We however need to check our assumptions... - - // UI context => root logger and global logger should also be null. - - Logger expected = global; - Logger logger3 = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); - Logger logger3b = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); - assertEquals(expected, logger3); - assertEquals(expected, logger3b); - Logger global2 = new Bridge.CustomLogger(Logger.GLOBAL_LOGGER_NAME); - manager.addLogger(global2); - Logger logger4 = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); - Logger logger4b = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); - assertNotNull(logger4); - assertNotNull(logger4b); - expected = global; - assertEquals(logger4, expected); - assertEquals(logger4b, expected); - - Logger logger5 = manager.getLogger(""); - Logger logger5b = manager.getLogger(""); - Logger expectedRoot = null; - assertEquals(logger5, expectedRoot); - assertEquals(logger5b, expectedRoot); - } - - } - } - - /** - * This test is designed to test the behavior of additional LogManager instances. - * It must be noted that if the security manager is off, then calling - * Bridge.changeContext() has actually no effect. - **/ - public static void testSeven() { - for (int i=0; i<3 ; i++) { - Bridge.desactivate(); - LogManager manager = new LogManager() {}; - Logger logger1 = manager.getLogger(""); - Logger logger1b = manager.getLogger(""); - assertNull(logger1); - assertNull(logger1b); - Logger global = new Bridge.CustomLogger(Logger.GLOBAL_LOGGER_NAME); - manager.addLogger(global); - Logger logger2 = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); - Logger logger2b = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); - assertNotNull(logger2); - assertNotNull(logger2b); - assertEquals(logger2, global); - assertEquals(logger2b, global); - Logger logger3 = manager.getLogger(""); - Logger logger3b = manager.getLogger(""); - assertNull(logger3); - assertNull(logger3b); - Logger root = new Bridge.CustomLogger(""); - manager.addLogger(root); - Logger logger4 = manager.getLogger(""); - Logger logger4b = manager.getLogger(""); - assertNotNull(logger4); - assertNotNull(logger4b); - assertEquals(logger4, root); - assertEquals(logger4b, root); - - for (int j = 0 ; j < 3 ; j++) { - Bridge.changeContext(); - - // this is not a supported configuration: - // We are in an UI context with several log managers. - // We however need to check our assumptions... - - // UI context => root logger and global logger should also be null. - - Logger logger5 = manager.getLogger(""); - Logger logger5b = manager.getLogger(""); - Logger expectedRoot = root; - assertEquals(logger5, expectedRoot); - assertEquals(logger5b, expectedRoot); - - assertEquals(global, manager.getLogger(Logger.GLOBAL_LOGGER_NAME)); - - Logger global2 = new Bridge.CustomLogger(Logger.GLOBAL_LOGGER_NAME); - manager.addLogger(global2); - Logger logger6 = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); - Logger logger6b = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); - Logger expectedGlobal = global; - - assertNotNull(logger6); - assertNotNull(logger6b); - assertEquals(logger6, expectedGlobal); - assertEquals(logger6b, expectedGlobal); - assertEquals(root, manager.getLogger("")); - - Logger root2 = new Bridge.CustomLogger(""); - manager.addLogger(root2); - expectedRoot = root; - Logger logger7 = manager.getLogger(""); - Logger logger7b = manager.getLogger(""); - assertNotNull(logger7); - assertNotNull(logger7b); - assertEquals(logger7, expectedRoot); - assertEquals(logger7b, expectedRoot); - } - } - } - - public static void testParent(Logger logger) { - Logger l = logger; - while (l.getParent() != null) { - l = l.getParent(); - } - assertEquals("", l.getName()); - } - - public static class TestError extends RuntimeException { - public TestError(String msg) { - super(msg); - } - } - - public static void assertNotNull(Object obj) { - if (obj == null) throw new NullPointerException(); - } - - public static void assertNull(Object obj) { - if (obj != null) throw new TestError("Null expected, got "+obj); - } - - public static void assertEquals(Object o1, Object o2) { - if (o1 != o2) { - throw new TestError(o1 + " != " + o2); - } - } - - public static void assertNotEquals(Object o1, Object o2) { - if (o1 == o2) { - throw new TestError(o1 + " == " + o2); - } - } -} diff --git a/test/jdk/javax/crypto/Cipher/TestEmptyModePadding.java b/test/jdk/javax/crypto/Cipher/TestEmptyModePadding.java new file mode 100644 index 00000000000..bd36e7f3ca7 --- /dev/null +++ b/test/jdk/javax/crypto/Cipher/TestEmptyModePadding.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025 IBM Corporation. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8358159 + * @summary test that the Cipher.getInstance() handles + * transformations with empty mode and/or padding + * @run main TestEmptyModePadding + */ + + +import java.security.*; +import javax.crypto.*; + +public class TestEmptyModePadding { + + public static void main(String[] args) throws Exception { + Provider provider = Security.getProvider(System.getProperty("test.provider.name", "SunJCE")); + + test("AES", provider); + test("AES/ECB/PKCS5Padding", provider); + test("AES//PKCS5Padding", provider); // Empty mode + test("AES/CBC/", provider); // Empty padding + test("AES/ /NoPadding", provider); // Mode is a space + test("AES/CBC/ ", provider); // Padding is a space + test("AES/ / ", provider); // Both mode and padding are spaces + test("AES//", provider); // Both mode and padding are missing + + } + + private static void test(String transformation, Provider provider) throws Exception { + Cipher c = Cipher.getInstance(transformation, provider); + } +} diff --git a/test/jdk/javax/crypto/EncryptedPrivateKeyInfo/EncryptKey.java b/test/jdk/javax/crypto/EncryptedPrivateKeyInfo/EncryptKey.java index d1fccd9730a..3fe8cfcfbfa 100644 --- a/test/jdk/javax/crypto/EncryptedPrivateKeyInfo/EncryptKey.java +++ b/test/jdk/javax/crypto/EncryptedPrivateKeyInfo/EncryptKey.java @@ -25,11 +25,15 @@ /** * @test + * @library /test/lib + * @modules java.base/sun.security.util * @bug 8298420 * @summary Testing encryptKey * @enablePreview */ +import sun.security.util.Pem; + import javax.crypto.EncryptedPrivateKeyInfo; import javax.crypto.SecretKey; import javax.crypto.spec.PBEParameterSpec; @@ -37,8 +41,13 @@ import javax.crypto.spec.SecretKeySpec; import java.security.AlgorithmParameters; import java.security.PEMDecoder; import java.security.PrivateKey; +import java.security.Provider; +import java.security.SecureRandom; +import java.security.Security; import java.util.Arrays; +import static jdk.test.lib.Asserts.assertEquals; + public class EncryptKey { private static final String encEdECKey = @@ -56,6 +65,8 @@ public class EncryptKey { passwdText.getBytes(), "PBE"); public static void main(String[] args) throws Exception { + Provider p = Security.getProvider(System.getProperty("test.provider.name", "SunJCE")); + EncryptedPrivateKeyInfo ekpi = PEMDecoder.of().decode(encEdECKey, EncryptedPrivateKeyInfo.class); PrivateKey priKey = PEMDecoder.of().withDecryption(password). @@ -71,6 +82,19 @@ public class EncryptKey { " with expected."); } + // Test encryptKey(PrivateKey, char[], String, ...) with provider + e = EncryptedPrivateKeyInfo.encryptKey(priKey, password, ekpi.getAlgName(), + ap.getParameterSpec(PBEParameterSpec.class), p); + if (!Arrays.equals(ekpi.getEncryptedData(), e.getEncryptedData())) { + throw new AssertionError("encryptKey() didn't match" + + " with expected."); + } + + // Test encryptKey(PrivateKey, char[], String, ...) with provider and null algorithm + e = EncryptedPrivateKeyInfo.encryptKey(priKey, password, null, null, + p); + assertEquals(e.getAlgName(), Pem.DEFAULT_ALGO); + // Test encryptKey(PrivateKey, Key, String, ...) e = EncryptedPrivateKeyInfo.encryptKey(priKey, key, ekpi.getAlgName(), ap.getParameterSpec(PBEParameterSpec.class),null, null); @@ -78,5 +102,26 @@ public class EncryptKey { throw new AssertionError("encryptKey() didn't match" + " with expected."); } + + // Test encryptKey(PrivateKey, Key, String, ...) with provider and null random + e = EncryptedPrivateKeyInfo.encryptKey(priKey, key, ekpi.getAlgName(), + ap.getParameterSpec(PBEParameterSpec.class), p, null); + if (!Arrays.equals(ekpi.getEncryptedData(), e.getEncryptedData())) { + throw new AssertionError("encryptKey() didn't match" + + " with expected."); + } + + // Test encryptKey(PrivateKey, Key, String, ...) with provider and SecureRandom + e = EncryptedPrivateKeyInfo.encryptKey(priKey, key, ekpi.getAlgName(), + ap.getParameterSpec(PBEParameterSpec.class), p, new SecureRandom()); + if (!Arrays.equals(ekpi.getEncryptedData(), e.getEncryptedData())) { + throw new AssertionError("encryptKey() didn't match" + + " with expected."); + } + + // Test encryptKey(PrivateKey, Key, String, ...) with provider and null algorithm + e = EncryptedPrivateKeyInfo.encryptKey(priKey, key, null, null, + p, new SecureRandom()); + assertEquals(e.getAlgName(), Pem.DEFAULT_ALGO); } } diff --git a/test/jdk/javax/crypto/EncryptedPrivateKeyInfo/GetKey.java b/test/jdk/javax/crypto/EncryptedPrivateKeyInfo/GetKey.java index 7c8951b3417..b1917ffa84d 100644 --- a/test/jdk/javax/crypto/EncryptedPrivateKeyInfo/GetKey.java +++ b/test/jdk/javax/crypto/EncryptedPrivateKeyInfo/GetKey.java @@ -35,6 +35,8 @@ import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import java.security.PEMDecoder; import java.security.PrivateKey; +import java.security.Provider; +import java.security.Security; import java.util.Arrays; public class GetKey { @@ -48,12 +50,29 @@ public class GetKey { IycFtI70ciPjgwDSjtCcPxR8fSxJPrm2yOJsRVo= -----END ENCRYPTED PRIVATE KEY----- """; + private static final String encDHECKey = + """ + -----BEGIN ENCRYPTED PRIVATE KEY----- + MIIBvDBmBgkqhkiG9w0BBQ0wWTA4BgkqhkiG9w0BBQwwKwQUN8pkErJx7aqH0fJF + BcOadPKiuRoCAhAAAgEQMAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAECBBAT1Vwd + gU4rTd6zy7lKr4wmBIIBUMe+2+O0AG6t4CMSHcDVceRg2jvbs5PmPjW4Ka5mDich + hVEsjSpJLbUyJdbji6UaiUpuWgvYSMLZ10pfhOFw/ssXwCw+JrlXUqDpQGLaW8ZR + zSL3CoozTI2Y6EBdWt53KbySwtZMoTpW/W3vPi98bJXtR635msf6gYXmSUP7DyoJ + 79dxz3pRYsnOuBe0yZ2wTq9iMgTMudzLJAFX2qyi+3KOb1g5Va9DYAqJmzCYOd74 + +I+0gGNFtSc1vGQYr3cAfcKT8AZ1RHE4IkpnpgFD5HsZ8f4hy0yK8juk9NE9Gzuy + B929LBXk6V3L0MKzIABS3QvAlhWETM6XtGBDugzAgsooo9lEHLwYRldvOlL+QYyE + CtqDmXOrgEMWvxWGEFCTKYhKkqMKjU3y3GiozEEdb9j2okW1s30yHQjIoj0OR4nB + D8GeP0QnY73NfbOw7z81TA== + -----END ENCRYPTED PRIVATE KEY----- + """; private static final String passwdText = "fish"; private static final char[] password = passwdText.toCharArray(); private static final SecretKey key = new SecretKeySpec( passwdText.getBytes(), "PBE"); public static void main(String[] args) throws Exception { + Provider p = Security.getProvider(System.getProperty("test.provider.name", "SunJCE")); + EncryptedPrivateKeyInfo ekpi = PEMDecoder.of().decode(encEdECKey, EncryptedPrivateKeyInfo.class); PrivateKey priKey = PEMDecoder.of().withDecryption(password). @@ -66,11 +85,23 @@ public class GetKey { + "match with expected."); } - // Test getKey(key, provider) + // Test getKey(key, provider) provider null if (!Arrays.equals(priKey.getEncoded(), ekpi.getKey(key, null).getEncoded())) { throw new AssertionError("getKey(key, provider) " + "didn't match with expected."); } + + // Test getKey(key, provider) with provider + EncryptedPrivateKeyInfo ekpiDH = PEMDecoder.of().decode(encDHECKey, + EncryptedPrivateKeyInfo.class); + PrivateKey priKeyDH = PEMDecoder.of().withDecryption(password). + decode(encDHECKey, PrivateKey.class); + + if (!Arrays.equals(priKeyDH.getEncoded(), + ekpiDH.getKey(key, p).getEncoded())) { + throw new AssertionError("getKey(key, provider) " + + "didn't match with expected."); + } } } diff --git a/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java b/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java index 2bfd3ea7603..0822205bbaf 100644 --- a/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java +++ b/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 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 @@ -557,6 +557,36 @@ * @run main/othervm/manual -Djava.security.debug=certpath CAInterop ssltlsrootrsa2022 CRL */ +/* + * @test id=sectigotlsrootr46 + * @bug 8359170 + * @summary Interoperability tests with Sectigo Public Server Authentication + * Root R46 + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop + * sectigotlsrootr46 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp + * -Dcom.sun.security.ocsp.useget=false CAInterop sectigotlsrootr46 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath CAInterop + * sectigotlsrootr46 CRL + */ + +/* + * @test id=sectigotlsroote46 + * @bug 8359170 + * @summary Interoperability tests with Sectigo Public Server Authentication + * Root E46 + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop + * sectigotlsroote46 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp + * -Dcom.sun.security.ocsp.useget=false CAInterop sectigotlsroote46 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath CAInterop + * sectigotlsroote46 CRL + */ + /** * Collection of certificate validation tests for interoperability with external CAs. * These tests are marked as manual as they depend on external infrastructure and may fail @@ -635,20 +665,20 @@ public class CAInterop { "https://revoked.sfig2.catest.starfieldtech.com"); case "globalsigneccrootcar4" -> - new CATestURLs("https://good.gsr4.demo.pki.goog", - "https://revoked.gsr4.demo.pki.goog"); + new CATestURLs("https://good.gsr4.demosite.pki.goog", + "https://revoked.gsr4.demosite.pki.goog"); case "gtsrootcar1" -> - new CATestURLs("https://good.gtsr1.demo.pki.goog", - "https://revoked.gtsr1.demo.pki.goog"); + new CATestURLs("https://good.gtsr1.demosite.pki.goog", + "https://revoked.gtsr1.demosite.pki.goog"); case "gtsrootcar2" -> - new CATestURLs("https://good.gtsr2.demo.pki.goog", - "https://revoked.gtsr2.demo.pki.goog"); + new CATestURLs("https://good.gtsr2.demosite.pki.goog", + "https://revoked.gtsr2.demosite.pki.goog"); case "gtsrootecccar3" -> - new CATestURLs("https://good.gtsr3.demo.pki.goog", - "https://revoked.gtsr3.demo.pki.goog"); + new CATestURLs("https://good.gtsr3.demosite.pki.goog", + "https://revoked.gtsr3.demosite.pki.goog"); case "gtsrootecccar4" -> - new CATestURLs("https://good.gtsr4.demo.pki.goog", - "https://revoked.gtsr4.demo.pki.goog"); + new CATestURLs("https://good.gtsr4.demosite.pki.goog", + "https://revoked.gtsr4.demosite.pki.goog"); case "microsoftecc2017" -> new CATestURLs("https://acteccroot2017.pki.microsoft.com", @@ -742,6 +772,13 @@ public class CAInterop { new CATestURLs("https://test-root-2022-rsa.ssl.com", "https://revoked-root-2022-rsa.ssl.com"); + case "sectigotlsrootr46" -> + new CATestURLs("https://sectigopublicserverauthenticationrootr46-ev.sectigo.com", + "https://sectigopublicserverauthenticationrootr46-ev.sectigo.com:444"); + case "sectigotlsroote46" -> + new CATestURLs("https://sectigopublicserverauthenticationroote46-ev.sectigo.com", + "https://sectigopublicserverauthenticationroote46-ev.sectigo.com:444"); + default -> throw new RuntimeException("No test setup found for: " + alias); }; } diff --git a/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/SectigoCSRootCAs.java b/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/SectigoCSRootCAs.java new file mode 100644 index 00000000000..80cd1d41cbc --- /dev/null +++ b/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/SectigoCSRootCAs.java @@ -0,0 +1,310 @@ +/* + * Copyright (c) 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8359170 + * @summary Interoperability tests with Sectigo Public Code Signing Root CAs + * @build ValidatePathWithParams + * @run main/othervm/manual -Djava.security.debug=ocsp,certpath SectigoCSRootCAs OCSP + * @run main/othervm/manual -Djava.security.debug=certpath SectigoCSRootCAs CRL + */ + +public class SectigoCSRootCAs { + + public static void main(String[] args) throws Exception { + + ValidatePathWithParams pathValidator = new ValidatePathWithParams(null); + + if (args.length >= 1 && "CRL".equalsIgnoreCase(args[0])) { + pathValidator.enableCRLCheck(); + } else { + // OCSP check by default + pathValidator.enableOCSPCheck(); + } + + new SectigoCSRootCA_R46().runTest(pathValidator); + new SectigoCSRootCA_E46().runTest(pathValidator); + } +} + +class SectigoCSRootCA_R46 { + + // Owner: CN=Sectigo Public Code Signing CA R36, O=Sectigo Limited, C=GB + // Issuer: CN=Sectigo Public Code Signing Root R46, O=Sectigo Limited, C=GB + // Serial number: 621d6d0c52019e3b9079152089211c0a + // Valid from: Sun Mar 21 17:00:00 PDT 2021 until: Fri Mar 21 16:59:59 + // PDT 2036 + private static final String INT = "-----BEGIN CERTIFICATE-----\n" + + "MIIGGjCCBAKgAwIBAgIQYh1tDFIBnjuQeRUgiSEcCjANBgkqhkiG9w0BAQwFADBW\n" + + "MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMS0wKwYDVQQD\n" + + "EyRTZWN0aWdvIFB1YmxpYyBDb2RlIFNpZ25pbmcgUm9vdCBSNDYwHhcNMjEwMzIy\n" + + "MDAwMDAwWhcNMzYwMzIxMjM1OTU5WjBUMQswCQYDVQQGEwJHQjEYMBYGA1UEChMP\n" + + "U2VjdGlnbyBMaW1pdGVkMSswKQYDVQQDEyJTZWN0aWdvIFB1YmxpYyBDb2RlIFNp\n" + + "Z25pbmcgQ0EgUjM2MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAmyud\n" + + "U/o1P45gBkNqwM/1f/bIU1MYyM7TbH78WAeVF3llMwsRHgBGRmxDeEDIArCS2VCo\n" + + "Vk4Y/8j6stIkmYV5Gej4NgNjVQ4BYoDjGMwdjioXan1hlaGFt4Wk9vT0k2oWJMJj\n" + + "L9G//N523hAm4jF4UjrW2pvv9+hdPX8tbbAfI3v0VdJiJPFy/7XwiunD7mBxNtec\n" + + "M6ytIdUlh08T2z7mJEXZD9OWcJkZk5wDuf2q52PN43jc4T9OkoXZ0arWZVeffvMr\n" + + "/iiIROSCzKoDmWABDRzV/UiQ5vqsaeFaqQdzFf4ed8peNWh1OaZXnYvZQgWx/SXi\n" + + "JDRSAolRzZEZquE6cbcH747FHncs/Kzcn0Ccv2jrOW+LPmnOyB+tAfiWu01TPhCr\n" + + "9VrkxsHC5qFNxaThTG5j4/Kc+ODD2dX/fmBECELcvzUHf9shoFvrn35XGf2RPaNT\n" + + "O2uSZ6n9otv7jElspkfK9qEATHZcodp+R4q2OIypxR//YEb3fkDn3UayWW9bAgMB\n" + + "AAGjggFkMIIBYDAfBgNVHSMEGDAWgBQy65Ka/zWWSC8oQEJwIDaRXBeF5jAdBgNV\n" + + "HQ4EFgQUDyrLIIcouOxvSK4rVKYpqhekzQwwDgYDVR0PAQH/BAQDAgGGMBIGA1Ud\n" + + "EwEB/wQIMAYBAf8CAQAwEwYDVR0lBAwwCgYIKwYBBQUHAwMwGwYDVR0gBBQwEjAG\n" + + "BgRVHSAAMAgGBmeBDAEEATBLBgNVHR8ERDBCMECgPqA8hjpodHRwOi8vY3JsLnNl\n" + + "Y3RpZ28uY29tL1NlY3RpZ29QdWJsaWNDb2RlU2lnbmluZ1Jvb3RSNDYuY3JsMHsG\n" + + "CCsGAQUFBwEBBG8wbTBGBggrBgEFBQcwAoY6aHR0cDovL2NydC5zZWN0aWdvLmNv\n" + + "bS9TZWN0aWdvUHVibGljQ29kZVNpZ25pbmdSb290UjQ2LnA3YzAjBggrBgEFBQcw\n" + + "AYYXaHR0cDovL29jc3Auc2VjdGlnby5jb20wDQYJKoZIhvcNAQEMBQADggIBAAb/\n" + + "guF3YzZue6EVIJsT/wT+mHVEYcNWlXHRkT+FoetAQLHI1uBy/YXKZDk8+Y1LoNqH\n" + + "rp22AKMGxQtgCivnDHFyAQ9GXTmlk7MjcgQbDCx6mn7yIawsppWkvfPkKaAQsiqa\n" + + "T9DnMWBHVNIabGqgQSGTrQWo43MOfsPynhbz2Hyxf5XWKZpRvr3dMapandPfYgoZ\n" + + "8iDL2OR3sYztgJrbG6VZ9DoTXFm1g0Rf97Aaen1l4c+w3DC+IkwFkvjFV3jS49ZS\n" + + "c4lShKK6BrPTJYs4NG1DGzmpToTnwoqZ8fAmi2XlZnuchC4NPSZaPATHvNIzt+z1\n" + + "PHo35D/f7j2pO1S8BCysQDHCbM5Mnomnq5aYcKCsdbh0czchOm8bkinLrYrKpii+\n" + + "Tk7pwL7TjRKLXkomm5D1Umds++pip8wH2cQpf93at3VDcOK4N7EwoIJB0kak6pSz\n" + + "Eu4I64U6gZs7tS/dGNSljf2OSSnRr7KWzq03zl8l75jy+hOds9TWSenLbjBQUGR9\n" + + "6cFr6lEUfAIEHVC1L68Y1GGxx4/eRI82ut83axHMViw1+sVpbPxg51Tbnio1lB93\n" + + "079WPFnYaOvfGAA0e0zcfF/M9gXr+korwQTh2Prqooq2bYNMvUoUKD85gnJ+t0sm\n" + + "rWrb8dee2CvYZXD5laGtaAxOfy/VKNmwuWuAh9kc\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=Sectigo Limited, O=Sectigo Limited, ST=West Yorkshire, C=GB + // Issuer: CN=Sectigo Public Code Signing CA R36, O=Sectigo Limited, C=GB + // Serial number: c1de046377578f1605414f3fa91bf5f6 + // Valid from: Wed Jun 04 17:00:00 PDT 2025 until: Fri Jun 05 16:59:59 + // PDT 2026 + private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + + "MIIGRDCCBKygAwIBAgIRAMHeBGN3V48WBUFPP6kb9fYwDQYJKoZIhvcNAQEMBQAw\n" + + "VDELMAkGA1UEBhMCR0IxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDErMCkGA1UE\n" + + "AxMiU2VjdGlnbyBQdWJsaWMgQ29kZSBTaWduaW5nIENBIFIzNjAeFw0yNTA2MDUw\n" + + "MDAwMDBaFw0yNjA2MDUyMzU5NTlaMFoxCzAJBgNVBAYTAkdCMRcwFQYDVQQIDA5X\n" + + "ZXN0IFlvcmtzaGlyZTEYMBYGA1UECgwPU2VjdGlnbyBMaW1pdGVkMRgwFgYDVQQD\n" + + "DA9TZWN0aWdvIExpbWl0ZWQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC\n" + + "AQDCYjakgsoYkqVpENW0MuN5hBZDdIM60WJgBXU7zTAXORntSu/Grn/SQywwTg4o\n" + + "ltRcKuCp0Cd5zLAIjtgpVDDACWHgxKUtxerjjBZeGp0+viR+biLL0mVNPXgZZ5bQ\n" + + "AnDYVKJaGnPsXQD8l+Bn/R2c4cw7mXjBYp2KrTuqOBkPzk4LmdgpKXjxiw1yYb+n\n" + + "WKZ+3BMLIU6/k+LB9+WB6Odrl4Lff1jB4C6XhQELGjZAbpkFB2+Qr0ajIA3ZFXqU\n" + + "IMh0j5oD5juuXxryOvCgSBkEwxPHnlXxZBNd3DmrZ9NGClBIGE2f9FOjzo5Rl7lV\n" + + "KlzFdFmcH8LaLtWjniF+iT+YZw3Ld1O9VMK7RaHePsS4JYfbjeapoCEgudecmIz4\n" + + "5Q2tTjCdR5s/SxiVbynfEw+cAGeiv4sRXNSg0uhZ2eGMHh6mPley2pUoRMR8Qx1U\n" + + "0Uzg2NtPsHAo0DIH3jKEWU2zP5UPwCfqKYGaZLNLeGh07NZHBCp3TGp9kPVen5Ib\n" + + "tnJssu+pab7fixvbpDM4/r9MkKU6C1IsE6lffyON0PA6LaywwecYTJGpieXqoz03\n" + + "5UmQXvAzkb9omIAcQ6yWMZNrqwwG9XRKQEhvG3v7sbFkck1KZOz4r/KHkLx9sIxm\n" + + "vngdD/qLFebxPIvPT0GKnvSzuGcdQXVTdkZBBBrunv+XpQIDAQABo4IBiTCCAYUw\n" + + "HwYDVR0jBBgwFoAUDyrLIIcouOxvSK4rVKYpqhekzQwwHQYDVR0OBBYEFGMpbbJO\n" + + "xiuD6t+HEyA3hjp4devXMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMBMG\n" + + "A1UdJQQMMAoGCCsGAQUFBwMDMEoGA1UdIARDMEEwNQYMKwYBBAGyMQECAQMCMCUw\n" + + "IwYIKwYBBQUHAgEWF2h0dHBzOi8vc2VjdGlnby5jb20vQ1BTMAgGBmeBDAEEATBJ\n" + + "BgNVHR8EQjBAMD6gPKA6hjhodHRwOi8vY3JsLnNlY3RpZ28uY29tL1NlY3RpZ29Q\n" + + "dWJsaWNDb2RlU2lnbmluZ0NBUjM2LmNybDB5BggrBgEFBQcBAQRtMGswRAYIKwYB\n" + + "BQUHMAKGOGh0dHA6Ly9jcnQuc2VjdGlnby5jb20vU2VjdGlnb1B1YmxpY0NvZGVT\n" + + "aWduaW5nQ0FSMzYuY3J0MCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5zZWN0aWdv\n" + + "LmNvbTANBgkqhkiG9w0BAQwFAAOCAYEAP2OCzJ+0hrg4XK3w+Ypoe0G5hKfzZ9RH\n" + + "nDcgY8BjgWYVOlN9ad2bU70RfgkZzylkaSt02KHOpkXmYpgfjZsovmyUchvlZ4fU\n" + + "RmivZleuO3G/ZvDFX373S40QFDd+lC1LYYUolRVz7/ZU2Vzql4FxsM1psRaW17xj\n" + + "jf9qaAvDlOH45eEEkfRUbIDdn1UYqDxdCN+90jtD1vRWkYINvE1T6mq3rHpEVoTS\n" + + "dIOgmcSL3MAKMB0LxWUPfoVdhnoUuoIxIAcV1SuR6zej4wHjClEaR8ReT/C23Jr3\n" + + "hQ4VDbfGu3gvlZG8/+lNmT+t4WaNPECxbFP0BgbD70FP594mSVH3fgptYiiRN7ez\n" + + "iUfOSBeCZpSMm7Z5P0KkxkagyFIR3vzgvqbJS/iaomvd9ZIkd9AwMEhugJpITeZj\n" + + "lKSXs+2q2UHQdLTPGVoOjmqyPhDGKAeVVF+jLIUWwtAaAoJm6ooXSp8sAeLA+e+K\n" + + "6RUFETVxhCefCjkbWq64OYLXriDb0l+W\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=Sectigo Limited, O=Sectigo Limited, ST=West Yorkshire, C=GB + // Issuer: CN=Sectigo Public Code Signing CA R36, O=Sectigo Limited, C=GB + // Serial number: 5ca6fb60da04db99dedbbc0c37131ec + // Valid from: Wed Jun 04 17:00:00 PDT 2025 until: Sun Jun 04 16:59:59 + // PDT 2028 + private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + + "MIIGQzCCBKugAwIBAgIQBcpvtg2gTbmd7bvAw3Ex7DANBgkqhkiG9w0BAQwFADBU\n" + + "MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMSswKQYDVQQD\n" + + "EyJTZWN0aWdvIFB1YmxpYyBDb2RlIFNpZ25pbmcgQ0EgUjM2MB4XDTI1MDYwNTAw\n" + + "MDAwMFoXDTI4MDYwNDIzNTk1OVowWjELMAkGA1UEBhMCR0IxFzAVBgNVBAgMDldl\n" + + "c3QgWW9ya3NoaXJlMRgwFgYDVQQKDA9TZWN0aWdvIExpbWl0ZWQxGDAWBgNVBAMM\n" + + "D1NlY3RpZ28gTGltaXRlZDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB\n" + + "ALDjoFCMN16zlrcv/saieSYT7FXEhTVDPLNzGAbNdBEX09FoL5EIkiN3biVIbDki\n" + + "bIocCFpo/yTrjARG/zz82AjdWHyomdtDjL35CQmgiUX7V8tu64xUfUAgadqm+0PL\n" + + "by1LRddKE7chpdJu+EDEmeYDPqcRGM+u8suPgosFf6XfVNFy/FZJiD1c7q6JNZ8i\n" + + "5NrvTs0zA9HckKE3uvPO9rw56EyF3SfUz9+zHKHwSElv8nCYpREudUf4yCzPNisK\n" + + "MVovzeCo36nzJFEdWTnDOr4mtvfCEGvJOU3mgzpECK7QF+yFifr90SG4lvrwzkig\n" + + "wYQymukXmB2gxN1tGOvgLig3Q/b4vljBiEeRPEba/L8YQnaXpR/BnPze8yb2t39l\n" + + "bzmnghkWkGA0PAB2vrzpi7pq12fGOD0+ErtAzAl/TAD/UFWwXDQLWX9LXRRKi5E+\n" + + "ScTlqLl9U1q9HsWYfM6CvLbc32TByaQ8yBytvsSRB0C0blp7CtP5MAc8j9xJdwAs\n" + + "Mj2bvSOfA+NJ0Kdg/tqdHHU6hex2HnGzDiEhovm6u/oAfDp/i2bBKLgARglMfGaC\n" + + "hFWeHLL6GAyBezMv+AQNCDCTYDMlqAihVMRUAfYgoHcVCfvTSETTTGdRUDFzIdCA\n" + + "wNwSVfykpadsev43I2IF+F3aNgJYuXnpxSCLPngemcgxAgMBAAGjggGJMIIBhTAf\n" + + "BgNVHSMEGDAWgBQPKssghyi47G9IritUpimqF6TNDDAdBgNVHQ4EFgQUlff/C/GC\n" + + "faJ+Y7ua3hKsCsrW9y4wDgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwEwYD\n" + + "VR0lBAwwCgYIKwYBBQUHAwMwSgYDVR0gBEMwQTA1BgwrBgEEAbIxAQIBAwIwJTAj\n" + + "BggrBgEFBQcCARYXaHR0cHM6Ly9zZWN0aWdvLmNvbS9DUFMwCAYGZ4EMAQQBMEkG\n" + + "A1UdHwRCMEAwPqA8oDqGOGh0dHA6Ly9jcmwuc2VjdGlnby5jb20vU2VjdGlnb1B1\n" + + "YmxpY0NvZGVTaWduaW5nQ0FSMzYuY3JsMHkGCCsGAQUFBwEBBG0wazBEBggrBgEF\n" + + "BQcwAoY4aHR0cDovL2NydC5zZWN0aWdvLmNvbS9TZWN0aWdvUHVibGljQ29kZVNp\n" + + "Z25pbmdDQVIzNi5jcnQwIwYIKwYBBQUHMAGGF2h0dHA6Ly9vY3NwLnNlY3RpZ28u\n" + + "Y29tMA0GCSqGSIb3DQEBDAUAA4IBgQAfVq3mY7ggMcTJeWKKrGxs9RUiuAY0p4Xv\n" + + "CHNQViM/tHAn0t/nkPp+d2Ji3Zr6PefN+1F6zmsxsbZHse52JNHWYUwCb/Dx4Vw6\n" + + "3Wnc1zhXtZnvUTUfgrivuIsMjUG8yzTdEt/taMKEO0KqlKPsBPgFKveDVVaq9UZa\n" + + "FfxTWqgrnvkvP/Lag/YeKKj4cJG+a/MJZJm7kvyaBNKXVAamr/bumoxKDzpD67ds\n" + + "n9qwBi2Mv0rRXvZ2SHQXzsJ/zjNKWUhpPVrpypaER7EUxjNuSgC4L8AmfvHiO67v\n" + + "9EVIEud+beP3FtCXl/cSHhVeDxiC0KBXXBl9zLBaYvCH+8iABnZLStLgBDtfdkfk\n" + + "TZEAGbrNOXJDMnKRxr8y377Zq+KHwfiTnyizACHyMMTi+CCwg1ZFGcLOHa5shByc\n" + + "Ln9lYysM1/5vrEjt3ZUw11+pDqbPCGS++xgAwcftKfJ0TZrW/g6NZ9URg+11H9ad\n" + + "WalBv2VkhJAFJam9P2Y+pi9luk85sGo=\n" + + "-----END CERTIFICATE-----"; + + public void runTest(ValidatePathWithParams pathValidator) throws Exception { + // Validate valid + pathValidator.validate(new String[]{VALID, INT}, + ValidatePathWithParams.Status.GOOD, null, System.out); + + // Validate Revoked + pathValidator.validate(new String[]{REVOKED, INT}, + ValidatePathWithParams.Status.REVOKED, + "Thu Jun 05 10:27:45 PDT 2025", System.out); + } +} + +class SectigoCSRootCA_E46 { + + // Owner: CN=Sectigo Public Code Signing CA EV E36, O=Sectigo Limited, C=GB + // Issuer: CN=Sectigo Public Code Signing Root E46, O=Sectigo Limited, C=GB + // Serial number: 3774434f9eb40e221f9236ca1f2f2717 + // Valid from: Sun Mar 21 17:00:00 PDT 2021 until: Fri Mar 21 16:59:59 + // PDT 2036 + private static final String INT_VALID = "-----BEGIN CERTIFICATE-----\n" + + "MIIDMDCCAragAwIBAgIQN3RDT560DiIfkjbKHy8nFzAKBggqhkjOPQQDAzBWMQsw\n" + + "CQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMS0wKwYDVQQDEyRT\n" + + "ZWN0aWdvIFB1YmxpYyBDb2RlIFNpZ25pbmcgUm9vdCBFNDYwHhcNMjEwMzIyMDAw\n" + + "MDAwWhcNMzYwMzIxMjM1OTU5WjBXMQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2Vj\n" + + "dGlnbyBMaW1pdGVkMS4wLAYDVQQDEyVTZWN0aWdvIFB1YmxpYyBDb2RlIFNpZ25p\n" + + "bmcgQ0EgRVYgRTM2MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE3mMV9nNViYoH\n" + + "4aSrPwFjpbbeXHw2pMbqezwDGb45uEZQr3qI9Hgt0k4R26o5upfXzJt03F8efu0r\n" + + "RNEs4yDDz6OCAWMwggFfMB8GA1UdIwQYMBaAFM99LKCQepgd3bZehcLg2hVx0uVe\n" + + "MB0GA1UdDgQWBBQadKQ417m2DrNb+txerj+28HM9iDAOBgNVHQ8BAf8EBAMCAYYw\n" + + "EgYDVR0TAQH/BAgwBgEB/wIBADATBgNVHSUEDDAKBggrBgEFBQcDAzAaBgNVHSAE\n" + + "EzARMAYGBFUdIAAwBwYFZ4EMAQMwSwYDVR0fBEQwQjBAoD6gPIY6aHR0cDovL2Ny\n" + + "bC5zZWN0aWdvLmNvbS9TZWN0aWdvUHVibGljQ29kZVNpZ25pbmdSb290RTQ2LmNy\n" + + "bDB7BggrBgEFBQcBAQRvMG0wRgYIKwYBBQUHMAKGOmh0dHA6Ly9jcnQuc2VjdGln\n" + + "by5jb20vU2VjdGlnb1B1YmxpY0NvZGVTaWduaW5nUm9vdEU0Ni5wN2MwIwYIKwYB\n" + + "BQUHMAGGF2h0dHA6Ly9vY3NwLnNlY3RpZ28uY29tMAoGCCqGSM49BAMDA2gAMGUC\n" + + "MQCger3L4CYx2W7HyHzvLaAnNee9QVqOwOrBYZyyqXERLtZg1DscsdoYZ2gszEW3\n" + + "zaUCMAaLtcwdoV35ADpru29wChS7kFgXt599Ex27wmL++uJCJth6xYr3nyF2b2YJ\n" + + "DAatOw==\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=Sectigo Public Code Signing CA E36, O=Sectigo Limited, C=GB + // Issuer: CN=Sectigo Public Code Signing Root E46, O=Sectigo Limited, C=GB + // Serial number: 3602617636e7034b9cc1fc5ffeac2d54 + // Valid from: Sun Mar 21 17:00:00 PDT 2021 until: Fri Mar 21 16:59:59 + // PDT 2036 + private static final String INT_REVOKED = "-----BEGIN CERTIFICATE-----\n" + + "MIIDLjCCArSgAwIBAgIQNgJhdjbnA0ucwfxf/qwtVDAKBggqhkjOPQQDAzBWMQsw\n" + + "CQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMS0wKwYDVQQDEyRT\n" + + "ZWN0aWdvIFB1YmxpYyBDb2RlIFNpZ25pbmcgUm9vdCBFNDYwHhcNMjEwMzIyMDAw\n" + + "MDAwWhcNMzYwMzIxMjM1OTU5WjBUMQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2Vj\n" + + "dGlnbyBMaW1pdGVkMSswKQYDVQQDEyJTZWN0aWdvIFB1YmxpYyBDb2RlIFNpZ25p\n" + + "bmcgQ0EgRTM2MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAElDe1m6jawDhrwMxJ\n" + + "yFPhKYf8EGu+lBw3bF5CzmfaH1I7Zi+WAmkeEwS3tiNxzPh8GbBBLtdaRuqGuyWc\n" + + "W6ERmaOCAWQwggFgMB8GA1UdIwQYMBaAFM99LKCQepgd3bZehcLg2hVx0uVeMB0G\n" + + "A1UdDgQWBBQlDZtt2Bh3t4rDOFFW5cfytf+DajAOBgNVHQ8BAf8EBAMCAYYwEgYD\n" + + "VR0TAQH/BAgwBgEB/wIBADATBgNVHSUEDDAKBggrBgEFBQcDAzAbBgNVHSAEFDAS\n" + + "MAYGBFUdIAAwCAYGZ4EMAQQBMEsGA1UdHwREMEIwQKA+oDyGOmh0dHA6Ly9jcmwu\n" + + "c2VjdGlnby5jb20vU2VjdGlnb1B1YmxpY0NvZGVTaWduaW5nUm9vdEU0Ni5jcmww\n" + + "ewYIKwYBBQUHAQEEbzBtMEYGCCsGAQUFBzAChjpodHRwOi8vY3J0LnNlY3RpZ28u\n" + + "Y29tL1NlY3RpZ29QdWJsaWNDb2RlU2lnbmluZ1Jvb3RFNDYucDdjMCMGCCsGAQUF\n" + + "BzABhhdodHRwOi8vb2NzcC5zZWN0aWdvLmNvbTAKBggqhkjOPQQDAwNoADBlAjBM\n" + + "ykNTSVvegC1m17yIi87qgx6QIGbw1Mw2bQ4gtOWBVb/C8ALByC1YK7yQJNLJFTkC\n" + + "MQCNBv3fe1eLrGELS5KQD0cEFbXGlzQ5r1mnOHePMqlK5d+rmMxff58/t6bo3QEb\n" + + "8SQ=\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=Sectigo Limited, O=Sectigo Limited, ST=West Yorkshire, C=GB, + // OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.3=GB, + // SERIALNUMBER=04058690 + // Issuer: CN=Sectigo Public Code Signing CA EV E36, O=Sectigo Limited, C=GB + // Serial number: fa2aa131f36b337717ac73f606a6ec49 + // Valid from: Tue Feb 13 16:00:00 PST 2024 until: Sat Feb 13 15:59:59 + // PST 2027 + private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + + "MIIDrjCCA1SgAwIBAgIRAPoqoTHzazN3F6xz9gam7EkwCgYIKoZIzj0EAwIwVzEL\n" + + "MAkGA1UEBhMCR0IxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDEuMCwGA1UEAxMl\n" + + "U2VjdGlnbyBQdWJsaWMgQ29kZSBTaWduaW5nIENBIEVWIEUzNjAeFw0yNDAyMTQw\n" + + "MDAwMDBaFw0yNzAyMTMyMzU5NTlaMIGhMREwDwYDVQQFEwgwNDA1ODY5MDETMBEG\n" + + "CysGAQQBgjc8AgEDEwJHQjEdMBsGA1UEDxMUUHJpdmF0ZSBPcmdhbml6YXRpb24x\n" + + "CzAJBgNVBAYTAkdCMRcwFQYDVQQIDA5XZXN0IFlvcmtzaGlyZTEYMBYGA1UECgwP\n" + + "U2VjdGlnbyBMaW1pdGVkMRgwFgYDVQQDDA9TZWN0aWdvIExpbWl0ZWQwWTATBgcq\n" + + "hkjOPQIBBggqhkjOPQMBBwNCAASwXGEU01WkW/hWNYza08ZT7i0ZeZ9M1s93JYEB\n" + + "rZ/f1Ho1YzxtToqgIK2o+32afablPFYWlE6wGyuL/TYggBpKo4IBtDCCAbAwHwYD\n" + + "VR0jBBgwFoAUGnSkONe5tg6zW/rcXq4/tvBzPYgwHQYDVR0OBBYEFHEcsJgcYuDO\n" + + "dv1raL6h83a6j9C/MA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMBMGA1Ud\n" + + "JQQMMAoGCCsGAQUFBwMDMEkGA1UdIARCMEAwNQYMKwYBBAGyMQECAQYBMCUwIwYI\n" + + "KwYBBQUHAgEWF2h0dHBzOi8vc2VjdGlnby5jb20vQ1BTMAcGBWeBDAEDMEsGA1Ud\n" + + "HwREMEIwQKA+oDyGOmh0dHA6Ly9jcmwuc2VjdGlnby5jb20vU2VjdGlnb1B1Ymxp\n" + + "Y0NvZGVTaWduaW5nQ0FFVkUzNi5jcmwwewYIKwYBBQUHAQEEbzBtMEYGCCsGAQUF\n" + + "BzAChjpodHRwOi8vY3J0LnNlY3RpZ28uY29tL1NlY3RpZ29QdWJsaWNDb2RlU2ln\n" + + "bmluZ0NBRVZFMzYuY3J0MCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5zZWN0aWdv\n" + + "LmNvbTAmBgNVHREEHzAdoBsGCCsGAQUFBwgDoA8wDQwLR0ItMDQwNTg2OTAwCgYI\n" + + "KoZIzj0EAwIDSAAwRQIgQVp7IIkEZNmC7GfmT1MSEhDebIjjzd75ZVEEbPP/4ocC\n" + + "IQDSyfPDKNMbKNOKrweDLwSE2GZV6nDWbiLz6ZmSZHob8w==\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=Sectigo Limited, O=Sectigo Limited, ST=West Yorkshire, C=GB + // Issuer: CN=Sectigo Public Code Signing CA E36, O=Sectigo Limited, C=GB + // Serial number: a1f601514271f24ca0a31c0d7b856705 + // Valid from: Wed Jun 04 17:00:00 PDT 2025 until: Sun Jun 04 16:59:59 + // PDT 2028 + private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + + "MIIDOTCCAt6gAwIBAgIRAKH2AVFCcfJMoKMcDXuFZwUwCgYIKoZIzj0EAwIwVDEL\n" + + "MAkGA1UEBhMCR0IxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDErMCkGA1UEAxMi\n" + + "U2VjdGlnbyBQdWJsaWMgQ29kZSBTaWduaW5nIENBIEUzNjAeFw0yNTA2MDUwMDAw\n" + + "MDBaFw0yODA2MDQyMzU5NTlaMFoxCzAJBgNVBAYTAkdCMRcwFQYDVQQIDA5XZXN0\n" + + "IFlvcmtzaGlyZTEYMBYGA1UECgwPU2VjdGlnbyBMaW1pdGVkMRgwFgYDVQQDDA9T\n" + + "ZWN0aWdvIExpbWl0ZWQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASwXGEU01Wk\n" + + "W/hWNYza08ZT7i0ZeZ9M1s93JYEBrZ/f1Ho1YzxtToqgIK2o+32afablPFYWlE6w\n" + + "GyuL/TYggBpKo4IBiTCCAYUwHwYDVR0jBBgwFoAUJQ2bbdgYd7eKwzhRVuXH8rX/\n" + + "g2owHQYDVR0OBBYEFHEcsJgcYuDOdv1raL6h83a6j9C/MA4GA1UdDwEB/wQEAwIH\n" + + "gDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMEoGA1UdIARDMEEw\n" + + "NQYMKwYBBAGyMQECAQMCMCUwIwYIKwYBBQUHAgEWF2h0dHBzOi8vc2VjdGlnby5j\n" + + "b20vQ1BTMAgGBmeBDAEEATBJBgNVHR8EQjBAMD6gPKA6hjhodHRwOi8vY3JsLnNl\n" + + "Y3RpZ28uY29tL1NlY3RpZ29QdWJsaWNDb2RlU2lnbmluZ0NBRTM2LmNybDB5Bggr\n" + + "BgEFBQcBAQRtMGswRAYIKwYBBQUHMAKGOGh0dHA6Ly9jcnQuc2VjdGlnby5jb20v\n" + + "U2VjdGlnb1B1YmxpY0NvZGVTaWduaW5nQ0FFMzYuY3J0MCMGCCsGAQUFBzABhhdo\n" + + "dHRwOi8vb2NzcC5zZWN0aWdvLmNvbTAKBggqhkjOPQQDAgNJADBGAiEAlEkiISLz\n" + + "PdJsFmVzJ2VZ8hnnVsOBXKbqISFQvIdguJoCIQCH4T0vwxn6uVkJpMvtxiMG/rYg\n" + + "jRFhfbxDcVee6likOw==\n" + + "-----END CERTIFICATE-----"; + + public void runTest(ValidatePathWithParams pathValidator) throws Exception { + // Validate valid + pathValidator.validate(new String[]{VALID, INT_VALID}, + ValidatePathWithParams.Status.GOOD, null, System.out); + + // Validate Revoked + pathValidator.validate(new String[]{REVOKED, INT_REVOKED}, + ValidatePathWithParams.Status.REVOKED, + "Thu Jun 05 10:27:19 PDT 2025", System.out); + } +} diff --git a/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java b/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java index d176a93784d..86a612ac3ba 100644 --- a/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java +++ b/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java @@ -28,7 +28,7 @@ * 8223499 8225392 8232019 8234245 8233223 8225068 8225069 8243321 8243320 * 8243559 8225072 8258630 8259312 8256421 8225081 8225082 8225083 8245654 * 8305975 8304760 8307134 8295894 8314960 8317373 8317374 8318759 8319187 - * 8321408 8316138 8341057 8303770 8350498 + * 8321408 8316138 8341057 8303770 8350498 8359170 * @summary Check root CA entries in cacerts file */ import java.io.ByteArrayInputStream; @@ -47,12 +47,12 @@ public class VerifyCACerts { + File.separator + "security" + File.separator + "cacerts"; // The numbers of certs now. - private static final int COUNT = 109; + private static final int COUNT = 113; // SHA-256 of cacerts, can be generated with // shasum -a 256 cacerts | sed -e 's/../&:/g' | tr '[:lower:]' '[:upper:]' | cut -c1-95 private static final String CHECKSUM - = "BD:6B:AB:BB:17:87:0D:D5:8D:53:D3:63:A5:DD:70:57:0F:4E:D3:57:4F:E5:FB:05:41:1C:A9:6E:B0:BF:79:38"; + = "18:36:49:15:B6:71:85:FF:F1:8E:C0:10:BE:0A:41:52:5B:DC:F7:B3:1F:51:7A:45:7D:7A:14:10:3A:59:42:4C"; // Hex formatter to upper case with ":" delimiter private static final HexFormat HEX = HexFormat.ofDelimiter(":").withUpperCase(); @@ -279,6 +279,14 @@ public class VerifyCACerts { "C3:2F:FD:9F:46:F9:36:D1:6C:36:73:99:09:59:43:4B:9A:D6:0A:AF:BB:9E:7C:F3:36:54:F1:44:CC:1B:A1:43"); put("ssltlsrootrsa2022 [jdk]", "8F:AF:7D:2E:2C:B4:70:9B:B8:E0:B3:36:66:BF:75:A5:DD:45:B5:DE:48:0F:8E:A8:D4:BF:E6:BE:BC:17:F2:ED"); + put("sectigotlsrootr46 [jdk]", + "7B:B6:47:A6:2A:EE:AC:88:BF:25:7A:A5:22:D0:1F:FE:A3:95:E0:AB:45:C7:3F:93:F6:56:54:EC:38:F2:5A:06"); + put("sectigotlsroote46 [jdk]", + "C9:0F:26:F0:FB:1B:40:18:B2:22:27:51:9B:5C:A2:B5:3E:2C:A5:B3:BE:5C:F1:8E:FE:1B:EF:47:38:0C:53:83"); + put("sectigocodesignrootr46 [jdk]", + "7E:76:26:0A:E6:9A:55:D3:F0:60:B0:FD:18:B2:A8:C0:14:43:C8:7B:60:79:10:30:C9:FA:0B:05:85:10:1A:38"); + put("sectigocodesignroote46 [jdk]", + "8F:63:71:D8:CC:5A:A7:CA:14:96:67:A9:8B:54:96:39:89:51:E4:31:9F:7A:FB:CC:6A:66:0D:67:3E:43:8D:0B"); } }; diff --git a/test/jdk/sun/security/pkcs/pkcs8/PKCS8Test.java b/test/jdk/sun/security/pkcs/pkcs8/PKCS8Test.java index 49cca69971f..9bb5502ad9f 100644 --- a/test/jdk/sun/security/pkcs/pkcs8/PKCS8Test.java +++ b/test/jdk/sun/security/pkcs/pkcs8/PKCS8Test.java @@ -31,10 +31,13 @@ * java.base/sun.security.provider * java.base/sun.security.x509 * @run main PKCS8Test + * @run main/othervm -Dtest.provider.name=SunJCE PKCS8Test */ import java.math.BigInteger; import java.security.InvalidKeyException; +import java.security.Provider; +import java.security.Security; import java.util.Arrays; import java.util.HexFormat; @@ -45,6 +48,7 @@ import sun.security.provider.DSAPrivateKey; public class PKCS8Test { + static Provider provider; static final String FORMAT = "PKCS#8"; static final String EXPECTED_ALG_ID_CHRS = "DSA, \n" + "\tp: 02\n\tq: 03\n\tg: 04\n"; @@ -59,7 +63,7 @@ public class PKCS8Test { "0403020101"); // PrivateKey OCTET int x = 1 public static void main(String[] args) throws Exception { - + provider = Security.getProvider(System.getProperty("test.provider.name")); byte[] encodedKey = new DSAPrivateKey( BigInteger.valueOf(1), BigInteger.valueOf(2), @@ -73,7 +77,8 @@ public class PKCS8Test { .toString(encodedKey)); } - PKCS8Key decodedKey = (PKCS8Key)PKCS8Key.parseKey(encodedKey); + PKCS8Key decodedKey = provider == null ? (PKCS8Key)PKCS8Key.parseKey(encodedKey) : + (PKCS8Key)PKCS8Key.parseKey(encodedKey, provider); assert(ALGORITHM.equalsIgnoreCase(decodedKey.getAlgorithm())); assert(FORMAT.equalsIgnoreCase(decodedKey.getFormat())); @@ -126,7 +131,11 @@ public class PKCS8Test { original[1] = (byte) (length - 2); // the length field inside DER original[4] = (byte) newVersion; // the version inside DER try { - PKCS8Key.parseKey(original); + if (provider == null) { + PKCS8Key.parseKey(original); + } else { + PKCS8Key.parseKey(original, provider); + } } catch (InvalidKeyException e) { throw new RuntimeException(e); } diff --git a/test/langtools/tools/javac/T6358024.java b/test/langtools/tools/javac/T6358024.java index 86bc37afda9..7388ce55cef 100644 --- a/test/langtools/tools/javac/T6358024.java +++ b/test/langtools/tools/javac/T6358024.java @@ -87,7 +87,9 @@ public class T6358024 extends AbstractProcessor { Arrays.asList(f)); MyTaskListener tl = new MyTaskListener(); task.setTaskListener(tl); - task.call(); + if (!task.call()) { + throw new AssertionError("test failed due to a compilation error"); + } if (tl.started != expect) throw new AssertionError("Unexpected number of TaskListener events; " + "expected " + expect + ", found " + tl.started); diff --git a/test/langtools/tools/javac/T6358166.java b/test/langtools/tools/javac/T6358166.java index e1aa2e00bbf..d3d4b2ae162 100644 --- a/test/langtools/tools/javac/T6358166.java +++ b/test/langtools/tools/javac/T6358166.java @@ -75,7 +75,9 @@ public class T6358166 extends AbstractProcessor { JavacTool tool = JavacTool.create(); JavacTaskImpl task = (JavacTaskImpl) tool.getTask(null, fm, null, allArgs, null, List.of(f), context); - task.call(); + if (!task.call()) { + throw new AssertionError("test failed due to a compilation error"); + } JavaCompiler c = JavaCompiler.instance(context); if (c.errorCount() != 0) diff --git a/test/langtools/tools/javac/T6361619.java b/test/langtools/tools/javac/T6361619.java index 67450129e3e..1f299a8f4c3 100644 --- a/test/langtools/tools/javac/T6361619.java +++ b/test/langtools/tools/javac/T6361619.java @@ -50,7 +50,8 @@ public class T6361619 extends AbstractProcessor { final PrintWriter out = new PrintWriter(System.err, true); - Iterable flags = Arrays.asList("-processorpath", testClassDir, + Iterable flags = Arrays.asList("--add-exports", "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED", + "-processorpath", testClassDir, "-processor", self, "-d", "."); DiagnosticListener dl = new DiagnosticListener() { @@ -69,7 +70,9 @@ public class T6361619 extends AbstractProcessor { task.setTaskListener(tl); // should complete, without exceptions - task.call(); + if (!task.call()) { + throw new AssertionError("test failed due to a compilation error"); + } } } diff --git a/test/langtools/tools/javac/T6395974.java b/test/langtools/tools/javac/T6395974.java index e8d2b716735..623a9563695 100644 --- a/test/langtools/tools/javac/T6395974.java +++ b/test/langtools/tools/javac/T6395974.java @@ -63,7 +63,9 @@ public class T6395974 { MyTaskListener tl = new MyTaskListener(); task.setTaskListener(tl); - task.call(); + if (task.call()) { + throw new AssertionError("test compilation was expected to fail"); + } } } diff --git a/test/langtools/tools/javac/T6397286.java b/test/langtools/tools/javac/T6397286.java index 5153a61aa77..8e8ef882aa2 100644 --- a/test/langtools/tools/javac/T6397286.java +++ b/test/langtools/tools/javac/T6397286.java @@ -56,6 +56,7 @@ public class T6397286 { }); try { + // no need to check the result of JavacTask::call, reevaluate if the test is modified task.call(); throw new AssertionError("no exception thrown"); } catch (RuntimeException e) { diff --git a/test/langtools/tools/javac/T6458823/T6458823.java b/test/langtools/tools/javac/T6458823/T6458823.java index 91736229e5a..cd23066edc8 100644 --- a/test/langtools/tools/javac/T6458823/T6458823.java +++ b/test/langtools/tools/javac/T6458823/T6458823.java @@ -66,7 +66,9 @@ public class T6458823 { files.add(new File(T6458823.class.getResource("TestClass.java").toURI())); final CompilationTask task = compiler.getTask(null, fm, diagColl, options, null, fm.getJavaFileObjectsFromFiles(files)); - task.call(); + if (!task.call()) { + throw new AssertionError("test failed due to a compilation error"); + } int diagCount = 0; for (Diagnostic diag : diagColl.getDiagnostics()) { if (diag.getKind() != Diagnostic.Kind.WARNING) { diff --git a/test/langtools/tools/javac/TryWithResources/TwrAvoidNullCheck.java b/test/langtools/tools/javac/TryWithResources/TwrAvoidNullCheck.java index f095b92b571..045558374c7 100644 --- a/test/langtools/tools/javac/TryWithResources/TwrAvoidNullCheck.java +++ b/test/langtools/tools/javac/TryWithResources/TwrAvoidNullCheck.java @@ -76,7 +76,9 @@ public class TwrAvoidNullCheck { DumpLower.preRegister(ctx); Iterable files = Arrays.asList(new ToolBox.JavaSource(code)); JavacTask task = JavacTool.create().getTask(null, null, null, null, null, files, ctx); - task.call(); + if (!task.call()) { + throw new AssertionError("test failed due to a compilation error"); + } boolean hasNullCheck = ((DumpLower) DumpLower.instance(ctx)).hasNullCheck; diff --git a/test/langtools/tools/javac/TryWithResources/TwrSimpleClose.java b/test/langtools/tools/javac/TryWithResources/TwrSimpleClose.java index af3f4ea19ef..11691a43040 100644 --- a/test/langtools/tools/javac/TryWithResources/TwrSimpleClose.java +++ b/test/langtools/tools/javac/TryWithResources/TwrSimpleClose.java @@ -89,7 +89,9 @@ public class TwrSimpleClose { JFMImpl fm = new JFMImpl(sfm)) { Iterable files = Arrays.asList(new ToolBox.JavaSource(code)); JavacTask task = (JavacTask) compiler.getTask(null, fm, null, null, null, files); - task.call(); + if (!task.call()) { + throw new AssertionError("test failed due to a compilation error"); + } if (fm.classBytes.size() != 1) { throw new AssertionError(); diff --git a/test/langtools/tools/javac/api/6406133/T6406133.java b/test/langtools/tools/javac/api/6406133/T6406133.java index 70e2fbe5fe6..24ddba1e602 100644 --- a/test/langtools/tools/javac/api/6406133/T6406133.java +++ b/test/langtools/tools/javac/api/6406133/T6406133.java @@ -90,7 +90,9 @@ public class T6406133 extends ToolTester { task = tool.getTask(pw, fm, listener, null, null, compilationUnits); task.setProcessors(Arrays.asList(processor)); task.setLocale(locale); //6443132 - task.call(); + if (task.call()) { + throw new AssertionError("test compilation was expected to fail"); + } if (!processor.locale.equals(locale)) throw new AssertionError("Error in diagnostic localization during annotation processing"); String res = useListener ? listener.result : pw.toString(); diff --git a/test/langtools/tools/javac/api/6410643/T6410643.java b/test/langtools/tools/javac/api/6410643/T6410643.java index a551f802d62..d8f5c798249 100644 --- a/test/langtools/tools/javac/api/6410643/T6410643.java +++ b/test/langtools/tools/javac/api/6410643/T6410643.java @@ -53,6 +53,7 @@ public class T6410643 extends ToolTester { void test(String... args) { task = tool.getTask(null, null, null, null, null, null); try { + // no need to check the result of JavacTask::call, reevaluate if the test is modified task.call(); throw new AssertionError("Error expected"); } catch (IllegalStateException e) { diff --git a/test/langtools/tools/javac/api/6412656/T6412656.java b/test/langtools/tools/javac/api/6412656/T6412656.java index b7976e036fd..cfea162ae98 100644 --- a/test/langtools/tools/javac/api/6412656/T6412656.java +++ b/test/langtools/tools/javac/api/6412656/T6412656.java @@ -47,7 +47,9 @@ public class T6412656 extends ToolTester { task = tool.getTask(null, fm, null, null, Collections.singleton(T6412656.class.getName()), null); task.setProcessors(Collections.singleton(new MyProc(this))); - task.call(); + if (!task.call()) { + throw new AssertionError("test failed due to a compilation error"); + } if (count == 0) throw new AssertionError("Annotation processor not run"); System.out.println("OK"); diff --git a/test/langtools/tools/javac/api/6423003/T6423003.java b/test/langtools/tools/javac/api/6423003/T6423003.java index 893f2dd6344..58d055e9685 100644 --- a/test/langtools/tools/javac/api/6423003/T6423003.java +++ b/test/langtools/tools/javac/api/6423003/T6423003.java @@ -41,11 +41,12 @@ public class T6423003 extends ToolTester { void test(String... args) { task = tool.getTask(null, fm, null, Arrays.asList("-Xlint:all"), null, null); try { + // no need to check the result of JavacTask::call, reevaluate if the test is modified task.call(); + throw new AssertionError("Expected IllegalStateException not thrown"); } catch (IllegalStateException ex) { return; } - throw new AssertionError("Expected IllegalStateException not thrown"); } public static void main(String... args) throws IOException { try (T6423003 t = new T6423003()) { diff --git a/test/langtools/tools/javac/api/6731573/T6731573.java b/test/langtools/tools/javac/api/6731573/T6731573.java index 0d7ceb8fd2f..892b8e63ffb 100644 --- a/test/langtools/tools/javac/api/6731573/T6731573.java +++ b/test/langtools/tools/javac/api/6731573/T6731573.java @@ -93,7 +93,9 @@ public class T6731573 extends ToolTester { if (sourceLine.optValue != null) options.add(sourceLine.optValue); task = tool.getTask(pw, fm, null, options, null, compilationUnits); - task.call(); + if (task.call()) { + throw new AssertionError("test compilation was expected to fail"); + } checkErrorLine(pw.toString(), diagType.shouldDisplaySource(sourceLine), options); diff --git a/test/langtools/tools/javac/api/7086261/T7086261.java b/test/langtools/tools/javac/api/7086261/T7086261.java index 1bc2d1a2dc8..391e71c94a7 100644 --- a/test/langtools/tools/javac/api/7086261/T7086261.java +++ b/test/langtools/tools/javac/api/7086261/T7086261.java @@ -71,7 +71,9 @@ public class T7086261 { try (JavaFileManager jfm = javac.getStandardFileManager(null, null, null)) { JavaCompiler.CompilationTask task = javac.getTask(null, jfm, new DiagnosticChecker(), null, null, Arrays.asList(new ErroneousSource())); - task.call(); + if (task.call()) { + throw new AssertionError("test compilation was expected to fail"); + } } } diff --git a/test/langtools/tools/javac/api/8007344/Test.java b/test/langtools/tools/javac/api/8007344/Test.java index c99b77a101f..d230fb6086b 100644 --- a/test/langtools/tools/javac/api/8007344/Test.java +++ b/test/langtools/tools/javac/api/8007344/Test.java @@ -38,6 +38,7 @@ import java.io.File; import java.io.PrintWriter; import java.util.Arrays; +import java.util.List; import java.util.Set; import javax.annotation.processing.RoundEnvironment; @@ -75,6 +76,12 @@ public class Test { } } + static final List OPTIONS = List.of( + "--add-exports", "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED", + "--add-exports", "jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED", + "--add-exports", "jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED", + "--add-exports", "jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED"); + PrintWriter out; int errors; @@ -102,10 +109,12 @@ public class Test { Iterable files, PrintWriter out, int expectedDocComments) { out.println("Test annotation processor"); - JavacTask task = javac.getTask(out, fm, null, null, null, files); + JavacTask task = javac.getTask(out, fm, null, OPTIONS, null, files); AnnoProc ap = new AnnoProc(DocTrees.instance(task)); task.setProcessors(Arrays.asList(ap)); - task.call(); + if (!task.call()) { + throw new AssertionError("test failed due to a compilation error"); + } ap.checker.checkDocComments(expectedDocComments); } @@ -113,10 +122,12 @@ public class Test { Iterable files, PrintWriter out, int expectedDocComments) { out.println("Test task listener"); - JavacTask task = javac.getTask(out, fm, null, null, null, files); + JavacTask task = javac.getTask(out, fm, null, OPTIONS, null, files); TaskListnr tl = new TaskListnr(DocTrees.instance(task)); task.addTaskListener(tl); - task.call(); + if (!task.call()) { + throw new AssertionError("test failed due to a compilation error"); + } tl.checker.checkDocComments(expectedDocComments); } diff --git a/test/langtools/tools/javac/api/DiagSpans.java b/test/langtools/tools/javac/api/DiagSpans.java index e4cdc6a5f07..527fe1aad62 100644 --- a/test/langtools/tools/javac/api/DiagSpans.java +++ b/test/langtools/tools/javac/api/DiagSpans.java @@ -72,7 +72,8 @@ public class DiagSpans extends TestRunner { } """, '/', - '^'); + '^', + false); } @Test @@ -87,7 +88,8 @@ public class DiagSpans extends TestRunner { } """, '/', - '^'); + '^', + false); } @Test @@ -102,7 +104,8 @@ public class DiagSpans extends TestRunner { } """, '/', - '^'); + '^', + false); } @Test @@ -118,7 +121,8 @@ public class DiagSpans extends TestRunner { } """, '/', - '^'); + '^', + false); } @Test @@ -134,7 +138,8 @@ public class DiagSpans extends TestRunner { } """, '/', - '^'); + '^', + false); } @Test @@ -158,7 +163,8 @@ public class DiagSpans extends TestRunner { class Sub2 extends Base2 {} """, '/', - '^'); + '^', + true); } @Test @@ -175,7 +181,8 @@ public class DiagSpans extends TestRunner { class Sub1 extends Base1 {} """, '/', - '^'); + '^', + false); } @Test @@ -192,10 +199,11 @@ public class DiagSpans extends TestRunner { class Sub1 extends Base1 {} """, '/', - '^'); + '^', + false); } - private void runDiagSpanTest(String code, char spanMarker, char prefMarker) throws Exception { + private void runDiagSpanTest(String code, char spanMarker, char prefMarker, boolean succCompilationExpected) throws Exception { var realCode = new StringBuilder(); var expectedError = new ArrayList(); int startPos = -1; @@ -238,7 +246,9 @@ public class DiagSpans extends TestRunner { }; var sourceFiles = List.of(new JFOImpl(realCode.toString())); var task = compiler.getTask(null, null, dl, null, null, sourceFiles); - task.call(); + if (task.call() != succCompilationExpected) { + throw new AssertionError("unexpected compilation result"); + } if (!Objects.equals(expectedError, actualErrors)) { throw new AssertionError("Expected error spans not found, expected: " + expectedError + ", actual: " + actualErrors); diff --git a/test/langtools/tools/javac/api/T6357331.java b/test/langtools/tools/javac/api/T6357331.java index 5253ebededd..0bc4ff98a53 100644 --- a/test/langtools/tools/javac/api/T6357331.java +++ b/test/langtools/tools/javac/api/T6357331.java @@ -53,7 +53,9 @@ public class T6357331 public void finished(TaskEvent e) { } }); - task.call(); + if (!task.call()) { + throw new AssertionError("test failed due to a compilation error"); + } // now the compilation is over, we expect IllegalStateException (not NPE) try { diff --git a/test/langtools/tools/javac/api/TestTreePath.java b/test/langtools/tools/javac/api/TestTreePath.java index b3887619947..7a016f42545 100644 --- a/test/langtools/tools/javac/api/TestTreePath.java +++ b/test/langtools/tools/javac/api/TestTreePath.java @@ -116,7 +116,9 @@ public class TestTreePath extends AbstractProcessor { null, null, null, Arrays.asList("-processor", this.getClass().getName()), null, tests); - task.call(); + if (!task.call()) { + throw new AssertionError("test failed due to a compilation error"); + } } } diff --git a/test/langtools/tools/javac/api/taskListeners/EventsBalancedTest.java b/test/langtools/tools/javac/api/taskListeners/EventsBalancedTest.java index bd01d192b6e..759ec8d66ac 100644 --- a/test/langtools/tools/javac/api/taskListeners/EventsBalancedTest.java +++ b/test/langtools/tools/javac/api/taskListeners/EventsBalancedTest.java @@ -79,7 +79,9 @@ public class EventsBalancedTest { task.setTaskListener(listener); - task.call(); + if (!task.call()) { + throw new AssertionError("test failed due to a compilation error"); + } for (Entry e : listener.kind2Count.entrySet()) { if (e.getValue() != null && e.getValue() != 0) { diff --git a/test/langtools/tools/javac/fatalErrors/ImproveFatalErrorHandling.java b/test/langtools/tools/javac/fatalErrors/ImproveFatalErrorHandling.java index de55cd8d5f7..278d8863b4a 100644 --- a/test/langtools/tools/javac/fatalErrors/ImproveFatalErrorHandling.java +++ b/test/langtools/tools/javac/fatalErrors/ImproveFatalErrorHandling.java @@ -76,7 +76,9 @@ public class ImproveFatalErrorHandling extends TestRunner { .getSystemJavaCompiler() .getTask(null, null, null, null, null, files); Context context = task.getContext(); - task.call(); + if (!task.call()) { + throw new AssertionError("test failed due to a compilation error"); + } JavaCompiler compiler = context.get(compilerKey); compiler.closeables = com.sun.tools.javac.util.List.of( new CloseException1(), new CloseException2(), diff --git a/test/langtools/tools/javac/lib/DPrinter.java b/test/langtools/tools/javac/lib/DPrinter.java index 6fa2f17dc67..5092e0698c2 100644 --- a/test/langtools/tools/javac/lib/DPrinter.java +++ b/test/langtools/tools/javac/lib/DPrinter.java @@ -1602,7 +1602,9 @@ public class DPrinter { } }); - task.call(); + if (!task.call()) { + throw new AssertionError("compilation failed at DPrinter.Main::run"); + } } TaskEvent.Kind getKind(String s) { diff --git a/test/langtools/tools/javac/modules/QueryBeforeEnter.java b/test/langtools/tools/javac/modules/QueryBeforeEnter.java index 226c6aed8e3..293b6302eec 100644 --- a/test/langtools/tools/javac/modules/QueryBeforeEnter.java +++ b/test/langtools/tools/javac/modules/QueryBeforeEnter.java @@ -359,7 +359,9 @@ public class QueryBeforeEnter extends ModuleTestBase { "-Xplugin:test"), null, fm.getJavaFileObjects(testSource)); - task.call(); + if (!task.call()) { + throw new AssertionError("test failed due to a compilation error"); + } } Main.compile(new String[] {"--processor-path", processorPath, diff --git a/test/langtools/tools/javac/patterns/SOEDeeplyNestedBlocksTest.java b/test/langtools/tools/javac/patterns/SOEDeeplyNestedBlocksTest.java index 4e738cce028..8f64b4cff37 100644 --- a/test/langtools/tools/javac/patterns/SOEDeeplyNestedBlocksTest.java +++ b/test/langtools/tools/javac/patterns/SOEDeeplyNestedBlocksTest.java @@ -34,7 +34,7 @@ import javax.tools.*; public class SOEDeeplyNestedBlocksTest { - static final int NESTING_DEPTH = 1000; + static final int NESTING_DEPTH = 500; public static void main(String... args) { var lines = new ArrayList(); @@ -48,7 +48,9 @@ public class SOEDeeplyNestedBlocksTest { var source = SimpleJavaFileObject.forSource(URI.create("mem://Test.java"), String.join("\n", lines)); var compiler = ToolProvider.getSystemJavaCompiler(); var task = compiler.getTask(null, null, noErrors, null, null, List.of(source)); - task.call(); + if (!task.call()) { + throw new AssertionError("test failed due to a compilation error"); + } } static DiagnosticListener noErrors = d -> { diff --git a/test/langtools/tools/javac/positions/TreeEndPosTest.java b/test/langtools/tools/javac/positions/TreeEndPosTest.java index 990053a7d4e..dc87409f4b2 100644 --- a/test/langtools/tools/javac/positions/TreeEndPosTest.java +++ b/test/langtools/tools/javac/positions/TreeEndPosTest.java @@ -174,7 +174,9 @@ public class TreeEndPosTest { compiler.getTask(writer, javaFileManager, dc, options, null, sources); - task.call(); + if (task.call()) { + throw new AssertionError("test compilation was expected to fail"); + } for (Diagnostic diagnostic : (List) dc.getDiagnostics()) { long actualStart = diagnostic.getStartPosition(); long actualEnd = diagnostic.getEndPosition(); diff --git a/test/langtools/tools/javac/processing/6348499/T6348499.java b/test/langtools/tools/javac/processing/6348499/T6348499.java index f8f8c30bdd7..266caa1e14f 100644 --- a/test/langtools/tools/javac/processing/6348499/T6348499.java +++ b/test/langtools/tools/javac/processing/6348499/T6348499.java @@ -61,7 +61,9 @@ public class T6348499 { "-processorpath", testClassPath); StringWriter out = new StringWriter(); JavacTask task = tool.getTask(out, fm, dl, opts, null, files); - task.call(); + if (task.call()) { + throw new AssertionError("test compilation was expected to fail"); + } String s = out.toString(); System.err.print(s); // Expect the following 1 multi-line diagnostic, and no output to log diff --git a/test/langtools/tools/javac/processing/6414633/T6414633.java b/test/langtools/tools/javac/processing/6414633/T6414633.java index d38d1acdd82..5ee7b5e646d 100644 --- a/test/langtools/tools/javac/processing/6414633/T6414633.java +++ b/test/langtools/tools/javac/processing/6414633/T6414633.java @@ -60,7 +60,9 @@ public class T6414633 { String[] opts = { "-proc:only", "-processor", A.class.getName() }; JavacTask task = tool.getTask(null, fm, dl, Arrays.asList(opts), null, files); - task.call(); + if (task.call()) { + throw new AssertionError("test compilation was expected to fail"); + } // two annotations on the same element -- expect 2 diags from the processor if (dl.diags != 2) diff --git a/test/langtools/tools/javac/processing/6430209/T6430209.java b/test/langtools/tools/javac/processing/6430209/T6430209.java index 2f79b36a3e1..1371b7c09d6 100644 --- a/test/langtools/tools/javac/processing/6430209/T6430209.java +++ b/test/langtools/tools/javac/processing/6430209/T6430209.java @@ -66,7 +66,9 @@ public class T6430209 { "-processorpath", testClassPath); StringWriter out = new StringWriter(); JavacTask task = tool.getTask(out, fm, null, opts, null, files); - task.call(); + if (task.call()) { + throw new AssertionError("test compilation was expected to fail"); + } String s = out.toString(); System.err.print(s); s = s.replace(System.getProperty("line.separator"), "\n"); diff --git a/test/langtools/tools/javac/processing/T6439826.java b/test/langtools/tools/javac/processing/T6439826.java index 846d77c3a7e..fed293d4e5e 100644 --- a/test/langtools/tools/javac/processing/T6439826.java +++ b/test/langtools/tools/javac/processing/T6439826.java @@ -55,7 +55,9 @@ public class T6439826 extends AbstractProcessor { "-processorpath", testClasses); StringWriter out = new StringWriter(); JavacTask task = tool.getTask(out, fm, dl, opts, null, files); - task.call(); + if (task.call()) { + throw new AssertionError("test compilation was expected to fail"); + } String s = out.toString(); System.err.print(s); // Expect the following 2 diagnostics, and no output to log diff --git a/test/langtools/tools/javac/processing/T8142931.java b/test/langtools/tools/javac/processing/T8142931.java index 5abeac83687..8ade5e19767 100644 --- a/test/langtools/tools/javac/processing/T8142931.java +++ b/test/langtools/tools/javac/processing/T8142931.java @@ -62,7 +62,9 @@ public class T8142931 extends AbstractProcessor { "-processorpath", testClasses); StringWriter out = new StringWriter(); JavacTask task = (JavacTask)tool.getTask(out, fm, dl, opts, null, files); - task.call(); + if (!task.call()) { + throw new AssertionError("test failed due to a compilation error"); + } String s = out.toString(); System.err.print(s); System.err.println(dl.count + " diagnostics; " + s.length() + " characters"); diff --git a/test/langtools/tools/javac/processing/model/LocalInAnonymous.java b/test/langtools/tools/javac/processing/model/LocalInAnonymous.java index 6cbbe512784..616062bb542 100644 --- a/test/langtools/tools/javac/processing/model/LocalInAnonymous.java +++ b/test/langtools/tools/javac/processing/model/LocalInAnonymous.java @@ -81,7 +81,9 @@ public class LocalInAnonymous { List options = Arrays.asList("-d", classes.toString()); StringWriter out = new StringWriter(); JavacTask task = (JavacTask) compiler.getTask(out, null, noErrors, options, null, files); - task.call(); + if (!task.call()) { + throw new AssertionError("test failed due to a compilation error"); + } if (!out.toString().isEmpty()) { throw new AssertionError("Unexpected output: " + out); } @@ -103,7 +105,9 @@ public class LocalInAnonymous { } } }); - task2.call(); + if (!task2.call()) { + throw new AssertionError("test failed due to a compilation error"); + } if (!out.toString().isEmpty()) { throw new AssertionError("Unexpected output: " + out); } @@ -112,7 +116,9 @@ public class LocalInAnonymous { "-processorpath", System.getProperty("test.classes"), "-processor", Processor.class.getName()); JavacTask task3 = (JavacTask) compiler.getTask(out, null, noErrors, options, null, files); - task3.call(); + if (!task3.call()) { + throw new AssertionError("test failed due to a compilation error"); + } if (!out.toString().isEmpty()) { throw new AssertionError("Unexpected output: " + out); } diff --git a/test/langtools/tools/javac/processing/options/TestNoteOnImplicitProcessing.java b/test/langtools/tools/javac/processing/options/TestNoteOnImplicitProcessing.java index 73089a9a3cf..181c29eeb56 100644 --- a/test/langtools/tools/javac/processing/options/TestNoteOnImplicitProcessing.java +++ b/test/langtools/tools/javac/processing/options/TestNoteOnImplicitProcessing.java @@ -323,7 +323,9 @@ public class TestNoteOnImplicitProcessing extends TestRunner { List options = List.of("-classpath", jarFile.toString(), "-XDrawDiagnostics"); CompilationTask task = provider.getTask(compilerOut, null, null, options, null, inputFile); - task.call(); + if (!task.call()) { + throw new AssertionError("test failed due to a compilation error"); + } verifyMessages(out, compilerOut, false, false); } @@ -335,7 +337,9 @@ public class TestNoteOnImplicitProcessing extends TestRunner { (Processor) processorClass.getDeclaredConstructor().newInstance(); task.setProcessors(List.of(processor)); - task.call(); + if (!task.call()) { + throw new AssertionError("test failed due to a compilation error"); + } verifyMessages(out, compilerOut, false, true); } diff --git a/test/langtools/tools/javac/processing/rounds/CompleteOnClosed.java b/test/langtools/tools/javac/processing/rounds/CompleteOnClosed.java index 1ebc6b2acec..f724d605e51 100644 --- a/test/langtools/tools/javac/processing/rounds/CompleteOnClosed.java +++ b/test/langtools/tools/javac/processing/rounds/CompleteOnClosed.java @@ -56,7 +56,9 @@ public class CompleteOnClosed extends JavacTestingAbstractProcessor { Iterable files = Arrays.asList(new ToolBox.JavaSource(source)); Iterable options = Arrays.asList("-processor", "CompleteOnClosed"); CompilationTask task = compiler.getTask(null, null, collector, options, null, files); - task.call(); + if (task.call()) { + throw new AssertionError("test compilation was expected to fail"); + } for (Diagnostic d : collector.getDiagnostics()) { System.out.println(d.toString()); } diff --git a/test/lib/jdk/test/lib/security/SecurityUtils.java b/test/lib/jdk/test/lib/security/SecurityUtils.java index 7509488225e..be6ff1cc0e3 100644 --- a/test/lib/jdk/test/lib/security/SecurityUtils.java +++ b/test/lib/jdk/test/lib/security/SecurityUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -45,6 +45,8 @@ public final class SecurityUtils { private enum KeySize{ RSA(2048), DSA(2048), + Ed25519(256), + EC(256), DH(2048); private final int keySize; @@ -145,6 +147,8 @@ public final class SecurityUtils { return switch (algo) { case "RSA" -> KeySize.RSA.keySize; case "DSA" -> KeySize.DSA.keySize; + case "Ed25519" -> KeySize.Ed25519.keySize; + case "EC" -> KeySize.EC.keySize; case "DH", "DiffieHellman" -> KeySize.DH.keySize; default -> throw new RuntimeException("Test key size not defined for " + algo); }; diff --git a/test/lib/jdk/test/whitebox/WhiteBox.java b/test/lib/jdk/test/whitebox/WhiteBox.java index 10fad866ca3..d1f2c5822af 100644 --- a/test/lib/jdk/test/whitebox/WhiteBox.java +++ b/test/lib/jdk/test/whitebox/WhiteBox.java @@ -297,10 +297,6 @@ public class WhiteBox { public native int g1ActiveMemoryNodeCount(); public native int[] g1MemoryNodeIds(); - // Parallel GC - public native long psVirtualSpaceAlignment(); - public native long psHeapGenerationAlignment(); - /** * Enumerates old regions with liveness less than specified and produces some statistics * @param liveness percent of region's liveness (live_objects / total_region_size * 100).