From 1c1a13085620a604b5668df4a26f4b09a704ceb5 Mon Sep 17 00:00:00 2001 From: David Holmes Date: Mon, 8 Jun 2026 22:01:56 +0000 Subject: [PATCH 01/20] 8384844: Remove expired flags in JDK 28 Reviewed-by: jwilhelm, kvn, syan, jsikstro --- src/hotspot/share/runtime/arguments.cpp | 19 ------------- src/java.base/share/man/java.md | 38 ++++++++++++++----------- 2 files changed, 21 insertions(+), 36 deletions(-) diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index dc177bdce6d..2804224ed01 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -544,25 +544,6 @@ static SpecialFlag const special_jvm_flags[] = { { "UseCompressedClassPointers", JDK_Version::jdk(25), JDK_Version::jdk(27), JDK_Version::undefined() }, #endif - { "PSChunkLargeArrays", JDK_Version::jdk(26), JDK_Version::jdk(27), JDK_Version::jdk(28) }, - { "ParallelRefProcEnabled", JDK_Version::jdk(26), JDK_Version::jdk(27), JDK_Version::jdk(28) }, - { "ParallelRefProcBalancingEnabled", JDK_Version::jdk(26), JDK_Version::jdk(27), JDK_Version::jdk(28) }, - { "MaxRAM", JDK_Version::jdk(26), JDK_Version::jdk(27), JDK_Version::jdk(28) }, - { "NewSizeThreadIncrease", JDK_Version::undefined(), JDK_Version::jdk(27), JDK_Version::jdk(28) }, - { "NeverActAsServerClassMachine", JDK_Version::jdk(26), JDK_Version::jdk(27), JDK_Version::jdk(28) }, - { "AlwaysActAsServerClassMachine", JDK_Version::jdk(26), JDK_Version::jdk(27), JDK_Version::jdk(28) }, - { "UseXMMForArrayCopy", JDK_Version::undefined(), JDK_Version::jdk(27), JDK_Version::jdk(28) }, - { "UseNewLongLShift", JDK_Version::undefined(), JDK_Version::jdk(27), JDK_Version::jdk(28) }, - { "AggressiveHeap", JDK_Version::jdk(26), JDK_Version::jdk(27), JDK_Version::jdk(28) }, - - {"ShenandoahAccelerationSamplePeriod", JDK_Version::undefined(), JDK_Version::jdk(27), JDK_Version::jdk(28) }, - {"ShenandoahRateAccelerationSampleSize", JDK_Version::undefined(), JDK_Version::jdk(27), JDK_Version::jdk(28) }, - {"ShenandoahMomentaryAllocationRateSpikeSampleSize", JDK_Version::undefined(), JDK_Version::jdk(27), JDK_Version::jdk(28) }, - {"ShenandoahAdaptiveSampleFrequencyHz", JDK_Version::undefined(), JDK_Version::jdk(27), JDK_Version::jdk(28) }, - {"ShenandoahAdaptiveSampleSizeSeconds", JDK_Version::undefined(), JDK_Version::jdk(27), JDK_Version::jdk(28) }, - {"ShenandoahAdaptiveInitialSpikeThreshold",JDK_Version::undefined(), JDK_Version::jdk(27), JDK_Version::jdk(28) }, - {"ShenandoahAdaptiveDecayFactor", JDK_Version::undefined(), JDK_Version::jdk(27), JDK_Version::jdk(28) }, - #ifdef ASSERT { "DummyObsoleteTestFlag", JDK_Version::undefined(), JDK_Version::jdk(18), JDK_Version::undefined() }, #endif diff --git a/src/java.base/share/man/java.md b/src/java.base/share/man/java.md index 70824046824..ef99084018d 100644 --- a/src/java.base/share/man/java.md +++ b/src/java.base/share/man/java.md @@ -2997,14 +2997,6 @@ they're used. : Enables the use of Java Flight Recorder (JFR) during the runtime of the application. Since JDK 8u40 this option has not been required to use JFR. -[`-XX:+ParallelRefProcEnabled`]{#-XX__ParallelRefProcEnabled} -: Enables parallel reference processing. By default, collectors employing multiple - threads perform parallel reference processing if the number of parallel threads - to use is larger than one. - The option is available only when the throughput or G1 garbage collector is used - (`-XX:+UseParallelGC` or `-XX:+UseG1GC`). Other collectors employing multiple - threads always perform reference processing in parallel. - ## Obsolete Java Options These `java` options are still accepted but ignored, and a warning is issued @@ -3017,6 +3009,18 @@ when they're used. 396](https://openjdk.org/jeps/396) and made obsolete in JDK 17 by [JEP 403](https://openjdk.org/jeps/403). +## 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:+AggressiveHeap`]{#-XX__AggressiveHeap} +: Enabled Java heap optimization. This set various parameters to be + optimal for long-running jobs with intensive memory allocation, based on + the configuration of the computer (RAM and CPU). By default, the option + was disabled and the heap sizes configured less aggressively. + [`-XX:+NeverActAsServerClassMachine`]{#-XX__NeverActAsServerClassMachine} : Enabled the "Client VM emulation" mode, which used only the C1 JIT compiler, a 32Mb CodeCache, and the Serial GC. The maximum amount of memory that the @@ -3037,18 +3041,18 @@ when they're used. -XX:{+|-}UseJVMCICompiler ``` -[`-XX:+AggressiveHeap`]{#-XX__AggressiveHeap} -: Enabled Java heap optimization. This set various parameters to be - optimal for long-running jobs with intensive memory allocation, based on - the configuration of the computer (RAM and CPU). By default, the option - was disabled and the heap sizes configured less aggressively. - -## Removed Java Options - -No documented java options have been removed in JDK @@VERSION_SPECIFICATION@@. +[`-XX:+ParallelRefProcEnabled`]{#-XX__ParallelRefProcEnabled} +: Enables parallel reference processing. By default, collectors employing multiple + threads perform parallel reference processing if the number of parallel threads + to use is larger than one. + The option is available only when the throughput or G1 garbage collector is used + (`-XX:+UseParallelGC` or `-XX:+UseG1GC`). Other collectors employing multiple + threads always perform reference processing in parallel. For the lists and descriptions of options removed in previous releases see the *Removed Java Options* section in: +- [The `java` Command, Release 27](https://docs.oracle.com/en/java/javase/27/docs/specs/man/java.html) + - [The `java` Command, Release 26](https://docs.oracle.com/en/java/javase/26/docs/specs/man/java.html) - [The `java` Command, Release 25](https://docs.oracle.com/en/java/javase/25/docs/specs/man/java.html) From ac85fddbbc89189dc7dd36991bea82157db699f7 Mon Sep 17 00:00:00 2001 From: Richard Reingruber Date: Tue, 9 Jun 2026 05:14:05 +0000 Subject: [PATCH 02/20] 8385166: PPC: C2: c_return_value and return_value should not set 2nd OptoRegPair for Op_RegI Reviewed-by: mdoerr, dbriemann --- src/hotspot/cpu/ppc/ppc.ad | 42 +++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/src/hotspot/cpu/ppc/ppc.ad b/src/hotspot/cpu/ppc/ppc.ad index 7360ed604f1..ea1768c6afd 100644 --- a/src/hotspot/cpu/ppc/ppc.ad +++ b/src/hotspot/cpu/ppc/ppc.ad @@ -3475,30 +3475,34 @@ frame %{ // 4 what apparently works and saves us some spills. return_addr(STACK 4); - // Location of native (C/C++) and interpreter return values. This - // is specified to be the same as Java. In the 32-bit VM, long - // values are actually returned from native calls in O0:O1 and - // returned to the interpreter in I0:I1. The copying to and from - // the register pairs is done by the appropriate call and epilog - // opcodes. This simplifies the register allocator. - c_return_value %{ - assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || - (ideal_reg == Op_RegN && CompressedOops::base() == nullptr && CompressedOops::shift() == 0), - "only return normal values"); - // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL - static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; - static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; - return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); - %} - // Location of compiled Java return values. Same as C return_value %{ assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || (ideal_reg == Op_RegN && CompressedOops::base() == nullptr && CompressedOops::shift() == 0), "only return normal values"); - // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL - static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; - static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; + // enum names from opcodes.hpp + static int typeToRegLo[Op_RegL+1] = { + 0, // Op_Node + 0, // Op_Set + R3_num, // Op_RegN + R3_num, // Op_RegI + R3_num, // Op_RegP + F1_num, // Op_RegF + F1_num, // Op_RegD + R3_num, // Op_RegL + }; + + static int typeToRegHi[Op_RegL+1] = { + 0, // Op_Node + 0, // Op_Set + OptoReg::Bad, // Op_RegN + OptoReg::Bad, // Op_RegI + R3_H_num, // Op_RegP + OptoReg::Bad, // Op_RegF + F1_H_num, // Op_RegD + R3_H_num // Op_RegL + }; + return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); %} %} From 7a7ee23168584b5ff80c3cb11360b738089f11c3 Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Tue, 9 Jun 2026 07:25:12 +0000 Subject: [PATCH 03/20] 8385454: Provide more NUMA related information in hsinfo/hserr files Reviewed-by: jsikstro, dbriemann --- src/hotspot/os/linux/os_linux.cpp | 95 +++++++++++++++++++++++++++++++ src/hotspot/os/linux/os_linux.hpp | 1 + 2 files changed, 96 insertions(+) diff --git a/src/hotspot/os/linux/os_linux.cpp b/src/hotspot/os/linux/os_linux.cpp index ba48f2b4efc..ad1f384fa32 100644 --- a/src/hotspot/os/linux/os_linux.cpp +++ b/src/hotspot/os/linux/os_linux.cpp @@ -2183,6 +2183,10 @@ void os::print_os_info(outputStream* st) { st->cr(); } + if (os::Linux::print_numa_info(st)) { + st->cr(); + } + VM_Version::print_platform_virtualization_info(st); os::Linux::print_steal_info(st); @@ -2622,6 +2626,97 @@ bool os::Linux::print_container_info(outputStream* st) { return true; } +#define SYS_DEVICES_NODE "/sys/devices/system/node" + +static size_t read_sysfs_file(const char* path, char* buf, size_t sz) { + FILE* f = os::fopen(path, "r"); + if (f == nullptr) return 0; + size_t n = fread(buf, 1, sz - 1, f); + fclose(f); + buf[n] = '\0'; + while (n > 0 && (buf[n-1] == '\n' || buf[n-1] == '\r')) buf[--n] = '\0'; + return n; +} + +static void print_numa_memory_info(outputStream* st, int node) { + char path[256]; + char line[256]; + long long mem_total = -1; + long long mem_free = -1; + os::snprintf_checked(path, sizeof(path), SYS_DEVICES_NODE "/node%d/meminfo", node); + FILE* f = os::fopen(path, "r"); + if (f == nullptr) { + return; + } + + while (fgets(line, sizeof(line), f) != nullptr) { + long long mval; + if (sscanf(line, "Node %*d MemTotal: %lld kB", &mval) == 1) mem_total = mval; + if (sscanf(line, "Node %*d MemFree: %lld kB", &mval) == 1) mem_free = mval; + } + fclose(f); + + if (mem_total >= 0) { st->print_cr("mem size: %lld kB", mem_total); } + if (mem_free >= 0) { st->print_cr("mem free: %lld kB", mem_free); } +} + +static void print_numa_cpu_list(outputStream* st, int node) { + char path[256]; + char buf[1024]; + os::snprintf_checked(path, sizeof(path), SYS_DEVICES_NODE "/node%d/cpulist", node); + if (read_sysfs_file(path, buf, sizeof(buf)) > 0) { + st->print_cr("cpus: %s", buf); + } else { + st->print_cr("cpus: (unavailable)"); + } +} + +bool os::Linux::print_numa_info(outputStream* st) { + if (!UseNUMA) { + // If NUMA optimizations are not enabled we don't print anything + return false; + } + + char buf[1024]; + if (read_sysfs_file("/sys/devices/system/node/online", buf, sizeof(buf)) > 0) { + st->print_cr("NUMA nodes online: %s", buf); + } else { + return false; + } + + bool first = true; + int node_count = 0; + + if (nindex_to_node() == nullptr) { + return false; + } + + for (int node: *nindex_to_node()) { + char nodepath[256]; + os::snprintf_checked(nodepath, sizeof(nodepath), SYS_DEVICES_NODE "/node%d", node); + DIR* currd = os::opendir(nodepath); + if (currd == nullptr) continue; + if (first) { + st->cr(); + first = false; + } + os::closedir(currd); + + st->print_cr("NUMA node %d", node); + StreamIndentor si(st); + print_numa_cpu_list(st, node); + print_numa_memory_info(st, node); + node_count++; + } + + if (node_count == 0) { + return false; + } + + st->print_cr("Total NUMA node count: %d", node_count); + return true; +} + void os::Linux::print_steal_info(outputStream* st) { if (has_initial_tick_info) { CPUPerfTicks pticks; diff --git a/src/hotspot/os/linux/os_linux.hpp b/src/hotspot/os/linux/os_linux.hpp index 41b5afbf5c3..51a10be1e5d 100644 --- a/src/hotspot/os/linux/os_linux.hpp +++ b/src/hotspot/os/linux/os_linux.hpp @@ -77,6 +77,7 @@ class os::Linux { static void print_proc_sys_info(outputStream* st); static bool print_ld_preload_file(outputStream* st); static void print_uptime_info(outputStream* st); + static bool print_numa_info(outputStream* st); public: struct CPUPerfTicks { From 8556794f6ef74413822aab6ccfa309194d6a1f4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20H=C3=A4ssig?= Date: Tue, 9 Jun 2026 09:06:34 +0000 Subject: [PATCH 04/20] 8385950: Git: add ignore revisions file Reviewed-by: erikj --- .git-blame-ignore-revs | 184 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 .git-blame-ignore-revs diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 00000000000..ee91f5d33e2 --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1,184 @@ +# git blame ignore revs file +# +# The list of revisions below will be ignored by git-blame (1) if this file gets +# passed via the --ignore-revs-file command line option or is configured using +# the blame.ignoreRevsFile key. +# +# Only add commits that obviously do not change semantics, e.g. mechanical refactorings +# or formatting. Always add the commit message as a comment above the revision +# to keep the file readable. + +# 8299973: Replace NULL with nullptr in share/utilities/ +1084fd24eb118d4131538c2a3ead714db7d0357b + +# 8299974: Replace NULL with nullptr in share/adlc/ +62537d200f01d58ff1c236f31f71c5839316db9e + +# 8300081: Replace NULL with nullptr in share/asm/ +9d5bab11f08a992803399f422d75b17f8607df72 + +# 8300086: Replace NULL with nullptr in share/c1/ +90d5041b6a055d6266140ffea2aa9a3b08b32209 + +# 8300087: Replace NULL with nullptr in share/cds/ +eca64795be63c599a637ce2a7f740b2d0a1ec9bc + +# 8300222: Replace NULL with nullptr in share/logging +bd5ca953058704087da4bc5796b3ce28ce2a8f78 + +# 8300240: Replace NULL with nullptr in share/ci/ +f52d35c84b7333809156d201c866793854143888 + +# 8300241: Replace NULL with nullptr in share/classfile/ +49ff52087be8b95cbf369518281312ecc9d83618 + +# 8300242: Replace NULL with nullptr in share/code/ +cfe57466ddecb93b528478d0b053b089dd1ed285 + +# 8300243: Replace NULL with nullptr in share/compiler/ +fcbf9d052efd16821750fb20813f8030ee828472 + +# 8300244: Replace NULL with nullptr in share/interpreter/ +a5d8e12872d9de399fa97b33896635d101b71372 + +# 8300245: Replace NULL with nullptr in share/jfr/ +cc396895e5a1dac49f4e341ce91c04b8c092d0af + +# 8300651: Replace NULL with nullptr in share/runtime/ +71107f4648d8f31a7bcc0aa5202ef46230df583f + +# 8301068: Replace NULL with nullptr in share/jvmci/ +90ec19efeda90f13a918b4481fe6ee552ab2af66 + +# 8301069: Replace NULL with nullptr in share/libadt/ +b0376a5f4421fb58c0feeddfce2c2083314e400c + +# 8301070: Replace NULL with nullptr in share/memory/ +d98a323a8b972c17a066c597a81b164681ad5589 + +# 8301072: Replace NULL with nullptr in share/oops/ +c8ace482edead720c865cf996729a316025d937e + +# 8301074: Replace NULL with nullptr in share/opto/ +5726d31e56530bbe7dee61ae04b126e20cb3611d + +# 8301076: Replace NULL with nullptr in share/prims/ +b76a52f2104b63e84e5d09f47ce01dd0cb3935d7 + +# 8301077: Replace NULL with nullptr in share/services/ +5c1ec82656323872c4628026662fe5b62e7a61e3 + +# 8301178: Replace NULL with nullptr in share/gc/epsilon/ +b77abc6a0daed0e01a9003d42493320376dc98bc + +# 8301179: Replace NULL with nullptr in share/gc/serial/ +107e184d59c0bbed6441a3c1a9bfd4527da3bce5 + +# 8301180: Replace NULL with nullptr in share/gc/parallel/ +3758487fda61b27e7e684413793ed28c0b9e64d3 + +# 8301223: Replace NULL with nullptr in share/gc/g1/ +75a4edca6b9fa6b3e66b564aeb4d7ca8acf02491 + +# 8301225: Replace NULL with nullptr in share/gc/shenandoah/ +0c9658446d111ec944f06b7a8a4e3ae7bf53ee8d + +# 8301477: Replace NULL with nullptr in os/aix +43288bbd684abfcefdf385ed1e0307070399ccbf + +# 8301478: Replace NULL with nullptr in os/bsd +716f1df609e7f0aa7b3b9383d23dde5c71017d02 + +# 8301479: Replace NULL with nullptr in os/linux +ac9e046748a9bb6ee065dc473d82135ce36043b7 + +# 8301480: Replace NULL with nullptr in os/posix +4539899c55c77771b951d005c17550ef9ac94819 + +# 8301481: Replace NULL with nullptr in os/windows +c91cd2814baa8dee2af8af0fecf9185d4a0a44cf + +# 8301493: Replace NULL with nullptr in cpu/aarch64 +948f3b3c24709eca3aa6c3f0db6adb9226d6f9ac + +# 8301494: Replace NULL with nullptr in cpu/arm +c4ffe4bf6369d5b271aa8689b8648f3fe8dcabed + +# 8301495: Replace NULL with nullptr in cpu/ppc +0826ceee65ab83f643a77716f8f12d0060369923 + +# 8301496: Replace NULL with nullptr in cpu/riscv +d2ce04bb101002abfdb7c8adb3fa8ea267903c36 + +# 8301497: Replace NULL with nullptr in cpu/s390 +54f7b6ca34986cc26c5b91c6724b9a1754c94391 + +# 8301498: Replace NULL with nullptr in cpu/x86 +4154a980ca28c1ae56db26e3dce64c07c225de12 + +# 8301499: Replace NULL with nullptr in cpu/zero +4e327db1d127c652ef39e31c164e36ae429a0065 + +# 8301500: Replace NULL with nullptr in os_cpu/aix_ppc +c8307e37fdf4453cade84efc113d93dd14333fd0 + +# 8301501: Replace NULL with nullptr in os_cpu/bsd_aarch64 +218223e4a31d485935655cb3f186a752defd8fa8 + +# 8301502: Replace NULL with nullptr in os_cpu/bsd_x86 +6daff6b26946748360d59a12e9069a08ab5ca06d + +# 8301503: Replace NULL with nullptr in os_cpu/bsd_zero +8cc399b672c6ce08037685b3a3a2db3c53a87b50 + +# 8301504: Replace NULL with nullptr in os_cpu/linux_aarch64 +13fcd602d37eb0095f169255128588b872639571 + +# 8301505: Replace NULL with nullptr in os_cpu/linux_arm +b81f0ff43ac8d1431f2f5dccb7499a3a1503823d + +# 8301506: Replace NULL with nullptr in os_cpu/linux_ppc +b1e96989b693aadea082a01576e25f85ed28ff0d + +# 8301507: Replace NULL with nullptr in os_cpu/linux_riscv +182d1b2fb7034b6e9177dc360cbea43d548c3ff0 + +# 8301508: Replace NULL with nullptr in os_cpu/linux_s390 +d097b5e6285e1a59632211e006592fedf2047c09 + +# 8301509: Replace NULL with nullptr in os_cpu/linux_x86 +5d1f71daf06870810c9ca24e911d6191cc4f3006 + +# 8301511: Replace NULL with nullptr in os_cpu/linux_zero +42a286a15862d9a05ea3477a9eeab46e7b33e599 + +# 8301512: Replace NULL with nullptr in os_cpu/windows_aarch64 +ad79e49141f063a61090eda69d96dc580db88949 + +# 8301513: Replace NULL with nullptr in os_cpu/windows_x86 +c109dae48c61c6fbeacadf59d509d37d2c4d2bb8 + +# 8308092: Replace NULL with nullptr in gc/x +599fa774b875da971d66f79e5e43ede2b5ce18aa + +# 8309044: Replace NULL with nullptr, final sweep of hotspot code +4f16161607edbf69f423ced1d3c24f7af058d46b + +# 8324286: Fix backsliding on use of nullptr instead of NULL +bcb340da091e3287da8d2ecfcd017ebcc6613cae + +# 8324678: Replace NULL with nullptr in HotSpot gtests +c1281e6b45ed167df69d29a6039d81854c145ae6 + +# 8324679: Replace NULL with nullptr in HotSpot .ad files +b3ecd55601d483359819d02e70789bbd412b13da + +# 8324680: Replace NULL with nullptr in JVMTI generated code +267780bf0adf4bfd831fbc04347e297fa8f3bb01 + +# 8324681: Replace NULL with nullptr in HotSpot jtreg test native code files +a6bdee48f39993128d8095d40ab417f0102af0f4 + +# 8324799: Use correct extension for C++ test headers +998d0baab0fd051c38d9fd6021628eb863b80554 + From f4b46d86dd690a47b894ce9a186d5c98149c3382 Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Tue, 9 Jun 2026 09:09:21 +0000 Subject: [PATCH 05/20] 8385989: Remove mention of obsoleted/removed ParallelRefProcEnabled in documentation Reviewed-by: aboldtch, jsikstro --- src/hotspot/share/gc/shared/gc_globals.hpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/hotspot/share/gc/shared/gc_globals.hpp b/src/hotspot/share/gc/shared/gc_globals.hpp index 1ff6fd493a7..14bc320e32c 100644 --- a/src/hotspot/share/gc/shared/gc_globals.hpp +++ b/src/hotspot/share/gc/shared/gc_globals.hpp @@ -199,10 +199,9 @@ range(1, (INT_MAX - 1)) \ \ product(size_t, ReferencesPerThread, 1000, EXPERIMENTAL, \ - "Ergonomically start one thread for this amount of " \ - "references for reference processing if " \ - "ParallelRefProcEnabled is true. Specify 0 to disable and " \ - "use all threads.") \ + "Ergonomically start one thread for this amount of references " \ + "for reference processing for parallel stop-the-world garbage " \ + "collectors. Specify 0 to force use of all available threads.") \ \ product(uint, InitiatingHeapOccupancyPercent, 45, \ "The percent occupancy (IHOP) of the current old generation " \ From ff2b7b3f9d57be6f869759f3cda3e3debb05d047 Mon Sep 17 00:00:00 2001 From: Amit Kumar Date: Tue, 9 Jun 2026 09:12:01 +0000 Subject: [PATCH 06/20] 8386150: VtablesTest.java fails when main thread is a Virtual Thread Reviewed-by: syan, shade --- test/hotspot/jtreg/runtime/logging/VtablesTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/hotspot/jtreg/runtime/logging/VtablesTest.java b/test/hotspot/jtreg/runtime/logging/VtablesTest.java index a07fe895173..c87c274d31d 100644 --- a/test/hotspot/jtreg/runtime/logging/VtablesTest.java +++ b/test/hotspot/jtreg/runtime/logging/VtablesTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -55,7 +55,7 @@ public class VtablesTest { output.shouldContain("NOT overriding with p2.D.nooverride()V"); output.shouldHaveExitValue(0); - pb = ProcessTools.createLimitedTestJavaProcessBuilder("-Xlog:vtables=trace", "p1/C"); + pb = ProcessTools.createLimitedTestJavaProcessBuilder("-Xlog:vtables=trace", "p1.C"); output = new OutputAnalyzer(pb.start()); output.shouldContain("transitive overriding superclass "); output.shouldHaveExitValue(0); From b6fb712b6fcb1095c162ba15bf519045a8c451ae Mon Sep 17 00:00:00 2001 From: Kevin Walls Date: Tue, 9 Jun 2026 12:56:01 +0000 Subject: [PATCH 07/20] 8385839: JMX config file correction Reviewed-by: sspitsyn --- .../share/conf/jmxremote.password.template | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/jdk.management.agent/share/conf/jmxremote.password.template b/src/jdk.management.agent/share/conf/jmxremote.password.template index c98a0ad253a..0b0607497de 100644 --- a/src/jdk.management.agent/share/conf/jmxremote.password.template +++ b/src/jdk.management.agent/share/conf/jmxremote.password.template @@ -55,8 +55,6 @@ # * com.sun.management.jmxremote.password.toHashes property is set to true in # management.properties file # * the password file is writable -# * the system security policy allows writing into the password file, if a -# security manager is configured # # In order to change the password for a role, replace the hashed password entry # with a new clear text password or a new hashed password. If the new password @@ -110,6 +108,6 @@ # below entries with clear passwords overwritten by their respective # SHA3-512 hash # -# monitorRole trilby APzBTt34rV2l+OMbuvbnOQ4si8UZmfRCVbIY1+fAofV5CkQzXS/FDMGteQQk/R3q1wtt104qImzJEA7gCwl6dw== 4EeTdSJ7X6Imu0Mb+dWqIns7a7QPIBoM3NB/XlpMQSPSicE7PnlALVWn2pBY3Q3pGDHyAb32Hd8GUToQbUhAjA== SHA3-512 +# monitorRole APzBTt34rV2l+OMbuvbnOQ4si8UZmfRCVbIY1+fAofV5CkQzXS/FDMGteQQk/R3q1wtt104qImzJEA7gCwl6dw== 4EeTdSJ7X6Imu0Mb+dWqIns7a7QPIBoM3NB/XlpMQSPSicE7PnlALVWn2pBY3Q3pGDHyAb32Hd8GUToQbUhAjA== SHA3-512 # controlRole roHEJSbRqSSTII4Z4+NOCV2OJaZVQ/dw153Fy2u4ILDP9XiZ426GwzCzc3RtpoqNMwqYIcfdd74xWXSMrWtGaA== w9qDsekgKn0WOVJycDyU0kLBa081zbStcCjUAVEqlfon5Sgx7XHtaodbmzpLegA1jT7Ag36T0zHaEWRHJe2fdA== SHA3-512 -# \ No newline at end of file +# From a529e45ad3958578275df0a6ec175d45d18ada2f Mon Sep 17 00:00:00 2001 From: Alexey Ivanov Date: Tue, 9 Jun 2026 16:00:42 +0000 Subject: [PATCH 08/20] 8291470: Description change for mouseMoved method in java.awt.event.MouseMotionAdapter Reviewed-by: azvegint, prr, serb --- .../java/awt/event/MouseMotionAdapter.java | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/java.desktop/share/classes/java/awt/event/MouseMotionAdapter.java b/src/java.desktop/share/classes/java/awt/event/MouseMotionAdapter.java index 4c284bf29ba..6bec617b5ae 100644 --- a/src/java.desktop/share/classes/java/awt/event/MouseMotionAdapter.java +++ b/src/java.desktop/share/classes/java/awt/event/MouseMotionAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,13 +32,13 @@ package java.awt.event; *

* Mouse motion events occur when a mouse is moved or dragged. * (Many such events will be generated in a normal program. - * To track clicks and other mouse events, use the MouseAdapter.) + * To track clicks and other mouse events, use the {@link MouseAdapter}.) *

* Extend this class to create a {@code MouseEvent} listener * and override the methods for the events of interest. (If you implement the * {@code MouseMotionListener} interface, you have to define all of * the methods in it. This abstract class defines null methods for them - * all, so you can only have to define methods for events you care about.) + * all, so you have to define only methods for events you care about.) *

* Create a listener object using the extended class and then register it with * a component using the component's {@code addMouseMotionListener} @@ -61,17 +61,14 @@ public abstract class MouseMotionAdapter implements MouseMotionListener { protected MouseMotionAdapter() {} /** - * Invoked when a mouse button is pressed on a component and then - * dragged. Mouse drag events will continue to be delivered to - * the component where the first originated until the mouse button is - * released (regardless of whether the mouse position is within the - * bounds of the component). + * {@inheritDoc} */ + @Override public void mouseDragged(MouseEvent e) {} /** - * Invoked when the mouse button has been moved on a component - * (with no buttons no down). + * {@inheritDoc} */ + @Override public void mouseMoved(MouseEvent e) {} } From 7f62474fcb63392c61239c0a54ddea70002832ac Mon Sep 17 00:00:00 2001 From: Justin Lu Date: Tue, 9 Jun 2026 16:28:45 +0000 Subject: [PATCH 09/20] 8386200: ListFormat incorrectly escapes single quotes Reviewed-by: naoto --- .../share/classes/java/text/ListFormat.java | 29 +++++++++++++++---- .../Format/ListFormat/TestListFormat.java | 14 ++++++++- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/src/java.base/share/classes/java/text/ListFormat.java b/src/java.base/share/classes/java/text/ListFormat.java index 29e58ea717c..c610ace64d6 100644 --- a/src/java.base/share/classes/java/text/ListFormat.java +++ b/src/java.base/share/classes/java/text/ListFormat.java @@ -498,15 +498,18 @@ public final class ListFormat extends Format { midIndex += mbLength; } } - parsed = new MessageFormat(createMessageFormatString(count), locale).parseObject(source, parsePos); + parsed = new MessageFormat(listToMessageFormatPattern(createMessageFormatString(count)), + locale).parseObject(source, parsePos); } } if (parsed == null) { // now try exact number patterns - parsed = new MessageFormat(patterns[TWO], locale).parseObject(source, parsePos); + parsed = new MessageFormat(listToMessageFormatPattern(patterns[TWO]), + locale).parseObject(source, parsePos); if (parsed == null) { - parsed = new MessageFormat(patterns[THREE], locale).parseObject(source, parsePos); + parsed = new MessageFormat(listToMessageFormatPattern(patterns[THREE]), + locale).parseObject(source, parsePos); } } @@ -584,9 +587,9 @@ public final class ListFormat extends Format { var len = input.length; return switch (len) { case 0 -> throw new IllegalArgumentException("There should at least be one input string"); - case 1 -> new MessageFormat("{0}", locale); - case 2, 3 -> new MessageFormat(patterns[len + 1], locale); - default -> new MessageFormat(createMessageFormatString(len), locale); + case 1 -> new MessageFormat(listToMessageFormatPattern("{0}"), locale); + case 2, 3 -> new MessageFormat(listToMessageFormatPattern(patterns[len + 1]), locale); + default -> new MessageFormat(listToMessageFormatPattern(createMessageFormatString(len)), locale); }; } @@ -742,4 +745,18 @@ public final class ListFormat extends Format { return prefixPos < suffixPos ? new int[] {prefixPos, suffixPos + suffix.length()} : null; } + + /** + * {@return the MessageFormat pattern corresponding to the passed ListFormat pattern} + * + * Single quotes must be escaped so they are interpreted as literal text + * as opposed to escaping delimiters when passed to MessageFormat. Everything + * else remains the same; ListFormat already handles other validation on its own. + * + * @param pattern list pattern to use + */ + private static String listToMessageFormatPattern(String pattern) { + return pattern.indexOf('\'') < 0 ? pattern : + pattern.replace("'", "''"); + } } diff --git a/test/jdk/java/text/Format/ListFormat/TestListFormat.java b/test/jdk/java/text/Format/ListFormat/TestListFormat.java index 68da9ce5fda..e85e98b6cf6 100644 --- a/test/jdk/java/text/Format/ListFormat/TestListFormat.java +++ b/test/jdk/java/text/Format/ListFormat/TestListFormat.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8041488 8316974 8318569 8306116 8385736 8385834 + * @bug 8041488 8316974 8318569 8306116 8385736 8385834 8386200 * @summary Tests for ListFormat class * @run junit TestListFormat */ @@ -74,6 +74,14 @@ public class TestListFormat { "", "", }; + // Ensures MessageFormat single quotes in custom patterns are treated as literals. + private static final String[] CUSTOM_PATTERNS_SINGLE_QUOTE = { + "' {0} ' {1}", + "{0} '' {1}", + "{0} ''' {1} '''", + "", + "", + }; private static final String[] CUSTOM_PATTERNS_IAE_START = { "{0}", "{0} mid {1}", @@ -142,6 +150,10 @@ public class TestListFormat { arguments(CUSTOM_PATTERNS_METACHAR, SAMPLE2, ". foo | bar ["), arguments(CUSTOM_PATTERNS_METACHAR, SAMPLE3, ". foo * bar | baz ["), arguments(CUSTOM_PATTERNS_METACHAR, SAMPLE4, ". foo * bar + baz | qux ["), + arguments(CUSTOM_PATTERNS_SINGLE_QUOTE, SAMPLE1, "foo"), + arguments(CUSTOM_PATTERNS_SINGLE_QUOTE, SAMPLE2, "' foo ''' bar '''"), + arguments(CUSTOM_PATTERNS_SINGLE_QUOTE, SAMPLE3, "' foo ' bar ''' baz '''"), + arguments(CUSTOM_PATTERNS_SINGLE_QUOTE, SAMPLE4, "' foo ' bar '' baz ''' qux '''") }; } From 543c21dde67c1014605ab314bb2567184d48934f Mon Sep 17 00:00:00 2001 From: Artur Barashev Date: Tue, 9 Jun 2026 17:35:26 +0000 Subject: [PATCH 10/20] 8386203: Use CRC32C checksum instead of Adler32 for stateless session ticket Reviewed-by: mullan, ascarpino --- .../share/classes/sun/security/ssl/SSLSessionImpl.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/java.base/share/classes/sun/security/ssl/SSLSessionImpl.java b/src/java.base/share/classes/sun/security/ssl/SSLSessionImpl.java index af0b8909d30..45882a79fd7 100644 --- a/src/java.base/share/classes/sun/security/ssl/SSLSessionImpl.java +++ b/src/java.base/share/classes/sun/security/ssl/SSLSessionImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,7 @@ import java.util.Queue; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.locks.ReentrantLock; -import java.util.zip.Adler32; +import java.util.zip.CRC32C; import javax.crypto.KDF; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; @@ -610,9 +610,9 @@ final class SSLSessionImpl extends ExtendedSSLSession { } private static int getChecksum(byte[] input) { - Adler32 adler32 = new Adler32(); - adler32.update(input); - return (int) adler32.getValue(); + CRC32C crc32c = new CRC32C(); + crc32c.update(input); + return (int) crc32c.getValue(); } void setMasterSecret(SecretKey secret) { From ced72988629662e1bedac633503845aebb7aed9b Mon Sep 17 00:00:00 2001 From: Xiaolong Peng Date: Tue, 9 Jun 2026 19:22:56 +0000 Subject: [PATCH 11/20] 8385961: Shenandoah: incorrect assert ordering in ShenandoahFreeSet::allocate_contiguous non-humongous path Reviewed-by: shade, wkemper --- src/hotspot/share/gc/shenandoah/shenandoahFreeSet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.cpp b/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.cpp index 4c474f2f86c..6563ffb6359 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.cpp @@ -1745,8 +1745,8 @@ HeapWord* ShenandoahFreeSet::allocate_contiguous(ShenandoahAllocRequest& req, bo for (idx_t i = beg; i <= end; i++) { ShenandoahHeapRegion* r = _heap->get_region(i); assert(i == beg || _heap->get_region(i - 1)->index() + 1 == r->index(), "Should be contiguous"); - assert(r->is_empty(), "Should be empty"); r->try_recycle_under_lock(); + assert(r->is_empty(), "Should be empty"); r->set_affiliation(req.affiliation()); r->make_regular_allocation(req.affiliation()); if ((i == end) && (used_words_in_last_region > 0)) { From 6c7fe6fd2045f13fce28139e8e6c5c1a9f6fa7d3 Mon Sep 17 00:00:00 2001 From: Jasmine Karthikeyan Date: Tue, 9 Jun 2026 23:00:22 +0000 Subject: [PATCH 12/20] 8349563: Improve AbsNode::Value() for integer types Reviewed-by: epeter, mchevalier, qamai --- src/hotspot/share/opto/subnode.cpp | 37 +- src/hotspot/share/opto/type.cpp | 12 + src/hotspot/share/opto/type.hpp | 4 + .../jtreg/compiler/c2/irTests/TestIRAbs.java | 567 +++++++++++++++++- 4 files changed, 605 insertions(+), 15 deletions(-) diff --git a/src/hotspot/share/opto/subnode.cpp b/src/hotspot/share/opto/subnode.cpp index 014f41f82cc..39d5f0be90c 100644 --- a/src/hotspot/share/opto/subnode.cpp +++ b/src/hotspot/share/opto/subnode.cpp @@ -1921,6 +1921,31 @@ bool BoolNode::is_counted_loop_exit_test() { return false; } +template +static const IntegerType* integral_abs_value(const IntegerType* t) { + typedef typename IntegerType::NativeUType NativeUType; + + // Find the absolute value of a type, resulting in a range that fits inside the unsigned range [0, signed_max+1]. + // The possible values of a TypeInteger is described with the following range in the signed domain: + // smin----------lo=======uhi--------0--------ulo===========hi----------smax + + // To find the absolute value of the range, we find the closer (min) value of uhi and ulo to 0, and the further (max) + // value of lo and hi from 0. In the unsigned domain, the resulting range looks like this: + // 0-----------min(|ulo|,|uhi|)================max(|lo|,|hi|)-----------umax + + // When the input range's hi and lo are both positive or negative, lo == ulo and hi == uhi: + // smin------------------------------0-------lo===========hi------------smax (Positive) + // smin--------lo===========hi-------0----------------------------------smax (Negative) + + // For these ranges, the result in the unsigned domain is simply [min(|lo|, |hi|), max(|lo|, |hi|)]: + // 0-----------min(|lo|,|hi|)==================max(|lo|,|hi|)-----------umax + + NativeUType umin = MIN2(g_uabs(t->_ulo), g_uabs(t->_uhi)); + NativeUType umax = MAX2(g_uabs(t->_lo), g_uabs(t->_hi)); + + return IntegerType::make_unsigned(umin, umax, t->_widen); +} + //============================================================================= //------------------------------Value------------------------------------------ const Type* AbsNode::Value(PhaseGVN* phase) const { @@ -1930,17 +1955,13 @@ const Type* AbsNode::Value(PhaseGVN* phase) const { switch (t1->base()) { case Type::Int: { const TypeInt* ti = t1->is_int(); - if (ti->is_con()) { - return TypeInt::make(g_uabs(ti->get_con())); - } - break; + + return integral_abs_value(ti); } case Type::Long: { const TypeLong* tl = t1->is_long(); - if (tl->is_con()) { - return TypeLong::make(g_uabs(tl->get_con())); - } - break; + + return integral_abs_value(tl); } case Type::FloatCon: return TypeF::make(abs(t1->getf())); diff --git a/src/hotspot/share/opto/type.cpp b/src/hotspot/share/opto/type.cpp index fcdf9b09fc3..a1e213319b7 100644 --- a/src/hotspot/share/opto/type.cpp +++ b/src/hotspot/share/opto/type.cpp @@ -1801,6 +1801,12 @@ const TypeInt* TypeInt::make(jint lo, jint hi, int widen) { return make_or_top(TypeIntPrototype{{lo, hi}, {0, max_juint}, {0, 0}}, widen)->is_int(); } +const TypeInt* TypeInt::make_unsigned(juint ulo, juint uhi, int widen) { + assert(ulo <= uhi, "must be legal bounds"); + // By creating the TypeInt with the full signed range and the given unsigned range, the signed bounds are inferred from the unsigned bounds. + return make_or_top(TypeIntPrototype{{min_jint, max_jint}, {ulo, uhi}, {0, 0}}, widen)->is_int(); +} + const Type* TypeInt::make_or_top(const TypeIntPrototype& t, int widen) { return make_or_top(t, widen, false); } @@ -1936,6 +1942,12 @@ const TypeLong* TypeLong::make(jlong lo, jlong hi, int widen) { return make_or_top(TypeIntPrototype{{lo, hi}, {0, max_julong}, {0, 0}}, widen)->is_long(); } +const TypeLong* TypeLong::make_unsigned(julong ulo, julong uhi, int widen) { + assert(ulo <= uhi, "must be legal bounds"); + // By creating the TypeLong with the full signed range and the given unsigned range, the signed bounds are inferred from the unsigned bounds. + return make_or_top(TypeIntPrototype{{min_jlong, max_jlong}, {ulo, uhi}, {0, 0}}, widen)->is_long(); +} + const Type* TypeLong::make_or_top(const TypeIntPrototype& t, int widen) { return make_or_top(t, widen, false); } diff --git a/src/hotspot/share/opto/type.hpp b/src/hotspot/share/opto/type.hpp index 6eaa497e86d..06201113311 100644 --- a/src/hotspot/share/opto/type.hpp +++ b/src/hotspot/share/opto/type.hpp @@ -782,6 +782,7 @@ protected: public: typedef jint NativeType; + typedef juint NativeUType; virtual bool eq(const Type* t) const; virtual uint hash() const; // Type specific hashing virtual bool singleton(void) const; // TRUE if type is a singleton @@ -795,6 +796,7 @@ public: static const TypeInt* make(jint con); // must always specify w static const TypeInt* make(jint lo, jint hi, int widen); + static const TypeInt* make_unsigned(juint ulo, juint uhi, int widen); static const Type* make_or_top(const TypeIntPrototype& t, int widen); static const TypeInt* make(const TypeIntPrototype& t, int widen) { return make_or_top(t, widen)->is_int(); } static const TypeInt* make(const TypeIntMirror& t, int widen) { @@ -871,6 +873,7 @@ protected: virtual const Type* filter_helper(const Type* kills, bool include_speculative) const; public: typedef jlong NativeType; + typedef julong NativeUType; virtual bool eq( const Type *t ) const; virtual uint hash() const; // Type specific hashing virtual bool singleton(void) const; // TRUE if type is a singleton @@ -885,6 +888,7 @@ public: static const TypeLong* make(jlong con); // must always specify w static const TypeLong* make(jlong lo, jlong hi, int widen); + static const TypeLong* make_unsigned(julong ulo, julong uhi, int widen); static const Type* make_or_top(const TypeIntPrototype& t, int widen); static const TypeLong* make(const TypeIntPrototype& t, int widen) { return make_or_top(t, widen)->is_long(); } static const TypeLong* make(const TypeIntMirror& t, int widen) { diff --git a/test/hotspot/jtreg/compiler/c2/irTests/TestIRAbs.java b/test/hotspot/jtreg/compiler/c2/irTests/TestIRAbs.java index a40c9eab12f..3dff0172143 100644 --- a/test/hotspot/jtreg/compiler/c2/irTests/TestIRAbs.java +++ b/test/hotspot/jtreg/compiler/c2/irTests/TestIRAbs.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2022, Arm Limited. All rights reserved. + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. * 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,18 +25,50 @@ package compiler.c2.irTests; import jdk.test.lib.Asserts; +import compiler.lib.generators.*; import compiler.lib.ir_framework.*; /* * @test - * @bug 8276673 8280089 + * @bug 8276673 8280089 8349563 * @summary Test abs nodes optimization in C2. - * @requires os.arch=="amd64" | os.arch=="x86_64" | os.arch=="aarch64" | os.arch=="riscv64" + * @key randomness * @library /test/lib / * @run driver compiler.c2.irTests.TestIRAbs */ public class TestIRAbs { + private static final RestrictableGenerator INTS = Generators.G.ints(); + private static final RestrictableGenerator LONGS = Generators.G.longs(); + + private static final IntRange INT_RANGE = IntRange.generate(INTS); + private static final IntRange INT_FULL_RANGE = new IntRange(Integer.MIN_VALUE, Integer.MAX_VALUE); + private static final IntRange INT_UNSIGNED_MAX = new IntRange(-1, Integer.MAX_VALUE); + private static final IntRange INT_POSITIVE = new IntRange(0, Integer.MAX_VALUE); + private static final IntRange INT_NEGATIVE = new IntRange(Integer.MIN_VALUE, 0); + private static final LongRange LONG_RANGE = LongRange.generate(LONGS); + private static final LongRange LONG_FULL_RANGE = new LongRange(Long.MIN_VALUE, Long.MAX_VALUE); + private static final LongRange LONG_UNSIGNED_MAX = new LongRange(-1, Long.MAX_VALUE); + private static final LongRange LONG_POSITIVE = new LongRange(0, Long.MAX_VALUE); + private static final LongRange LONG_NEGATIVE = new LongRange(Long.MIN_VALUE, 0); + + private static final int INT_1 = INTS.next(); + private static final int INT_2 = INTS.next(); + private static final int INT_3 = INTS.next(); + private static final int INT_4 = INTS.next(); + private static final int INT_5 = INTS.next(); + private static final int INT_6 = INTS.next(); + private static final int INT_7 = INTS.next(); + private static final int INT_8 = INTS.next(); + + private static final long LONG_1 = LONGS.next(); + private static final long LONG_2 = LONGS.next(); + private static final long LONG_3 = LONGS.next(); + private static final long LONG_4 = LONGS.next(); + private static final long LONG_5 = LONGS.next(); + private static final long LONG_6 = LONGS.next(); + private static final long LONG_7 = LONGS.next(); + private static final long LONG_8 = LONGS.next(); public static char [] cspecial = { 0, 42, 128, 256, 1024, 4096, 65535 @@ -103,7 +136,7 @@ public class TestIRAbs { } @Test - @IR(failOn = {IRNode.ABS_I, IRNode.ABS_L, IRNode.ABS_F, IRNode.ABS_D}) + @IR(failOn = {IRNode.ABS_I, IRNode.ABS_L, IRNode.ABS_F, IRNode.ABS_D}, applyIfPlatform = { "64-bit", "true" }) public void testAbsConstant() { // Test abs(constant) optimization for int Asserts.assertEquals(Integer.MAX_VALUE, Math.abs(Integer.MAX_VALUE)); @@ -160,14 +193,14 @@ public class TestIRAbs { } @Test - @IR(counts = {IRNode.ABS_L, "1"}) + @IR(counts = {IRNode.ABS_L, "1"}, applyIfPlatform = { "64-bit", "true" }) public long testLong0(long x) { return Math.abs(Math.abs(x)); // transformed to Math.abs(x) } @Test - @IR(failOn = {IRNode.SUB_L}) - @IR(counts = {IRNode.ABS_L, "1"}) + @IR(failOn = {IRNode.SUB_L}, applyIfPlatform = { "64-bit", "true" }) + @IR(counts = {IRNode.ABS_L, "1"}, applyIfPlatform = { "64-bit", "true" }) public long testLong1(long x) { return Math.abs(0 - x); // transformed to Math.abs(x) } @@ -229,4 +262,524 @@ public class TestIRAbs { Asserts.assertEquals(cspecial[i], (char) Math.abs(cspecial[i])); } } - } + + @Run(test = {"testIntRange1", "testIntRange2", "testIntRange3", "testIntRange4", + "testIntRangeFolding", "testIntFullRangeFolding", "testIntUnsignedMaxFolding", + "testIntPositiveRangeFolding", "testIntNegativeRangeFolding"}) + public void checkIntRanges(RunInfo info) { + for (int i : ispecial) { + checkIntRange(i); + } + + for (int j = 0; j < 20; j++) { + int i = INTS.next(); + checkIntRange(i); + } + } + + @DontCompile + public void checkIntRange(int i) { + Asserts.assertEquals(Math.abs((i & 7) - 4) > 4, testIntRange1(i)); + Asserts.assertEquals(Math.abs((i & 7) - 4) < 0, testIntRange2(i)); + Asserts.assertEquals(Math.abs(-((i & 7) + 2)) < 2, testIntRange3(i)); + Asserts.assertEquals(Math.abs(-((i & 7) + 2)) > 9, testIntRange4(i)); + Asserts.assertEquals(testIntRangeFoldingInterpreter(i), testIntRangeFolding(i)); + Asserts.assertEquals(testIntFullRangeFoldingInterpreter(i), testIntFullRangeFolding(i)); + Asserts.assertEquals(testIntUnsignedMaxFoldingInterpreter(i), testIntUnsignedMaxFolding(i)); + Asserts.assertEquals(testIntPositiveRangeFoldingInterpreter(i), testIntPositiveRangeFolding(i)); + Asserts.assertEquals(testIntNegativeRangeFoldingInterpreter(i), testIntNegativeRangeFolding(i)); + } + + @Run(test = {"testLongRange1", "testLongRange2", "testLongRange3", "testLongRange4", + "testLongRangeFolding", "testLongFullRangeFolding", "testLongUnsignedMaxFolding", + "testLongPositiveRangeFolding", "testLongNegativeRangeFolding"}) + public void checkLongRanges(RunInfo info) { + for (long l : lspecial) { + checkLongRange(l); + } + + for (int j = 0; j < 20; j++) { + long l = LONGS.next(); + checkLongRange(l); + } + } + + @DontCompile + public void checkLongRange(long l) { + Asserts.assertEquals(Math.abs((l & 7) - 4) > 4, testLongRange1(l)); + Asserts.assertEquals(Math.abs((l & 7) - 4) < 0, testLongRange2(l)); + Asserts.assertEquals(Math.abs(-((l & 7) + 2)) < 2, testLongRange3(l)); + Asserts.assertEquals(Math.abs(-((l & 7) + 2)) > 9, testLongRange4(l)); + Asserts.assertEquals(testLongRangeFoldingInterpreter(l), testLongRangeFolding(l)); + Asserts.assertEquals(testLongFullRangeFoldingInterpreter(l), testLongFullRangeFolding(l)); + Asserts.assertEquals(testLongUnsignedMaxFoldingInterpreter(l), testLongUnsignedMaxFolding(l)); + Asserts.assertEquals(testLongPositiveRangeFoldingInterpreter(l), testLongPositiveRangeFolding(l)); + Asserts.assertEquals(testLongNegativeRangeFoldingInterpreter(l), testLongNegativeRangeFolding(l)); + } + + // Int ranges + + @Test + @IR(failOn = { IRNode.ABS_I }) + public boolean testIntRange1(int in) { + // [-4, 3] => [0, 4] + return Math.abs((in & 7) - 4) > 4; + } + + @Test + @IR(failOn = { IRNode.ABS_I }) + public boolean testIntRange2(int in) { + // [-4, 3] => [0, 4] + return Math.abs((in & 7) - 4) < 0; + } + + @Test + @IR(failOn = { IRNode.ABS_I }) + public boolean testIntRange3(int in) { + // [-9, -2] => [2, 9] + return Math.abs(-((in & 7) + 2)) < 2; + } + + @Test + @IR(failOn = { IRNode.ABS_I }) + public boolean testIntRange4(int in) { + // [-9, -2] => [2, 9] + return Math.abs(-((in & 7) + 2)) > 9; + } + + @Test + public int testIntRangeFolding(int in) { + int c = INT_RANGE.clamp(in); + int v = Math.abs(c); + + int sum = 0; + if (v > INT_1) { sum += 1; } + if (v > INT_2) { sum += 2; } + if (v > INT_3) { sum += 4; } + if (v > INT_4) { sum += 8; } + if (v > INT_5) { sum += 16; } + if (v > INT_6) { sum += 32; } + if (v > INT_7) { sum += 64; } + if (v > INT_8) { sum += 128; } + + return sum; + } + + @DontCompile + public int testIntRangeFoldingInterpreter(int in) { + int c = INT_RANGE.clamp(in); + int v = Math.abs(c); + + int sum = 0; + if (v > INT_1) { sum += 1; } + if (v > INT_2) { sum += 2; } + if (v > INT_3) { sum += 4; } + if (v > INT_4) { sum += 8; } + if (v > INT_5) { sum += 16; } + if (v > INT_6) { sum += 32; } + if (v > INT_7) { sum += 64; } + if (v > INT_8) { sum += 128; } + + return sum; + } + + @Test + public int testIntFullRangeFolding(int in) { + int c = INT_FULL_RANGE.clamp(in); + int v = Math.abs(c); + + int sum = 0; + if (v > INT_1) { sum += 1; } + if (v > INT_2) { sum += 2; } + if (v > INT_3) { sum += 4; } + if (v > INT_4) { sum += 8; } + if (v > INT_5) { sum += 16; } + if (v > INT_6) { sum += 32; } + if (v > INT_7) { sum += 64; } + if (v > INT_8) { sum += 128; } + + return sum; + } + + @DontCompile + public int testIntFullRangeFoldingInterpreter(int in) { + int c = INT_FULL_RANGE.clamp(in); + int v = Math.abs(c); + + int sum = 0; + if (v > INT_1) { sum += 1; } + if (v > INT_2) { sum += 2; } + if (v > INT_3) { sum += 4; } + if (v > INT_4) { sum += 8; } + if (v > INT_5) { sum += 16; } + if (v > INT_6) { sum += 32; } + if (v > INT_7) { sum += 64; } + if (v > INT_8) { sum += 128; } + + return sum; + } + + @Test + public int testIntUnsignedMaxFolding(int in) { + int c = INT_UNSIGNED_MAX.clamp(in); + int v = Math.abs(c); + + int sum = 0; + if (v > INT_1) { sum += 1; } + if (v > INT_2) { sum += 2; } + if (v > INT_3) { sum += 4; } + if (v > INT_4) { sum += 8; } + if (v > INT_5) { sum += 16; } + if (v > INT_6) { sum += 32; } + if (v > INT_7) { sum += 64; } + if (v > INT_8) { sum += 128; } + + return sum; + } + + @DontCompile + public int testIntUnsignedMaxFoldingInterpreter(int in) { + int c = INT_UNSIGNED_MAX.clamp(in); + int v = Math.abs(c); + + int sum = 0; + if (v > INT_1) { sum += 1; } + if (v > INT_2) { sum += 2; } + if (v > INT_3) { sum += 4; } + if (v > INT_4) { sum += 8; } + if (v > INT_5) { sum += 16; } + if (v > INT_6) { sum += 32; } + if (v > INT_7) { sum += 64; } + if (v > INT_8) { sum += 128; } + + return sum; + } + + @Test + public int testIntPositiveRangeFolding(int in) { + int c = INT_POSITIVE.clamp(in); + int v = Math.abs(c); + + int sum = 0; + if (v > INT_1) { sum += 1; } + if (v > INT_2) { sum += 2; } + if (v > INT_3) { sum += 4; } + if (v > INT_4) { sum += 8; } + if (v > INT_5) { sum += 16; } + if (v > INT_6) { sum += 32; } + if (v > INT_7) { sum += 64; } + if (v > INT_8) { sum += 128; } + + return sum; + } + + @DontCompile + public int testIntPositiveRangeFoldingInterpreter(int in) { + int c = INT_POSITIVE.clamp(in); + int v = Math.abs(c); + + int sum = 0; + if (v > INT_1) { sum += 1; } + if (v > INT_2) { sum += 2; } + if (v > INT_3) { sum += 4; } + if (v > INT_4) { sum += 8; } + if (v > INT_5) { sum += 16; } + if (v > INT_6) { sum += 32; } + if (v > INT_7) { sum += 64; } + if (v > INT_8) { sum += 128; } + + return sum; + } + + @Test + public int testIntNegativeRangeFolding(int in) { + int c = INT_NEGATIVE.clamp(in); + int v = Math.abs(c); + + int sum = 0; + if (v > INT_1) { sum += 1; } + if (v > INT_2) { sum += 2; } + if (v > INT_3) { sum += 4; } + if (v > INT_4) { sum += 8; } + if (v > INT_5) { sum += 16; } + if (v > INT_6) { sum += 32; } + if (v > INT_7) { sum += 64; } + if (v > INT_8) { sum += 128; } + + return sum; + } + + @DontCompile + public int testIntNegativeRangeFoldingInterpreter(int in) { + int c = INT_NEGATIVE.clamp(in); + int v = Math.abs(c); + + int sum = 0; + if (v > INT_1) { sum += 1; } + if (v > INT_2) { sum += 2; } + if (v > INT_3) { sum += 4; } + if (v > INT_4) { sum += 8; } + if (v > INT_5) { sum += 16; } + if (v > INT_6) { sum += 32; } + if (v > INT_7) { sum += 64; } + if (v > INT_8) { sum += 128; } + + return sum; + } + + // Long ranges + + @Test + @IR(failOn = { IRNode.ABS_L }, applyIfPlatform = { "64-bit", "true" }) + public boolean testLongRange1(long in) { + // [-4, 3] => [0, 4] + return Math.abs((in & 7) - 4) > 4; + } + + @Test + @IR(failOn = { IRNode.ABS_L }, applyIfPlatform = { "64-bit", "true" }) + public boolean testLongRange2(long in) { + // [-4, 3] => [0, 4] + return Math.abs((in & 7) - 4) < 0; + } + + @Test + @IR(failOn = { IRNode.ABS_L }, applyIfPlatform = { "64-bit", "true" }) + public boolean testLongRange3(long in) { + // [-9, -2] => [2, 9] + return Math.abs(-((in & 7) + 2)) < 2; + } + + @Test + @IR(failOn = { IRNode.ABS_L }, applyIfPlatform = { "64-bit", "true" }) + public boolean testLongRange4(long in) { + // [-9, -2] => [2, 9] + return Math.abs(-((in & 7) + 2)) > 9; + } + + @Test + public int testLongRangeFolding(long in) { + long c = LONG_RANGE.clamp(in); + long v = Math.abs(c); + + int sum = 0; + if (v > LONG_1) { sum += 1; } + if (v > LONG_2) { sum += 2; } + if (v > LONG_3) { sum += 4; } + if (v > LONG_4) { sum += 8; } + if (v > LONG_5) { sum += 16; } + if (v > LONG_6) { sum += 32; } + if (v > LONG_7) { sum += 64; } + if (v > LONG_8) { sum += 128; } + + return sum; + } + + @DontCompile + public int testLongRangeFoldingInterpreter(long in) { + long c = LONG_RANGE.clamp(in); + long v = Math.abs(c); + + int sum = 0; + if (v > LONG_1) { sum += 1; } + if (v > LONG_2) { sum += 2; } + if (v > LONG_3) { sum += 4; } + if (v > LONG_4) { sum += 8; } + if (v > LONG_5) { sum += 16; } + if (v > LONG_6) { sum += 32; } + if (v > LONG_7) { sum += 64; } + if (v > LONG_8) { sum += 128; } + + return sum; + } + + @Test + public int testLongFullRangeFolding(long in) { + long c = LONG_FULL_RANGE.clamp(in); + long v = Math.abs(c); + + int sum = 0; + if (v > LONG_1) { sum += 1; } + if (v > LONG_2) { sum += 2; } + if (v > LONG_3) { sum += 4; } + if (v > LONG_4) { sum += 8; } + if (v > LONG_5) { sum += 16; } + if (v > LONG_6) { sum += 32; } + if (v > LONG_7) { sum += 64; } + if (v > LONG_8) { sum += 128; } + + return sum; + } + + @DontCompile + public int testLongFullRangeFoldingInterpreter(long in) { + long c = LONG_FULL_RANGE.clamp(in); + long v = Math.abs(c); + + int sum = 0; + if (v > LONG_1) { sum += 1; } + if (v > LONG_2) { sum += 2; } + if (v > LONG_3) { sum += 4; } + if (v > LONG_4) { sum += 8; } + if (v > LONG_5) { sum += 16; } + if (v > LONG_6) { sum += 32; } + if (v > LONG_7) { sum += 64; } + if (v > LONG_8) { sum += 128; } + + return sum; + } + + @Test + public int testLongUnsignedMaxFolding(long in) { + long c = LONG_UNSIGNED_MAX.clamp(in); + long v = Math.abs(c); + + int sum = 0; + if (v > LONG_1) { sum += 1; } + if (v > LONG_2) { sum += 2; } + if (v > LONG_3) { sum += 4; } + if (v > LONG_4) { sum += 8; } + if (v > LONG_5) { sum += 16; } + if (v > LONG_6) { sum += 32; } + if (v > LONG_7) { sum += 64; } + if (v > LONG_8) { sum += 128; } + + return sum; + } + + @DontCompile + public int testLongUnsignedMaxFoldingInterpreter(long in) { + long c = LONG_UNSIGNED_MAX.clamp(in); + long v = Math.abs(c); + + int sum = 0; + if (v > LONG_1) { sum += 1; } + if (v > LONG_2) { sum += 2; } + if (v > LONG_3) { sum += 4; } + if (v > LONG_4) { sum += 8; } + if (v > LONG_5) { sum += 16; } + if (v > LONG_6) { sum += 32; } + if (v > LONG_7) { sum += 64; } + if (v > LONG_8) { sum += 128; } + + return sum; + } + + @Test + public int testLongPositiveRangeFolding(long in) { + long c = LONG_POSITIVE.clamp(in); + long v = Math.abs(c); + + int sum = 0; + if (v > LONG_1) { sum += 1; } + if (v > LONG_2) { sum += 2; } + if (v > LONG_3) { sum += 4; } + if (v > LONG_4) { sum += 8; } + if (v > LONG_5) { sum += 16; } + if (v > LONG_6) { sum += 32; } + if (v > LONG_7) { sum += 64; } + if (v > LONG_8) { sum += 128; } + + return sum; + } + + @DontCompile + public int testLongPositiveRangeFoldingInterpreter(long in) { + long c = LONG_POSITIVE.clamp(in); + long v = Math.abs(c); + + int sum = 0; + if (v > LONG_1) { sum += 1; } + if (v > LONG_2) { sum += 2; } + if (v > LONG_3) { sum += 4; } + if (v > LONG_4) { sum += 8; } + if (v > LONG_5) { sum += 16; } + if (v > LONG_6) { sum += 32; } + if (v > LONG_7) { sum += 64; } + if (v > LONG_8) { sum += 128; } + + return sum; + } + + @Test + public int testLongNegativeRangeFolding(long in) { + long c = LONG_NEGATIVE.clamp(in); + long v = Math.abs(c); + + int sum = 0; + if (v > LONG_1) { sum += 1; } + if (v > LONG_2) { sum += 2; } + if (v > LONG_3) { sum += 4; } + if (v > LONG_4) { sum += 8; } + if (v > LONG_5) { sum += 16; } + if (v > LONG_6) { sum += 32; } + if (v > LONG_7) { sum += 64; } + if (v > LONG_8) { sum += 128; } + + return sum; + } + + @DontCompile + public int testLongNegativeRangeFoldingInterpreter(long in) { + long c = LONG_NEGATIVE.clamp(in); + long v = Math.abs(c); + + int sum = 0; + if (v > LONG_1) { sum += 1; } + if (v > LONG_2) { sum += 2; } + if (v > LONG_3) { sum += 4; } + if (v > LONG_4) { sum += 8; } + if (v > LONG_5) { sum += 16; } + if (v > LONG_6) { sum += 32; } + if (v > LONG_7) { sum += 64; } + if (v > LONG_8) { sum += 128; } + + return sum; + } + + record IntRange(int lo, int hi) { + IntRange { + if (lo > hi) { + throw new IllegalArgumentException("lo > hi"); + } + } + + int clamp(int v) { + return Math.min(hi, Math.max(v, lo)); + } + + static IntRange generate(Generator g) { + var a = g.next(); + var b = g.next(); + if (a > b) { + var tmp = a; + a = b; + b = tmp; + } + return new IntRange(a, b); + } + } + + record LongRange(long lo, long hi) { + LongRange { + if (lo > hi) { + throw new IllegalArgumentException("lo > hi"); + } + } + + long clamp(long v) { + return Math.min(hi, Math.max(v, lo)); + } + + static LongRange generate(Generator g) { + var a = g.next(); + var b = g.next(); + if (a > b) { + var tmp = a; + a = b; + b = tmp; + } + return new LongRange(a, b); + } + } +} From 4b3ec455c85314d051800a8f46dd8f5c93881e3a Mon Sep 17 00:00:00 2001 From: Albert Mingkun Yang Date: Wed, 10 Jun 2026 06:55:22 +0000 Subject: [PATCH 13/20] 8386098: Add empty MemRegion precondition to CardTable methods Reviewed-by: tschatzl, iwalulya, jsikstro --- src/hotspot/share/gc/shared/cardTable.cpp | 2 ++ src/hotspot/share/gc/shared/cardTableBarrierSet.inline.hpp | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/hotspot/share/gc/shared/cardTable.cpp b/src/hotspot/share/gc/shared/cardTable.cpp index e6e3fdf3d82..dcf13ab48e9 100644 --- a/src/hotspot/share/gc/shared/cardTable.cpp +++ b/src/hotspot/share/gc/shared/cardTable.cpp @@ -194,6 +194,7 @@ void CardTable::resize_covered_region(MemRegion new_region) { // Note that these versions are precise! The scanning code has to handle the // fact that the write barrier may be either precise or imprecise. void CardTable::dirty_MemRegion(MemRegion mr) { + assert(!mr.is_empty(), "precondition"); assert(align_down(mr.start(), HeapWordSize) == mr.start(), "Unaligned start"); assert(align_up (mr.end(), HeapWordSize) == mr.end(), "Unaligned end" ); assert(_covered[0].contains(mr) || _covered[1].contains(mr), "precondition"); @@ -203,6 +204,7 @@ void CardTable::dirty_MemRegion(MemRegion mr) { } void CardTable::clear_MemRegion(MemRegion mr) { + assert(!mr.is_empty(), "precondition"); // Be conservative: only clean cards entirely contained within the // region. CardValue* cur; diff --git a/src/hotspot/share/gc/shared/cardTableBarrierSet.inline.hpp b/src/hotspot/share/gc/shared/cardTableBarrierSet.inline.hpp index f60a7f47a19..5c10a1618a5 100644 --- a/src/hotspot/share/gc/shared/cardTableBarrierSet.inline.hpp +++ b/src/hotspot/share/gc/shared/cardTableBarrierSet.inline.hpp @@ -130,7 +130,10 @@ oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw, // pointer delta is scaled to number of elements (length field in // objArrayOop) which we assume is 32 bit. assert(pd == (size_t)(int)pd, "length field overflow"); - bs->write_ref_array((HeapWord*)dst_raw, pd); + if (pd > 0) { + // Copied at least one element; call the barrier. + bs->write_ref_array((HeapWord*)dst_raw, pd); + } return OopCopyResult::failed_check_class_cast; } } From 8630517d18c88775afe3f1f5d50d22b66f107f05 Mon Sep 17 00:00:00 2001 From: Ivan Walulya Date: Wed, 10 Jun 2026 08:18:12 +0000 Subject: [PATCH 14/20] 8386254: Parallel: Adjust Pointers should use stripes in young spaces Reviewed-by: ayang, tschatzl --- .../share/gc/parallel/psParallelCompact.cpp | 72 +++++++++---------- .../share/gc/parallel/psParallelCompact.hpp | 7 +- 2 files changed, 37 insertions(+), 42 deletions(-) diff --git a/src/hotspot/share/gc/parallel/psParallelCompact.cpp b/src/hotspot/share/gc/parallel/psParallelCompact.cpp index a4a2bfe72c2..ff757f205a2 100644 --- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp +++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp @@ -1268,8 +1268,7 @@ void PSParallelCompact::marking_phase(ParallelOldTracer *gc_tracer) { #endif } -template -void PSParallelCompact::adjust_in_space_helper(SpaceId id, Atomic* claim_counter, Func&& on_stripe) { +void PSParallelCompact::adjust_in_space_helper(SpaceId id, Atomic* claim_counter) { MutableSpace* sp = PSParallelCompact::space(id); HeapWord* const bottom = sp->bottom(); HeapWord* const top = sp->top(); @@ -1288,53 +1287,46 @@ void PSParallelCompact::adjust_in_space_helper(SpaceId id, Atomic* claim_c break; } HeapWord* stripe_end = MIN2(cur_stripe + stripe_size, top); - on_stripe(cur_stripe, stripe_end); + adjust_in_stripe(cur_stripe, stripe_end); + } +} + +size_t PSParallelCompact::adjust_in_obj_with_limit(HeapWord* obj_start, HeapWord* left, HeapWord* right) { + precond(mark_bitmap()->is_marked(obj_start)); + oop obj = cast_to_oop(obj_start); + return obj->oop_iterate_size(&pc_adjust_pointer_closure, MemRegion(left, right)); +} + +void PSParallelCompact::adjust_in_stripe(HeapWord* stripe_start, HeapWord* stripe_end) { + precond(_summary_data.is_region_aligned(stripe_start)); + + RegionData* cur_region = _summary_data.addr_to_region_ptr(stripe_start); + HeapWord* obj_start; + if (cur_region->partial_obj_size() != 0) { + obj_start = cur_region->partial_obj_addr(); + obj_start += adjust_in_obj_with_limit(obj_start, stripe_start, stripe_end); + } else { + obj_start = stripe_start; + } + + while (obj_start < stripe_end) { + obj_start = mark_bitmap()->find_obj_beg(obj_start, stripe_end); + if (obj_start >= stripe_end) { + break; + } + obj_start += adjust_in_obj_with_limit(obj_start, stripe_start, stripe_end); } } void PSParallelCompact::adjust_in_old_space(Atomic* claim_counter) { // Regions in old-space shouldn't be split. - assert(!_space_info[old_space_id].split_info().is_valid(), "inv"); + precond(!_space_info[old_space_id].split_info().is_valid()); - auto scan_obj_with_limit = [&] (HeapWord* obj_start, HeapWord* left, HeapWord* right) { - assert(mark_bitmap()->is_marked(obj_start), "inv"); - oop obj = cast_to_oop(obj_start); - return obj->oop_iterate_size(&pc_adjust_pointer_closure, MemRegion(left, right)); - }; - - adjust_in_space_helper(old_space_id, claim_counter, [&] (HeapWord* stripe_start, HeapWord* stripe_end) { - assert(_summary_data.is_region_aligned(stripe_start), "inv"); - RegionData* cur_region = _summary_data.addr_to_region_ptr(stripe_start); - HeapWord* obj_start; - if (cur_region->partial_obj_size() != 0) { - obj_start = cur_region->partial_obj_addr(); - obj_start += scan_obj_with_limit(obj_start, stripe_start, stripe_end); - } else { - obj_start = stripe_start; - } - - while (obj_start < stripe_end) { - obj_start = mark_bitmap()->find_obj_beg(obj_start, stripe_end); - if (obj_start >= stripe_end) { - break; - } - obj_start += scan_obj_with_limit(obj_start, stripe_start, stripe_end); - } - }); + adjust_in_space_helper(old_space_id, claim_counter); } void PSParallelCompact::adjust_in_young_space(SpaceId id, Atomic* claim_counter) { - adjust_in_space_helper(id, claim_counter, [](HeapWord* stripe_start, HeapWord* stripe_end) { - HeapWord* obj_start = stripe_start; - while (obj_start < stripe_end) { - obj_start = mark_bitmap()->find_obj_beg(obj_start, stripe_end); - if (obj_start >= stripe_end) { - break; - } - oop obj = cast_to_oop(obj_start); - obj_start += obj->oop_iterate_size(&pc_adjust_pointer_closure); - } - }); + adjust_in_space_helper(id, claim_counter); } void PSParallelCompact::adjust_pointers_in_spaces(uint worker_id, Atomic* claim_counters) { diff --git a/src/hotspot/share/gc/parallel/psParallelCompact.hpp b/src/hotspot/share/gc/parallel/psParallelCompact.hpp index 25f4f66de6f..909005f5360 100644 --- a/src/hotspot/share/gc/parallel/psParallelCompact.hpp +++ b/src/hotspot/share/gc/parallel/psParallelCompact.hpp @@ -760,8 +760,11 @@ public: // should_do_max_compaction controls whether all spaces for dead objs should be reclaimed. static bool invoke(bool clear_all_soft_refs, bool should_do_max_compaction); - template - static void adjust_in_space_helper(SpaceId id, Atomic* claim_counter, Func&& on_stripe); + static void adjust_in_space_helper(SpaceId id, Atomic* claim_counter); + + static size_t adjust_in_obj_with_limit(HeapWord* obj_start, HeapWord* left, HeapWord* right); + + static void adjust_in_stripe(HeapWord* stripe_start, HeapWord* stripe_end); static void adjust_in_old_space(Atomic* claim_counter); From 83495ebe78cff5d7f9422b40f023c16570fc1881 Mon Sep 17 00:00:00 2001 From: Gui Cao Date: Wed, 10 Jun 2026 08:43:57 +0000 Subject: [PATCH 15/20] 8386161: RISC-V: Auto-enable Zvkn/Zvkg extension features Reviewed-by: fyang, dzhang --- src/hotspot/cpu/riscv/globals_riscv.hpp | 6 +++--- src/hotspot/os_cpu/linux_riscv/riscv_hwprobe.cpp | 4 +--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/hotspot/cpu/riscv/globals_riscv.hpp b/src/hotspot/cpu/riscv/globals_riscv.hpp index 18ca120bdfa..f05b9ff7791 100644 --- a/src/hotspot/cpu/riscv/globals_riscv.hpp +++ b/src/hotspot/cpu/riscv/globals_riscv.hpp @@ -120,10 +120,10 @@ define_pd_global(intx, InlineSmallCode, 1000); product(bool, UseZvbb, false, EXPERIMENTAL, "Use Zvbb instructions") \ product(bool, UseZvbc, false, EXPERIMENTAL, "Use Zvbc instructions") \ product(bool, UseZvfh, false, DIAGNOSTIC, "Use Zvfh instructions") \ - product(bool, UseZvkn, false, EXPERIMENTAL, \ + product(bool, UseZvkg, false, DIAGNOSTIC, "Use Zvkg instructions") \ + product(bool, UseZvkn, false, DIAGNOSTIC, \ "Use Zvkn group extension, Zvkned, Zvknhb, Zvkb, Zvkt") \ product(bool, UseCtxFencei, false, EXPERIMENTAL, \ - "Use PR_RISCV_CTX_SW_FENCEI_ON to avoid explicit icache flush") \ - product(bool, UseZvkg, false, EXPERIMENTAL, "Use Zvkg instructions") + "Use PR_RISCV_CTX_SW_FENCEI_ON to avoid explicit icache flush") #endif // CPU_RISCV_GLOBALS_RISCV_HPP diff --git a/src/hotspot/os_cpu/linux_riscv/riscv_hwprobe.cpp b/src/hotspot/os_cpu/linux_riscv/riscv_hwprobe.cpp index 253f460dca3..a3bd1bfa870 100644 --- a/src/hotspot/os_cpu/linux_riscv/riscv_hwprobe.cpp +++ b/src/hotspot/os_cpu/linux_riscv/riscv_hwprobe.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2023, Rivos Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -249,7 +249,6 @@ void RiscvHwprobe::add_features_from_query_result() { if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZVFH)) { VM_Version::ext_Zvfh.enable_feature(); } -#ifndef PRODUCT if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZVKNED) && is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZVKNHB) && is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZVKB) && @@ -259,7 +258,6 @@ void RiscvHwprobe::add_features_from_query_result() { if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZVKG)) { VM_Version::ext_Zvkg.enable_feature(); } -#endif // ====== non-extensions ====== // From e2bdec187e1662a5458ae8d93f0f336f1f1af28c Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Wed, 10 Jun 2026 10:13:43 +0000 Subject: [PATCH 16/20] 8386252: Shenandoah: Polish LRB argument preparation Reviewed-by: mdoerr, fyang --- .../shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp | 9 +++------ .../gc/shenandoah/shenandoahBarrierSetAssembler_ppc.cpp | 9 +++------ .../shenandoah/shenandoahBarrierSetAssembler_riscv.cpp | 9 +++------ 3 files changed, 9 insertions(+), 18 deletions(-) diff --git a/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp index 7731290c801..c590b6699c0 100644 --- a/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp @@ -976,12 +976,9 @@ void ShenandoahBarrierStubC2::lrb(MacroAssembler& masm) { if (c_rarg0 == _obj) { __ lea(c_rarg1, _addr); } else if (c_rarg1 == _obj) { - // Set up arguments in reverse, and then flip them - __ lea(c_rarg0, _addr); - // flip them - __ mov(_tmp1, c_rarg0); - __ mov(c_rarg0, c_rarg1); - __ mov(c_rarg1, _tmp1); + __ mov(_tmp1, c_rarg1); + __ lea(c_rarg1, _addr); + __ mov(c_rarg0, _tmp1); } else { assert_different_registers(c_rarg1, _obj); __ lea(c_rarg1, _addr); diff --git a/src/hotspot/cpu/ppc/gc/shenandoah/shenandoahBarrierSetAssembler_ppc.cpp b/src/hotspot/cpu/ppc/gc/shenandoah/shenandoahBarrierSetAssembler_ppc.cpp index 823ff175379..582327282fd 100644 --- a/src/hotspot/cpu/ppc/gc/shenandoah/shenandoahBarrierSetAssembler_ppc.cpp +++ b/src/hotspot/cpu/ppc/gc/shenandoah/shenandoahBarrierSetAssembler_ppc.cpp @@ -1210,12 +1210,9 @@ void ShenandoahBarrierStubC2::lrb(MacroAssembler& masm) { if (c_rarg0 == _obj) { __ addi(c_rarg1, _addr.base(), _addr.disp()); } else if (c_rarg1 == _obj) { - // Set up arguments in reverse, and then flip them - __ addi(c_rarg0, _addr.base(), _addr.disp()); - // flip them - __ mr(_tmp1, c_rarg0); - __ mr(c_rarg0, c_rarg1); - __ mr(c_rarg1, _tmp1); + __ mr(_tmp1, c_rarg1); + __ addi(c_rarg1, _addr.base(), _addr.disp()); + __ mr(c_rarg0, _tmp1); } else { assert_different_registers(c_rarg1, _obj); __ addi(c_rarg1, _addr.base(), _addr.disp()); diff --git a/src/hotspot/cpu/riscv/gc/shenandoah/shenandoahBarrierSetAssembler_riscv.cpp b/src/hotspot/cpu/riscv/gc/shenandoah/shenandoahBarrierSetAssembler_riscv.cpp index d30592d68f1..eec5f9a5165 100644 --- a/src/hotspot/cpu/riscv/gc/shenandoah/shenandoahBarrierSetAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/gc/shenandoah/shenandoahBarrierSetAssembler_riscv.cpp @@ -912,12 +912,9 @@ void ShenandoahBarrierStubC2::lrb(MacroAssembler& masm) { if (c_rarg0 == _obj) { __ la(c_rarg1, _addr); } else if (c_rarg1 == _obj) { - // Set up arguments in reverse, and then flip them - __ la(c_rarg0, _addr); - // flip them - __ mv(_tmp1, c_rarg0); - __ mv(c_rarg0, c_rarg1); - __ mv(c_rarg1, _tmp1); + __ mv(_tmp1, c_rarg1); + __ la(c_rarg1, _addr); + __ mv(c_rarg0, _tmp1); } else { assert_different_registers(c_rarg1, _obj); __ la(c_rarg1, _addr); From 0fe051d305a8673c1c86e051012fff5f4fc04a83 Mon Sep 17 00:00:00 2001 From: Ivan Bereziuk Date: Wed, 10 Jun 2026 16:27:24 +0000 Subject: [PATCH 17/20] 8385427: Make unified logging checks in tests tolerant of added spaces Reviewed-by: dholmes, iklam --- .../runtime/ClassFile/PreviewVersion.java | 4 +-- .../jtreg/runtime/NMT/MallocLimitTest.java | 20 +++++++------- .../cds/appcds/LambdaProxyClasslist.java | 4 +-- .../cds/appcds/LambdaWithOldClass.java | 4 +-- .../runtime/cds/appcds/ProhibitedPackage.java | 4 +-- .../cds/appcds/aotCache/AOTLoggingTag.java | 10 +++---- .../cds/appcds/aotClassLinking/AddOpens.java | 8 +++--- .../appcds/customLoader/OldClassAndInf.java | 4 +-- .../dynamicArchive/ArchivedSuperIf.java | 4 +-- .../appcds/dynamicArchive/JFRDynamicCDS.java | 4 +-- .../dynamicArchive/LambdaContainsOldInf.java | 4 +-- .../appcds/dynamicArchive/MainModuleOnly.java | 2 +- .../classpathtests/BootAppendTests.java | 2 +- .../appcds/jigsaw/modulepath/AddModules.java | 10 +++---- .../jigsaw/modulepath/ModulePathAndCP.java | 8 +++--- .../OldClassAndRedefineClass.java | 8 +++--- .../jni/mutateFinals/MutateFinalsTest.java | 6 ++--- .../logging/ClassInitializationTest.java | 4 +-- .../jtreg/runtime/logging/CondyIndyTest.java | 26 +++++++++---------- .../jtreg/runtime/logging/ExceptionsTest.java | 4 +-- .../runtime/logging/GenerateOopMapTest.java | 4 +-- .../jtreg/runtime/logging/StackWalkTest.java | 4 +-- .../runtime/logging/StartupTimeTest.java | 4 +-- .../runtime/logging/VerificationTest.java | 14 +++++----- .../PatchModule/PatchModuleTraceCL.java | 10 +++---- .../os/THPsInThreadStackPreventionTest.java | 6 ++--- .../os/TestHugePageDecisionsAtVMStartup.java | 20 +++++++------- .../jtreg/runtime/os/TestTrimNative.java | 4 +-- .../dcmd/gc/HeapDumpParallelTest.java | 5 ++-- .../jdk/jfr/jcmd/TestJcmdChangeLogLevel.java | 7 ++--- test/jdk/jdk/jfr/jcmd/TestJcmdConfigure.java | 8 +++--- .../jfr/startupargs/TestStartupMessage.java | 6 ++--- 32 files changed, 118 insertions(+), 114 deletions(-) diff --git a/test/hotspot/jtreg/runtime/ClassFile/PreviewVersion.java b/test/hotspot/jtreg/runtime/ClassFile/PreviewVersion.java index 9e3ae8de832..f58a287a895 100644 --- a/test/hotspot/jtreg/runtime/ClassFile/PreviewVersion.java +++ b/test/hotspot/jtreg/runtime/ClassFile/PreviewVersion.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -71,7 +71,7 @@ public class PreviewVersion { pb = ProcessTools.createLimitedTestJavaProcessBuilder("--enable-preview", "-Xlog:class+preview", "-cp", "." + File.pathSeparator + System.getProperty("test.classes"), "PVTest"); oa = new OutputAnalyzer(pb.start()); - oa.shouldContain("[info][class,preview] Loading class PVTest that depends on preview features"); + oa.shouldMatch("\\[info *\\]\\[class,preview *\\] Loading class PVTest that depends on preview features"); oa.shouldHaveExitValue(0); // Subtract 1 from class's major version. The class should fail to load diff --git a/test/hotspot/jtreg/runtime/NMT/MallocLimitTest.java b/test/hotspot/jtreg/runtime/NMT/MallocLimitTest.java index 8b711304a99..14832e833e1 100644 --- a/test/hotspot/jtreg/runtime/NMT/MallocLimitTest.java +++ b/test/hotspot/jtreg/runtime/NMT/MallocLimitTest.java @@ -1,6 +1,6 @@ /* * Copyright (c) 2022 SAP SE. All rights reserved. - * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -106,7 +106,7 @@ public class MallocLimitTest { ProcessBuilder pb = processBuilderWithSetting("-XX:MallocLimit=1m"); OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldNotHaveExitValue(0); - output.shouldContain("[nmt] MallocLimit: total limit: 1024K (fatal)"); + output.shouldMatch("\\[nmt *\\] MallocLimit: total limit: 1024K \\(fatal\\)"); output.shouldMatch("# fatal error: MallocLimit: reached global limit \\(triggering allocation size: \\d+[BKM], allocated so far: \\d+[BKM], limit: 1024K\\)"); } @@ -114,8 +114,8 @@ public class MallocLimitTest { ProcessBuilder pb = processBuilderWithSetting("-XX:MallocLimit=1m:oom"); OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldNotHaveExitValue(0); - output.shouldContain("[nmt] MallocLimit: total limit: 1024K (oom)"); - output.shouldMatch(".*\\[warning\\]\\[nmt\\] MallocLimit: reached global limit \\(triggering allocation size: \\d+[BKM], allocated so far: \\d+[BKM], limit: 1024K\\)"); + output.shouldMatch("\\[nmt *\\] MallocLimit: total limit: 1024K \\(oom\\)"); + output.shouldMatch("\\[warning\\]\\[nmt *\\] MallocLimit: reached global limit \\(triggering allocation size: \\d+[BKM], allocated so far: \\d+[BKM], limit: 1024K\\)"); // The rest is fuzzy. We may get SIGSEGV or a native OOM message, depending on how the failing allocation was handled. } @@ -123,7 +123,7 @@ public class MallocLimitTest { ProcessBuilder pb = processBuilderWithSetting("-XX:MallocLimit=compiler:1234k", "-Xcomp"); OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldNotHaveExitValue(0); - output.shouldContain("[nmt] MallocLimit: category \"mtCompiler\" limit: 1234K (fatal)"); + output.shouldMatch("\\[nmt *\\] MallocLimit: category \"mtCompiler\" limit: 1234K \\(fatal\\)"); output.shouldMatch("# fatal error: MallocLimit: reached category \"mtCompiler\" limit \\(triggering allocation size: \\d+[BKM], allocated so far: \\d+[BKM], limit: 1234K\\)"); } @@ -131,8 +131,8 @@ public class MallocLimitTest { ProcessBuilder pb = processBuilderWithSetting("-XX:MallocLimit=compiler:1234k:oom", "-Xcomp"); OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldNotHaveExitValue(0); - output.shouldContain("[nmt] MallocLimit: category \"mtCompiler\" limit: 1234K (oom)"); - output.shouldMatch(".*\\[warning\\]\\[nmt\\] MallocLimit: reached category \"mtCompiler\" limit \\(triggering allocation size: \\d+[BKM], allocated so far: \\d+[BKM], limit: 1234K\\)"); + output.shouldMatch("\\[nmt *\\] MallocLimit: category \"mtCompiler\" limit: 1234K \\(oom\\)"); + output.shouldMatch("\\[warning\\]\\[nmt *\\] MallocLimit: reached category \"mtCompiler\" limit \\(triggering allocation size: \\d+[BKM], allocated so far: \\d+[BKM], limit: 1234K\\)"); // The rest is fuzzy. We may get SIGSEGV or a native OOM message, depending on how the failing allocation was handled. } @@ -140,9 +140,9 @@ public class MallocLimitTest { ProcessBuilder pb = processBuilderWithSetting("-XX:MallocLimit=other:2g,compiler:1g:oom,internal:1k"); OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldNotHaveExitValue(0); - output.shouldContain("[nmt] MallocLimit: category \"mtCompiler\" limit: 1024M (oom)"); - output.shouldContain("[nmt] MallocLimit: category \"mtInternal\" limit: 1024B (fatal)"); - output.shouldContain("[nmt] MallocLimit: category \"mtOther\" limit: 2048M (fatal)"); + output.shouldMatch("\\[nmt *\\] MallocLimit: category \"mtCompiler\" limit: 1024M \\(oom\\)"); + output.shouldMatch("\\[nmt *\\] MallocLimit: category \"mtInternal\" limit: 1024B \\(fatal\\)"); + output.shouldMatch("\\[nmt *\\] MallocLimit: category \"mtOther\" limit: 2048M \\(fatal\\)"); output.shouldMatch("# fatal error: MallocLimit: reached category \"mtInternal\" limit \\(triggering allocation size: \\d+[BKM], allocated so far: \\d+[BKM], limit: 1024B\\)"); } diff --git a/test/hotspot/jtreg/runtime/cds/appcds/LambdaProxyClasslist.java b/test/hotspot/jtreg/runtime/cds/appcds/LambdaProxyClasslist.java index adafa0d9c69..db431b180eb 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/LambdaProxyClasslist.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/LambdaProxyClasslist.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -59,7 +59,7 @@ public class LambdaProxyClasslist { out = TestCommon.dump(appJar, TestCommon.list("LambHello", "@lambda-proxy LambHello run ()Ljava/lang/Runnable; ()V REF_invokeStatic LambHello lambda$doTest$0 ()V ()Z")); - out.shouldContain("[warning][cds] No invoke dynamic constant pool entry can be found for class LambHello. The classlist is probably out-of-date.") + out.shouldMatch("\\[warning\\]\\[cds *\\] No invoke dynamic constant pool entry can be found for class LambHello\\. The classlist is probably out-of-date\\.") .shouldHaveExitValue(0); // 4. More blank spaces in between items should be fine. diff --git a/test/hotspot/jtreg/runtime/cds/appcds/LambdaWithOldClass.java b/test/hotspot/jtreg/runtime/cds/appcds/LambdaWithOldClass.java index d7ce22e3cf1..796437c0474 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/LambdaWithOldClass.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/LambdaWithOldClass.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -67,7 +67,7 @@ public class LambdaWithOldClass { .setUseVersion(false) .addSuffix(mainClass); OutputAnalyzer output = CDSTestUtils.runWithArchive(runOpts); - output.shouldContain("[class,load] LambdaWithOldClassApp source: shared objects file") + output.shouldMatch("\\[class,load *\\] LambdaWithOldClassApp source: shared objects file") .shouldHaveExitValue(0); if (!CDSTestUtils.isAOTClassLinkingEnabled()) { // With AOTClassLinking, we don't archive any lambda with old classes in the method diff --git a/test/hotspot/jtreg/runtime/cds/appcds/ProhibitedPackage.java b/test/hotspot/jtreg/runtime/cds/appcds/ProhibitedPackage.java index ea69d2db3cd..be5175e6d6a 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/ProhibitedPackage.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/ProhibitedPackage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -65,7 +65,7 @@ public class ProhibitedPackage { TestCommon.list("java/lang/Prohibited", "ProhibitedHelper"), "-Xlog:class+load") .shouldContain("Dumping") - .shouldNotContain("[info][class,load] java.lang.Prohibited source: ") + .shouldNotMatch("\\[info *\\]\\[class,load *\\] java.lang.Prohibited source: ") .shouldHaveExitValue(0); // Try loading the class in a prohibited package with various -Xshare diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/AOTLoggingTag.java b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/AOTLoggingTag.java index 4cc6ef81c45..864ce88cd11 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/AOTLoggingTag.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/AOTLoggingTag.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -58,7 +58,7 @@ public class AOTLoggingTag { "-cp", appJar, helloClass); out = CDSTestUtils.executeAndLog(pb, "train"); - out.shouldContain("[aot] Writing binary AOTConfiguration file:"); + out.shouldMatch("\\[aot *\\] Writing binary AOTConfiguration file:"); out.shouldHaveExitValue(0); //---------------------------------------------------------------------- @@ -70,7 +70,7 @@ public class AOTLoggingTag { "-Xlog:aot", "-cp", appJar); out = CDSTestUtils.executeAndLog(pb, "asm"); - out.shouldContain("[aot] Opened AOT configuration file hello.aotconfig"); + out.shouldMatch("\\[aot *\\] Opened AOT configuration file hello\\.aotconfig"); out.shouldHaveExitValue(0); //---------------------------------------------------------------------- @@ -80,7 +80,7 @@ public class AOTLoggingTag { "-Xlog:aot", "-cp", appJar, helloClass); out = CDSTestUtils.executeAndLog(pb, "prod"); - out.shouldContain("[aot] Opened AOT cache hello.aot"); + out.shouldMatch("\\[aot *\\] Opened AOT cache hello\\.aot"); out.shouldHaveExitValue(0); //---------------------------------------------------------------------- @@ -90,7 +90,7 @@ public class AOTLoggingTag { "-XX:AOTMode=on", "-cp", appJar, helloClass); out = CDSTestUtils.executeAndLog(pb, "prod"); - out.shouldContain("[aot] An error has occurred while processing the AOT cache. Run with -Xlog:aot for details."); + out.shouldMatch("\\[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/aotClassLinking/AddOpens.java b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AddOpens.java index f7e15f8fae0..694e653676e 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AddOpens.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AddOpens.java @@ -67,7 +67,7 @@ public class AddOpens { {{"-Xlog:cds", "-Xlog:cds"}, {"--add-opens", addOpensArg}}; private static String expectedOutput[] = - { "[class,load] com.simple.Main source: shared objects file", + { "\\[class,load *\\] com\\.simple\\.Main source: shared objects file", "method.setAccessible succeeded!"}; public static void buildTestModule() throws Exception { @@ -103,7 +103,7 @@ public class AddOpens { out.shouldContain("Full module graph = enabled"); }) .setProductionChecker((OutputAnalyzer out) -> { - out.shouldContain(expectedOutput[0]); + out.shouldMatch(expectedOutput[0]); out.shouldContain(expectedOutput[1]); }) .runStaticWorkflow() @@ -154,7 +154,7 @@ public class AddOpens { @Override public void checkExecution(OutputAnalyzer out, RunMode runMode) throws Exception { if (runMode == RunMode.PRODUCTION) { - out.shouldContain(expectedOutput[0]); + out.shouldMatch(expectedOutput[0]); out.shouldContain(expectedOutput[1]); } else if (runMode == RunMode.ASSEMBLY) { out.shouldMatch("(full module graph: enabled)|(Full module graph = enabled)"); @@ -197,7 +197,7 @@ public class AddOpens { @Override public void checkExecution(OutputAnalyzer out, RunMode runMode) throws Exception { if (runMode == RunMode.PRODUCTION) { - out.shouldContain(expectedOutput[0]); + out.shouldMatch(expectedOutput[0]); out.shouldContain(expectedOutput[1]); } else if (runMode == RunMode.ASSEMBLY) { out.shouldMatch("(full module graph: enabled)|(Full module graph = enabled)"); diff --git a/test/hotspot/jtreg/runtime/cds/appcds/customLoader/OldClassAndInf.java b/test/hotspot/jtreg/runtime/cds/appcds/customLoader/OldClassAndInf.java index ea5acef8551..eb7f1dbf11f 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/customLoader/OldClassAndInf.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/customLoader/OldClassAndInf.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -92,7 +92,7 @@ public class OldClassAndInf { TestCommon.checkExec(output); for (String loadee : loadees) { - output.shouldContain("[class,load] " + loadee + " source: shared objects file"); + output.shouldMatch("\\[class,load *\\] " + loadee + " source: shared objects file"); } } } diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/ArchivedSuperIf.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/ArchivedSuperIf.java index b46b48efb62..28d8043cde0 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/ArchivedSuperIf.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/ArchivedSuperIf.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -74,7 +74,7 @@ public class ArchivedSuperIf extends DynamicArchiveTestBase { .assertNormalExit(output -> { // The interface Bar will be loaded from the archive. // The class (Baz) which implements Bar will be loaded from jar. - output.shouldContain("[class,load] pkg.Bar source: shared objects file (top)") + output.shouldMatch("\\[class,load *\\] pkg\\.Bar source: shared objects file \\(top\\)") .shouldMatch(".class.load. pkg.Baz source:.*archived_super_if.jar") .shouldHaveExitValue(0); }); diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/JFRDynamicCDS.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/JFRDynamicCDS.java index 7abfd11b914..c6c30c164a1 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/JFRDynamicCDS.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/JFRDynamicCDS.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved. * 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,7 +62,7 @@ public class JFRDynamicCDS extends DynamicArchiveTestBase { .assertNormalExit(output -> { output.shouldHaveExitValue(0) .shouldMatch(".class.load. jdk.jfr.events.*source:.*jrt:/jdk.jfr") - .shouldContain("[class,load] JFRDynamicCDSApp source: shared objects file (top)"); + .shouldMatch("\\[class,load *\\] JFRDynamicCDSApp source: shared objects file \\(top\\)"); }); } } diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/LambdaContainsOldInf.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/LambdaContainsOldInf.java index 9845fd9549b..5ff65f85493 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/LambdaContainsOldInf.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/LambdaContainsOldInf.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -76,7 +76,7 @@ public class LambdaContainsOldInf extends DynamicArchiveTestBase { "-Xlog:class+load=debug", "-cp", appJar, mainClass, mainArg) .assertNormalExit(output -> { - output.shouldContain("[class,load] LambdaContainsOldInfApp source: shared objects file (top)") + output.shouldMatch("\\[class,load *\\] LambdaContainsOldInfApp source: shared objects file \\(top\\)") .shouldMatch(".class.load. OldProvider.source:.*lambda_contains_old_inf.jar") .shouldMatch(".class.load. LambdaContainsOldInfApp[$][$]Lambda.*/0x.*source:.*LambdaContainsOldInf") .shouldHaveExitValue(0); diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/MainModuleOnly.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/MainModuleOnly.java index a43888c81cd..8f001209892 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/MainModuleOnly.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/MainModuleOnly.java @@ -117,7 +117,7 @@ public class MainModuleOnly extends DynamicArchiveTestBase { "--module-path", moduleDir.toString(), "-m", TEST_MODULE1) .assertNormalExit(output -> { - output.shouldContain("[class,load] com.simple.Main source: shared objects file") + output.shouldMatch("\\[class,load *\\] com\\.simple\\.Main source: shared objects file") .shouldHaveExitValue(0); }); diff --git a/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/classpathtests/BootAppendTests.java b/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/classpathtests/BootAppendTests.java index a77c38c21b9..8bb84424676 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/classpathtests/BootAppendTests.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/classpathtests/BootAppendTests.java @@ -205,7 +205,7 @@ public class BootAppendTests { "Test #6", BOOT_APPEND_CLASS, "true", "BOOT"); TestCommon.checkExec(output); if (!TestCommon.isUnableToMap(output)) - output.shouldContain("[class,load] sun.nio.cs.ext1.MyClass source: shared objects file"); + output.shouldMatch("\\[class,load *\\] sun\\.nio\\.cs\\.ext1\\.MyClass source: shared objects file"); } diff --git a/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/modulepath/AddModules.java b/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/modulepath/AddModules.java index bd569732ed5..9c2039e538b 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/modulepath/AddModules.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/modulepath/AddModules.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -118,8 +118,8 @@ public class AddModules { moduleDir.toString(), // --module-path MAIN_MODULE1) // -m .assertNormalExit(out -> { - out.shouldContain("[class,load] com.greetings.Main source: shared objects file") - .shouldContain("[class,load] org.astro.World source: shared objects file"); + out.shouldMatch("\\[class,load *\\] com\\.greetings\\.Main source: shared objects file") + .shouldMatch("\\[class,load *\\] org\\.astro\\.World source: shared objects file"); }); // run the com.hello module with the archive with the --module-path @@ -130,8 +130,8 @@ public class AddModules { moduleDir.toString(), // --module-path MAIN_MODULE2) // -m .assertNormalExit(out -> { - out.shouldContain("[class,load] com.hello.Main source: shared objects file") - .shouldContain("[class,load] org.astro.World source: shared objects file"); + out.shouldMatch("\\[class,load *\\] com\\.hello\\.Main source: shared objects file") + .shouldMatch("\\[class,load *\\] org\\.astro\\.World source: shared objects file"); }); } } diff --git a/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/modulepath/ModulePathAndCP.java b/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/modulepath/ModulePathAndCP.java index 6c44ad587e3..9985215f773 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/modulepath/ModulePathAndCP.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/modulepath/ModulePathAndCP.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -115,8 +115,8 @@ public class ModulePathAndCP { moduleDir.toString(), // --module-path MAIN_MODULE) // -m .assertNormalExit(out -> { - out.shouldContain("[class,load] com.greetings.Main source: shared objects file") - .shouldContain("[class,load] org.astro.World source: shared objects file"); + out.shouldMatch("\\[class,load *\\] com\\.greetings\\.Main source: shared objects file") + .shouldMatch("\\[class,load *\\] org\\.astro\\.World source: shared objects file"); }); // run with the archive with the --module-path different from the one during @@ -181,7 +181,7 @@ public class ModulePathAndCP { jars, // --module-path MAIN_MODULE) // -m .assertNormalExit(out -> { - out.shouldContain("[class,load] com.greetings.Main source: shared objects file") + out.shouldMatch("\\[class,load *\\] com\\.greetings\\.Main source: shared objects file") .shouldMatch(".class.load. org.astro.World source:.*org.astro.jar"); }); } diff --git a/test/hotspot/jtreg/runtime/cds/appcds/jvmti/redefineClasses/OldClassAndRedefineClass.java b/test/hotspot/jtreg/runtime/cds/appcds/jvmti/redefineClasses/OldClassAndRedefineClass.java index 26bccdf764e..b55e6cfbd8b 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/jvmti/redefineClasses/OldClassAndRedefineClass.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/jvmti/redefineClasses/OldClassAndRedefineClass.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -71,8 +71,8 @@ public class OldClassAndRedefineClass { "-Xlog:cds,class+load", agentCmdArg, "OldClassAndRedefineClassApp"); - out.shouldContain("[class,load] OldSuper source: shared objects file") - .shouldContain("[class,load] ChildOldSuper source: shared objects file") - .shouldContain("[class,load] Hello source: __VM_RedefineClasses__"); + out.shouldMatch("\\[class,load *\\] OldSuper source: shared objects file") + .shouldMatch("\\[class,load *\\] ChildOldSuper source: shared objects file") + .shouldMatch("\\[class,load *\\] Hello source: __VM_RedefineClasses__"); } } diff --git a/test/hotspot/jtreg/runtime/jni/mutateFinals/MutateFinalsTest.java b/test/hotspot/jtreg/runtime/jni/mutateFinals/MutateFinalsTest.java index 0ae4ae231b9..69786e3b368 100644 --- a/test/hotspot/jtreg/runtime/jni/mutateFinals/MutateFinalsTest.java +++ b/test/hotspot/jtreg/runtime/jni/mutateFinals/MutateFinalsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -134,7 +134,7 @@ class MutateFinalsTest { void testMutateInstanceFinalWithLogging(String methodName) throws Exception { String type = methodName.contains("Object") ? "Object" : ""; test(methodName, "-Xlog:jni=debug") - .shouldContain("[debug][jni] Set" + type + "Field mutated final instance field") + .shouldMatch("\\[debug *\\]\\[jni *\\] Set" + type + "Field mutated final instance field") .shouldHaveExitValue(0); } @@ -147,7 +147,7 @@ class MutateFinalsTest { void testMutateStaticFinalWithLogging(String methodName) throws Exception { String type = methodName.contains("Object") ? "Object" : ""; test(methodName, "-Xlog:jni=debug") - .shouldContain("[debug][jni] SetStatic" + type + "Field mutated final static field") + .shouldMatch("\\[debug *\\]\\[jni *\\] SetStatic" + type + "Field mutated final static field") .shouldHaveExitValue(0); } diff --git a/test/hotspot/jtreg/runtime/logging/ClassInitializationTest.java b/test/hotspot/jtreg/runtime/logging/ClassInitializationTest.java index 34249e5fec8..ab076826723 100644 --- a/test/hotspot/jtreg/runtime/logging/ClassInitializationTest.java +++ b/test/hotspot/jtreg/runtime/logging/ClassInitializationTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -60,7 +60,7 @@ public class ClassInitializationTest { "BadMap50"); out = new OutputAnalyzer(pb.start()); out.shouldNotHaveExitValue(0); - out.shouldNotContain("[class,init]"); + out.shouldNotMatch("\\[class,init *\\]"); out.shouldNotContain("Fail over class verification to old verifier for: BadMap50"); } diff --git a/test/hotspot/jtreg/runtime/logging/CondyIndyTest.java b/test/hotspot/jtreg/runtime/logging/CondyIndyTest.java index c62402c918b..9e75d52496f 100644 --- a/test/hotspot/jtreg/runtime/logging/CondyIndyTest.java +++ b/test/hotspot/jtreg/runtime/logging/CondyIndyTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved. * 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,27 +44,27 @@ public class CondyIndyTest { "CondyIndy"); OutputAnalyzer o = new OutputAnalyzer(pb.start()); o.shouldHaveExitValue(0); - o.shouldContain("[info][methodhandles"); - o.shouldNotContain("[debug][methodhandles,indy"); - o.shouldNotContain("[debug][methodhandles,condy"); + o.shouldMatch("\\[info *\\]\\[methodhandles"); + o.shouldNotMatch("\\[debug *\\]\\[methodhandles,indy"); + o.shouldNotMatch("\\[debug *\\]\\[methodhandles,condy"); // (2) methodhandles+condy=debug only pb = ProcessTools.createLimitedTestJavaProcessBuilder("-Xlog:methodhandles+condy=debug", "CondyIndy"); o = new OutputAnalyzer(pb.start()); o.shouldHaveExitValue(0); - o.shouldNotContain("[info ][methodhandles"); - o.shouldNotContain("[debug][methodhandles,indy"); - o.shouldContain("[debug][methodhandles,condy"); + o.shouldNotMatch("\\[info *\\]\\[methodhandles"); + o.shouldNotMatch("\\[debug *\\]\\[methodhandles,indy"); + o.shouldMatch("\\[debug *\\]\\[methodhandles,condy"); // (3) methodhandles+indy=debug only pb = ProcessTools.createLimitedTestJavaProcessBuilder("-Xlog:methodhandles+indy=debug", "CondyIndy"); o = new OutputAnalyzer(pb.start()); o.shouldHaveExitValue(0); - o.shouldNotContain("[info ][methodhandles"); - o.shouldContain("[debug][methodhandles,indy"); - o.shouldNotContain("[debug][methodhandles,condy"); + o.shouldNotMatch("\\[info *\\]\\[methodhandles"); + o.shouldMatch("\\[debug *\\]\\[methodhandles,indy"); + o.shouldNotMatch("\\[debug *\\]\\[methodhandles,condy"); // (4) methodhandles, condy, indy all on pb = ProcessTools.createLimitedTestJavaProcessBuilder("-Xlog:methodhandles=info", @@ -73,8 +73,8 @@ public class CondyIndyTest { "CondyIndy"); o = new OutputAnalyzer(pb.start()); o.shouldHaveExitValue(0); - o.shouldContain("[info ][methodhandles"); - o.shouldContain("[debug][methodhandles,indy"); - o.shouldContain("[debug][methodhandles,condy"); + o.shouldMatch("\\[info *\\]\\[methodhandles"); + o.shouldMatch("\\[debug *\\]\\[methodhandles,indy"); + o.shouldMatch("\\[debug *\\]\\[methodhandles,condy"); }; } diff --git a/test/hotspot/jtreg/runtime/logging/ExceptionsTest.java b/test/hotspot/jtreg/runtime/logging/ExceptionsTest.java index c2c966cb047..3bbec57b158 100644 --- a/test/hotspot/jtreg/runtime/logging/ExceptionsTest.java +++ b/test/hotspot/jtreg/runtime/logging/ExceptionsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -68,7 +68,7 @@ public class ExceptionsTest { static void analyzeOutputOff(ProcessBuilder pb) throws Exception { OutputAnalyzer output = new OutputAnalyzer(pb.start()); - output.shouldNotContain("[exceptions]"); + output.shouldNotMatch("\\[exceptions *\\]"); output.shouldHaveExitValue(0); } diff --git a/test/hotspot/jtreg/runtime/logging/GenerateOopMapTest.java b/test/hotspot/jtreg/runtime/logging/GenerateOopMapTest.java index 6e114ff6b1d..c16102ff448 100644 --- a/test/hotspot/jtreg/runtime/logging/GenerateOopMapTest.java +++ b/test/hotspot/jtreg/runtime/logging/GenerateOopMapTest.java @@ -43,7 +43,7 @@ public class GenerateOopMapTest { static String infoPattern = "[generateoopmap]"; static String debugPattern = "[generateoopmap] Basicblock#0 begins at:"; - static String tracePattern = "[trace][generateoopmap] 5 vars = 'r' stack = 'v' monitors = '' \tifne"; + static String tracePattern = "\\[trace *\\]\\[generateoopmap\\] 5 vars = 'r' stack = 'v' monitors = '' \tifne"; static String traceDetailPattern = "[generateoopmap] 0 vars = ( r |slot0) invokestatic()V"; static void test() throws Exception { @@ -63,7 +63,7 @@ public class GenerateOopMapTest { pb = ProcessTools.createLimitedTestJavaProcessBuilder("-Xlog:generateoopmap=trace", "GenerateOopMapTest", "test"); o = new OutputAnalyzer(pb.start()); - o.shouldContain(tracePattern).shouldHaveExitValue(0); + o.shouldMatch(tracePattern).shouldHaveExitValue(0); // Prints extra stuff with detailed. Not sure how useful this is but keep it for now. if (Platform.isDebugBuild()) { diff --git a/test/hotspot/jtreg/runtime/logging/StackWalkTest.java b/test/hotspot/jtreg/runtime/logging/StackWalkTest.java index 226dac6f466..1cf90c1088d 100644 --- a/test/hotspot/jtreg/runtime/logging/StackWalkTest.java +++ b/test/hotspot/jtreg/runtime/logging/StackWalkTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,7 +44,7 @@ public class StackWalkTest { static void analyzeOutputOff(ProcessBuilder pb) throws Exception { OutputAnalyzer output = new OutputAnalyzer(pb.start()); - output.shouldNotContain("[stackwalk]"); + output.shouldNotMatch("\\[stackwalk *\\]"); output.shouldHaveExitValue(0); } diff --git a/test/hotspot/jtreg/runtime/logging/StartupTimeTest.java b/test/hotspot/jtreg/runtime/logging/StartupTimeTest.java index 88ec76efd12..a1715509243 100644 --- a/test/hotspot/jtreg/runtime/logging/StartupTimeTest.java +++ b/test/hotspot/jtreg/runtime/logging/StartupTimeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,7 +47,7 @@ public class StartupTimeTest { static void analyzeOutputOff(ProcessBuilder pb) throws Exception { OutputAnalyzer output = new OutputAnalyzer(pb.start()); - output.shouldNotContain("[startuptime]"); + output.shouldNotMatch("\\[startuptime *\\]"); output.shouldHaveExitValue(0); } diff --git a/test/hotspot/jtreg/runtime/logging/VerificationTest.java b/test/hotspot/jtreg/runtime/logging/VerificationTest.java index a6a0ee66acc..b2315f585c8 100644 --- a/test/hotspot/jtreg/runtime/logging/VerificationTest.java +++ b/test/hotspot/jtreg/runtime/logging/VerificationTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,26 +39,26 @@ public class VerificationTest { static void analyzeOutputOn(ProcessBuilder pb, boolean isLogLevelInfo) throws Exception { OutputAnalyzer output = new OutputAnalyzer(pb.start()); - output.shouldContain("[verification]"); + output.shouldMatch("\\[verification *\\]"); output.shouldContain("Verifying class VerificationTest$InternalClass with new format"); output.shouldContain("Verifying method VerificationTest$InternalClass.()V"); output.shouldContain("End class verification for: VerificationTest$InternalClass"); if (isLogLevelInfo) { // logging level 'info' should not output stack map and opcode data. - output.shouldNotContain("[verification] StackMapTable: frame_count"); - output.shouldNotContain("[verification] offset = 0, opcode ="); + output.shouldNotMatch("\\[verification *\\] StackMapTable: frame_count"); + output.shouldNotMatch("\\[verification *\\] offset = 0, opcode ="); } else { // log level debug - output.shouldContain("[debug][verification] StackMapTable: frame_count"); - output.shouldContain("[debug][verification] offset = 0, opcode ="); + output.shouldMatch("\\[debug *\\]\\[verification *\\] StackMapTable: frame_count"); + output.shouldMatch("\\[debug *\\]\\[verification *\\] offset = 0, opcode ="); } output.shouldHaveExitValue(0); } static void analyzeOutputOff(ProcessBuilder pb) throws Exception { OutputAnalyzer output = new OutputAnalyzer(pb.start()); - output.shouldNotContain("[verification]"); + output.shouldNotMatch("\\[verification *\\]"); output.shouldHaveExitValue(0); } diff --git a/test/hotspot/jtreg/runtime/modules/PatchModule/PatchModuleTraceCL.java b/test/hotspot/jtreg/runtime/modules/PatchModule/PatchModuleTraceCL.java index 4750e95c828..0c57b4f2076 100644 --- a/test/hotspot/jtreg/runtime/modules/PatchModule/PatchModuleTraceCL.java +++ b/test/hotspot/jtreg/runtime/modules/PatchModule/PatchModuleTraceCL.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -60,11 +60,11 @@ public class PatchModuleTraceCL { OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); // "modules" jimage case. - output.shouldContain("[class,load] java.lang.Thread source: jrt:/java.base"); + output.shouldMatch("\\[class,load *\\] java\\.lang\\.Thread source: jrt:/java.base"); // --patch-module case. - output.shouldContain("[class,load] javax.naming.spi.NamingManager source: mods/java.naming"); + output.shouldMatch("\\[class,load *\\] javax\\.naming\\.spi\\.NamingManager source: mods/java.naming"); // -cp case. - output.shouldContain("[class,load] PatchModuleMain source: file"); + output.shouldMatch("\\[class,load *\\] PatchModuleMain source: file"); // Test -Xlog:class+load=info output for -Xbootclasspath/a source = "package PatchModuleTraceCL_pkg; " + @@ -82,7 +82,7 @@ public class PatchModuleTraceCL { "-Xlog:class+load=info", "PatchModuleMain", "PatchModuleTraceCL_pkg.ItIsI"); output = new OutputAnalyzer(pb.start()); // -Xbootclasspath/a case. - output.shouldContain("[class,load] PatchModuleTraceCL_pkg.ItIsI source: xbcp"); + output.shouldMatch("\\[class,load *\\] PatchModuleTraceCL_pkg\\.ItIsI source: xbcp"); output.shouldHaveExitValue(0); } } diff --git a/test/hotspot/jtreg/runtime/os/THPsInThreadStackPreventionTest.java b/test/hotspot/jtreg/runtime/os/THPsInThreadStackPreventionTest.java index 163a665b687..7fa80a5b40b 100644 --- a/test/hotspot/jtreg/runtime/os/THPsInThreadStackPreventionTest.java +++ b/test/hotspot/jtreg/runtime/os/THPsInThreadStackPreventionTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2023, Red Hat Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -188,7 +188,7 @@ public class THPsInThreadStackPreventionTest { output.shouldHaveExitValue(0); // this line indicates the mitigation is active: - output.shouldContain("[pagesize] JVM will attempt to prevent THPs in thread stacks."); + output.shouldMatch("\\[pagesize *\\] JVM will attempt to prevent THPs in thread stacks\\."); ProcSelfStatus status = ProcSelfStatus.parse(output); if (status.numLifeThreads < numThreads) { @@ -225,7 +225,7 @@ public class THPsInThreadStackPreventionTest { output.shouldHaveExitValue(0); // We deliberately switched off mitigation, VM should tell us: - output.shouldContain("[pagesize] JVM will *not* prevent THPs in thread stacks. This may cause high RSS."); + output.shouldMatch("\\[pagesize *\\] JVM will \\*not\\* prevent THPs in thread stacks\\. This may cause high RSS\\."); // Parse output from self/status ProcSelfStatus status = ProcSelfStatus.parse(output); diff --git a/test/hotspot/jtreg/runtime/os/TestHugePageDecisionsAtVMStartup.java b/test/hotspot/jtreg/runtime/os/TestHugePageDecisionsAtVMStartup.java index 6c5896df058..52e7560a460 100644 --- a/test/hotspot/jtreg/runtime/os/TestHugePageDecisionsAtVMStartup.java +++ b/test/hotspot/jtreg/runtime/os/TestHugePageDecisionsAtVMStartup.java @@ -68,8 +68,8 @@ import java.util.Set; public class TestHugePageDecisionsAtVMStartup { // End user warnings, printing with Xlog:pagesize at warning level, should be unconditional - static final String warningNoTHP = "[warning][pagesize] UseTransparentHugePages disabled, transparent huge pages are not supported by the operating system."; - static final String warningNoLP = "[warning][pagesize] UseLargePages disabled, no large pages configured and available on the system."; + static final String warningNoTHP = "\\[warning\\]\\[pagesize *\\] UseTransparentHugePages disabled, transparent huge pages are not supported by the operating system\\."; + static final String warningNoLP = "\\[warning\\]\\[pagesize *\\] UseLargePages disabled, no large pages configured and available on the system\\."; static final String buildSizeString(long l) { String units[] = { "K", "M", "G" }; @@ -119,27 +119,27 @@ public class TestHugePageDecisionsAtVMStartup { } if (!useLP) { - out.shouldContain("[info][pagesize] Large page support disabled"); + out.shouldMatch("\\[info *\\]\\[pagesize *\\] Large page support disabled"); } else if (useLP && !useTHP && (!configuration.supportsExplicitHugePages() || !haveUsableExplicitHugePages)) { - out.shouldContain(warningNoLP); + out.shouldMatch(warningNoLP); } else if (useLP && useTHP && !configuration.supportsTHP()) { - out.shouldContain(warningNoTHP); + out.shouldMatch(warningNoTHP); } else if (useLP && !useTHP && configuration.supportsExplicitHugePages() && haveUsableExplicitHugePages) { if (configuration.getExplicitAvailableHugePageNumber() == 0) { throw new SkippedException("No usable explicit hugepages configured on the system, skipping test"); } - out.shouldContain("[info][pagesize] Using the default large page size: " + buildSizeString(configuration.getExplicitDefaultHugePageSize())); - out.shouldContain("[info][pagesize] UseLargePages=1, UseTransparentHugePages=0"); - out.shouldContain("[info][pagesize] Large page support enabled"); + out.shouldMatch("\\[info *\\]\\[pagesize *\\] Using the default large page size: " + buildSizeString(configuration.getExplicitDefaultHugePageSize())); + out.shouldMatch("\\[info *\\]\\[pagesize *\\] UseLargePages=1, UseTransparentHugePages=0"); + out.shouldMatch("\\[info *\\]\\[pagesize *\\] Large page support enabled"); } else if (useLP && useTHP && configuration.supportsTHP()) { long thpPageSize = configuration.getThpPageSizeOrFallback(); String thpPageSizeString = buildSizeString(thpPageSize); // We expect to see exactly two "Usable page sizes" : the system page size and the THP page size. The system // page size differs, but its always in KB). - out.shouldContain("[info][pagesize] UseLargePages=1, UseTransparentHugePages=1"); - out.shouldMatch(".*\\[info]\\[pagesize] Large page support enabled. Usable page sizes: \\d+[kK], " + thpPageSizeString + ". Default large page size: " + thpPageSizeString + ".*"); + out.shouldMatch("\\[info *\\]\\[pagesize *\\] UseLargePages=1, UseTransparentHugePages=1"); + out.shouldMatch("\\[info *\\]\\[pagesize *\\] Large page support enabled\\. Usable page sizes: \\d+[kK], " + thpPageSizeString + "\\. Default large page size: " + thpPageSizeString); } } diff --git a/test/hotspot/jtreg/runtime/os/TestTrimNative.java b/test/hotspot/jtreg/runtime/os/TestTrimNative.java index e8645a91479..467891bfe1e 100644 --- a/test/hotspot/jtreg/runtime/os/TestTrimNative.java +++ b/test/hotspot/jtreg/runtime/os/TestTrimNative.java @@ -1,7 +1,7 @@ /* * Copyright (c) 2023 SAP SE. All rights reserved. * Copyright (c) 2023, 2024, Red Hat, Inc. All rights reserved. - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -322,7 +322,7 @@ public class TestTrimNative { checkExpectedLogMessages(output, false, 0); parseOutputAndLookForNegativeTrim(output, 0, 0, strictTesting); // The following output is expected to be printed with warning level, so it should not need -Xlog - output.shouldContain("[warning][trimnative] Native heap trim is not supported on this platform"); + output.shouldMatch("\\[warning\\]\\[trimnative *\\] Native heap trim is not supported on this platform"); } break; case "testOffExplicit": { diff --git a/test/hotspot/jtreg/serviceability/dcmd/gc/HeapDumpParallelTest.java b/test/hotspot/jtreg/serviceability/dcmd/gc/HeapDumpParallelTest.java index 0010c5bdd78..f4dcb4dc1b0 100644 --- a/test/hotspot/jtreg/serviceability/dcmd/gc/HeapDumpParallelTest.java +++ b/test/hotspot/jtreg/serviceability/dcmd/gc/HeapDumpParallelTest.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2023, Alibaba Group Holding Limited. All Rights Reserved. + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -55,7 +56,7 @@ public class HeapDumpParallelTest { dcmdOut.shouldHaveExitValue(0); dcmdOut.shouldContain("Heap dump file created"); OutputAnalyzer appOut = new OutputAnalyzer(app.getProcessStdout()); - appOut.shouldContain("[heapdump]"); + appOut.shouldMatch("\\[heapdump *\\]"); String opts = Arrays.asList(Utils.getTestJavaOpts()).toString(); if (opts.contains("-XX:+UseSerialGC") || opts.contains("-XX:+UseEpsilonGC")) { System.out.println("UseSerialGC detected."); @@ -136,4 +137,4 @@ public class HeapDumpParallelTest { PidJcmdExecutor executor = new PidJcmdExecutor("" + lingeredAppPid); return executor.execute("GC.heap_dump " + arg + " " + heapDumpFile.getAbsolutePath()); } -} \ No newline at end of file +} diff --git a/test/jdk/jdk/jfr/jcmd/TestJcmdChangeLogLevel.java b/test/jdk/jdk/jfr/jcmd/TestJcmdChangeLogLevel.java index c4ef5ecfa74..a6dcd458383 100644 --- a/test/jdk/jdk/jfr/jcmd/TestJcmdChangeLogLevel.java +++ b/test/jdk/jdk/jfr/jcmd/TestJcmdChangeLogLevel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,7 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.List; +import java.util.regex.Pattern; import jdk.test.lib.dcmd.JcmdExecutor; import jdk.test.lib.dcmd.PidJcmdExecutor; @@ -46,7 +47,7 @@ import jdk.test.lib.dcmd.PidJcmdExecutor; public class TestJcmdChangeLogLevel { public static void main(String[] args) throws Exception { final String fileName = "jfr_trace.txt"; - final String findWhat = "[info][jfr] Flight Recorder initialized"; + final Pattern findWhat = Pattern.compile("\\[info *\\]\\[jfr *\\] Flight Recorder initialized"); boolean passed = false; JcmdExecutor je = new PidJcmdExecutor(); @@ -61,7 +62,7 @@ public class TestJcmdChangeLogLevel { throw new Error(e); } for (String l : lines) { - if (l.toString().contains(findWhat)) { + if (findWhat.matcher(l).find()) { passed = true; break; } diff --git a/test/jdk/jdk/jfr/jcmd/TestJcmdConfigure.java b/test/jdk/jdk/jfr/jcmd/TestJcmdConfigure.java index f64c99bedbc..8000199558c 100644 --- a/test/jdk/jdk/jfr/jcmd/TestJcmdConfigure.java +++ b/test/jdk/jdk/jfr/jcmd/TestJcmdConfigure.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,7 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; +import java.util.regex.Pattern; import jdk.jfr.internal.Repository; import jdk.jfr.internal.Options; @@ -127,7 +128,8 @@ public class TestJcmdConfigure { } private static void testRepository(){ - final String findWhat = "[info][jfr] Same base repository path " + REPOSITORYPATH_1 + " is set"; + final Pattern findWhat = Pattern.compile("\\[info *\\]\\[jfr *\\] Same base repository path " + + Pattern.quote(REPOSITORYPATH_1) + " is set"); try { JcmdHelper.jcmd("JFR.configure", REPOSITORYPATH_SETTING_1); @@ -138,7 +140,7 @@ public class TestJcmdConfigure { Asserts.assertTrue(samePath.equals(initialPath)); List lines = Files.readAllLines(Paths.get(JFR_UNIFIED_LOG_FILE)); - Asserts.assertTrue(lines.stream().anyMatch(l->l.contains(findWhat))); + Asserts.assertTrue(lines.stream().anyMatch(l -> findWhat.matcher(l).find())); JcmdHelper.jcmd("JFR.configure", REPOSITORYPATH_SETTING_2); Path changedPath = Repository.getRepository().getRepositoryPath(); diff --git a/test/jdk/jdk/jfr/startupargs/TestStartupMessage.java b/test/jdk/jdk/jfr/startupargs/TestStartupMessage.java index 4a934ebb36d..28e2891a08c 100644 --- a/test/jdk/jdk/jfr/startupargs/TestStartupMessage.java +++ b/test/jdk/jdk/jfr/startupargs/TestStartupMessage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -59,12 +59,12 @@ public class TestStartupMessage { // Can't turn off log with -Xlog:jfr+startup=warning startJfrJvm() - .shouldContain("[info][jfr,startup") + .shouldMatch("\\[info *\\]\\[jfr,startup") .shouldContain("Started recording") .shouldContain("Use jcmd"); startJfrJvm("-Xlog:jfr+startup=info") - .shouldContain("[info][jfr,startup") + .shouldMatch("\\[info *\\]\\[jfr,startup") .shouldContain("Started recording") .shouldContain("Use jcmd"); } From 3f44d03e8a1f79477b4d9d45433b9ec76a9aeda8 Mon Sep 17 00:00:00 2001 From: Albert Mingkun Yang Date: Wed, 10 Jun 2026 16:29:55 +0000 Subject: [PATCH 18/20] 8386323: Remove unused MemoryPool allocation availability state Reviewed-by: stefank, tschatzl, jsikstro --- src/hotspot/share/gc/parallel/psMemoryPool.cpp | 6 +++--- src/hotspot/share/gc/serial/serialMemoryPools.cpp | 6 +++--- src/hotspot/share/services/memoryPool.cpp | 3 +-- src/hotspot/share/services/memoryPool.hpp | 8 -------- 4 files changed, 7 insertions(+), 16 deletions(-) diff --git a/src/hotspot/share/gc/parallel/psMemoryPool.cpp b/src/hotspot/share/gc/parallel/psMemoryPool.cpp index 40170f62f06..13304ca18ad 100644 --- a/src/hotspot/share/gc/parallel/psMemoryPool.cpp +++ b/src/hotspot/share/gc/parallel/psMemoryPool.cpp @@ -32,7 +32,7 @@ PSOldGenerationPool::PSOldGenerationPool(PSOldGen* old_gen, } MemoryUsage PSOldGenerationPool::get_memory_usage() { - size_t maxSize = (available_for_allocation() ? max_size() : 0); + size_t maxSize = max_size(); size_t used = used_in_bytes(); size_t committed = _old_gen->capacity_in_bytes(); @@ -59,7 +59,7 @@ PSEdenSpacePool::PSEdenSpacePool(PSYoungGen* young_gen, } MemoryUsage PSEdenSpacePool::get_memory_usage() { - size_t maxSize = (available_for_allocation() ? max_size() : 0); + size_t maxSize = max_size(); size_t used = used_in_bytes(); size_t committed = _space->capacity_in_bytes(); @@ -80,7 +80,7 @@ PSSurvivorSpacePool::PSSurvivorSpacePool(PSYoungGen* young_gen, } MemoryUsage PSSurvivorSpacePool::get_memory_usage() { - size_t maxSize = (available_for_allocation() ? max_size() : 0); + size_t maxSize = max_size(); size_t used = used_in_bytes(); size_t committed = committed_in_bytes(); return MemoryUsage(initial_size(), used, committed, maxSize); diff --git a/src/hotspot/share/gc/serial/serialMemoryPools.cpp b/src/hotspot/share/gc/serial/serialMemoryPools.cpp index 723b53a3e2b..8b0230264ef 100644 --- a/src/hotspot/share/gc/serial/serialMemoryPools.cpp +++ b/src/hotspot/share/gc/serial/serialMemoryPools.cpp @@ -40,7 +40,7 @@ size_t ContiguousSpacePool::used_in_bytes() { } MemoryUsage ContiguousSpacePool::get_memory_usage() { - size_t maxSize = (available_for_allocation() ? max_size() : 0); + size_t maxSize = max_size(); size_t used = used_in_bytes(); size_t committed = _space->capacity(); @@ -64,7 +64,7 @@ size_t SurvivorContiguousSpacePool::committed_in_bytes() { } MemoryUsage SurvivorContiguousSpacePool::get_memory_usage() { - size_t maxSize = (available_for_allocation() ? max_size() : 0); + size_t maxSize = max_size(); size_t used = used_in_bytes(); size_t committed = committed_in_bytes(); @@ -85,7 +85,7 @@ size_t TenuredGenerationPool::used_in_bytes() { MemoryUsage TenuredGenerationPool::get_memory_usage() { size_t used = used_in_bytes(); size_t committed = _gen->capacity(); - size_t maxSize = (available_for_allocation() ? max_size() : 0); + size_t maxSize = max_size(); return MemoryUsage(initial_size(), used, committed, maxSize); } diff --git a/src/hotspot/share/services/memoryPool.cpp b/src/hotspot/share/services/memoryPool.cpp index 41362181c6b..8361913862c 100644 --- a/src/hotspot/share/services/memoryPool.cpp +++ b/src/hotspot/share/services/memoryPool.cpp @@ -51,7 +51,6 @@ MemoryPool::MemoryPool(const char* name, _type(type), _initial_size(init_size), _max_size(max_size), - _available_for_allocation(true), _managers(), _num_managers(0), _peak_usage(), @@ -188,7 +187,7 @@ MemoryUsage CodeHeapPool::get_memory_usage() { size_t used = used_in_bytes(); OrderAccess::acquire(); // ensure possible cache expansion in CodeCache::allocate is seen size_t committed = _codeHeap->capacity(); - size_t maxSize = (available_for_allocation() ? max_size() : 0); + size_t maxSize = max_size(); return MemoryUsage(initial_size(), used, committed, maxSize); } diff --git a/src/hotspot/share/services/memoryPool.hpp b/src/hotspot/share/services/memoryPool.hpp index a55c593ebed..f0a4ba21659 100644 --- a/src/hotspot/share/services/memoryPool.hpp +++ b/src/hotspot/share/services/memoryPool.hpp @@ -61,7 +61,6 @@ class MemoryPool : public CHeapObj { PoolType _type; size_t _initial_size; size_t _max_size; - bool _available_for_allocation; // Default is true MemoryManager* _managers[max_num_managers]; int _num_managers; MemoryUsage _peak_usage; // Peak memory usage @@ -98,13 +97,6 @@ class MemoryPool : public CHeapObj { bool is_pool(instanceHandle pool) const; - bool available_for_allocation() { return _available_for_allocation; } - bool set_available_for_allocation(bool value) { - bool prev = _available_for_allocation; - _available_for_allocation = value; - return prev; - } - MemoryManager* get_memory_manager(int index) { assert(index >= 0 && index < _num_managers, "Invalid index"); return _managers[index]; From 132072077aa4a15db108989e3d17e6d9249d3ba2 Mon Sep 17 00:00:00 2001 From: Sruthy Jayan Date: Wed, 10 Jun 2026 17:22:23 +0000 Subject: [PATCH 19/20] 8380993: [REDO] Incorrect Interpretation of POSIX TZ Environment Variable on AIX Reviewed-by: naoto --- .../unix/native/libjava/TimeZone_md.c | 72 +++++++++---- .../java/util/TimeZone/AIXTzMappingTest.java | 102 ++++++++++++++++++ .../util/TimeZone/CustomTzIDCheckDST.java | 7 +- 3 files changed, 158 insertions(+), 23 deletions(-) create mode 100644 test/jdk/java/util/TimeZone/AIXTzMappingTest.java diff --git a/src/java.base/unix/native/libjava/TimeZone_md.c b/src/java.base/unix/native/libjava/TimeZone_md.c index 2f163cf27f1..bc2ed500d60 100644 --- a/src/java.base/unix/native/libjava/TimeZone_md.c +++ b/src/java.base/unix/native/libjava/TimeZone_md.c @@ -352,33 +352,15 @@ getPlatformTimeZoneID() } static char * -mapPlatformToJavaTimezone(const char *java_home_dir, const char *tz) { +getJavaTimezoneFromPlatform(const char *tz_buf, size_t tz_len, const char *mapfilename) { FILE *tzmapf; - char mapfilename[PATH_MAX + 1]; char line[256]; int linecount = 0; - char *tz_buf = NULL; - char *temp_tz = NULL; char *javatz = NULL; - size_t tz_len = 0; - /* On AIX, the TZ environment variable may end with a comma - * followed by modifier fields until early AIX6.1. - * This restriction has been removed from AIX7. */ - - tz_buf = strdup(tz); - tz_len = strlen(tz_buf); - - /* Open tzmappings file, with buffer overrun check */ - if ((strlen(java_home_dir) + 15) > PATH_MAX) { - jio_fprintf(stderr, "Path %s/lib/tzmappings exceeds maximum path length\n", java_home_dir); - goto tzerr; - } - strcpy(mapfilename, java_home_dir); - strcat(mapfilename, "/lib/tzmappings"); if ((tzmapf = fopen(mapfilename, "r")) == NULL) { jio_fprintf(stderr, "can't open %s\n", mapfilename); - goto tzerr; + return NULL; } while (fgets(line, sizeof(line), tzmapf) != NULL) { @@ -431,10 +413,58 @@ mapPlatformToJavaTimezone(const char *java_home_dir, const char *tz) { break; } } + (void) fclose(tzmapf); + return javatz; +} + +static char * +mapPlatformToJavaTimezone(const char *java_home_dir, const char *tz) { + char mapfilename[PATH_MAX + 1]; + char *tz_buf = NULL; + char *javatz = NULL; + char *temp_tz = NULL; + size_t tz_len = 0; + + /* On AIX, the TZ environment variable may end with a comma + * followed by modifier fields until early AIX6.1. + * This restriction has been removed from AIX7. */ + + tz_buf = strdup(tz); + if (tz_buf == NULL) { + jio_fprintf(stderr, "Failed to allocate timezone buffer\n"); + goto tzerr; + } + tz_len = strlen(tz_buf); + + /* Open tzmappings file, with buffer overrun check */ + if ((strlen(java_home_dir) + 15) > PATH_MAX) { + jio_fprintf(stderr, "Path %s/lib/tzmappings exceeds maximum path length\n", java_home_dir); + goto tzerr; + } + strcpy(mapfilename, java_home_dir); + strcat(mapfilename, "/lib/tzmappings"); + + // First attempt to find the Java timezone for the full tz string + javatz = getJavaTimezoneFromPlatform(tz_buf, tz_len, mapfilename); + + // If no match was found, check for timezone with truncated value + if (javatz == NULL) { + temp_tz = strchr(tz, ','); + tz_len = (temp_tz == NULL) ? strlen(tz) : temp_tz - tz; + free((void *) tz_buf); + tz_buf = (char *)malloc(tz_len + 1); + if (tz_buf == NULL) { + jio_fprintf(stderr, "Failed to allocate timezone buffer\n"); + goto tzerr; + } + memcpy(tz_buf, tz, tz_len); + tz_buf[tz_len] = '\0'; + javatz = getJavaTimezoneFromPlatform(tz_buf, tz_len, mapfilename); + } tzerr: - if (tz_buf != NULL ) { + if (tz_buf != NULL) { free((void *) tz_buf); } diff --git a/test/jdk/java/util/TimeZone/AIXTzMappingTest.java b/test/jdk/java/util/TimeZone/AIXTzMappingTest.java new file mode 100644 index 00000000000..6324bb8581a --- /dev/null +++ b/test/jdk/java/util/TimeZone/AIXTzMappingTest.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * 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 8380993 + * @library /test/lib + * @summary Validates AIX timezone mapping behavior where POSIX TZ strings + * with comma-separated DST rules are truncated and mapped through tzmappings + * to the expected IANA timezone IDs. + * @requires os.family == "aix" + * @run main/othervm AIXTzMappingTest + */ + +import java.util.TimeZone; + +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.process.OutputAnalyzer; + +public class AIXTzMappingTest { + + // POSIX TZ strings that should be mapped via tzmappings + private static final String TZ_CET = "CET-1CEST,M3.5.0,M10.5.0"; + private static final String TZ_MEZ = "MEZ-1MESZ,M3.5.0,M10.5.0/3"; + + private static final String ID_PARIS = "Europe/Paris"; + private static final String ID_BERLIN = "Europe/Berlin"; + + public static void main(String[] args) throws Throwable { + if (args.length == 0) { + runWithTZ(TZ_CET, ID_PARIS); + runWithTZ(TZ_MEZ, ID_BERLIN); + } else if (args.length == 1) { + runTZTest(args[0]); + } else { + throw new RuntimeException( + "Expected 0 or 1 arguments, got " + args.length); + } + } + + private static void runWithTZ(String tz, String expectedId) + throws Throwable { + ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder( + "AIXTzMappingTest", expectedId); + + pb.environment().put("TZ", tz); + + OutputAnalyzer output = ProcessTools.executeProcess(pb); + output.shouldHaveExitValue(0); + } + + /* + * On AIX, POSIX TZ strings such as: + * CET-1CEST,M3.5.0,M10.5.0 + * MEZ-1MESZ,M3.5.0,M10.5.0/3 + * are truncated at the comma and mapped through tzmappings to + * IANA timezone IDs. + * + * This test verifies that the expected IANA timezone ID is selected. + */ + private static void runTZTest(String expectedId) { + String tzStr = System.getenv("TZ"); + + if (tzStr == null) { + throw new RuntimeException( + "Got unexpected timezone information: TZ is null"); + } + + TimeZone tz = TimeZone.getDefault(); + String tzId = tz.getID(); + + if (!expectedId.equals(tzId)) { + throw new RuntimeException( + "Expected timezone ID " + expectedId + + " but got " + tzId + + " for TZ=" + tzStr); + } + + System.out.println( + "AIX timezone mapping test passed: " + + tzId + " for TZ=" + tzStr); + } +} diff --git a/test/jdk/java/util/TimeZone/CustomTzIDCheckDST.java b/test/jdk/java/util/TimeZone/CustomTzIDCheckDST.java index 5fd48efadcc..9a332202ab3 100644 --- a/test/jdk/java/util/TimeZone/CustomTzIDCheckDST.java +++ b/test/jdk/java/util/TimeZone/CustomTzIDCheckDST.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,10 @@ * @library /test/lib * @summary This test will ensure that daylight savings rules are followed * appropriately when setting a custom timezone ID via the TZ env variable. - * @requires os.family != "windows" + * AIX is excluded because it uses a different timezone mapping mechanism + * through the tzmappings file; see AIXTzMappingTest.java for AIX-specific + * coverage. + * @requires os.family != "windows" & os.family != "aix" * @run main/othervm CustomTzIDCheckDST */ From dc4bb5acbe5d766f5fe389d8aeac0cc649f4f776 Mon Sep 17 00:00:00 2001 From: Anthony Scarpino Date: Wed, 10 Jun 2026 17:35:43 +0000 Subject: [PATCH 20/20] 8383608: Make BinaryEncodable non-exhaustive Reviewed-by: mullan --- .../java/security/BinaryEncodable.java | 34 ++++++++-- .../classes/java/security/PEMDecoder.java | 25 ++++--- .../internal/InternalBinaryEncodable.java | 39 +++++++++++ test/jdk/sun/security/internal/CheckIBE.java | 67 +++++++++++++++++++ .../sun/security/internal/ExhaustiveBE.java | 65 ++++++++++++++++++ 5 files changed, 212 insertions(+), 18 deletions(-) create mode 100644 src/java.base/share/classes/sun/security/internal/InternalBinaryEncodable.java create mode 100644 test/jdk/sun/security/internal/CheckIBE.java create mode 100644 test/jdk/sun/security/internal/ExhaustiveBE.java diff --git a/src/java.base/share/classes/java/security/BinaryEncodable.java b/src/java.base/share/classes/java/security/BinaryEncodable.java index bd5d05ee4ec..a1713c413ba 100644 --- a/src/java.base/share/classes/java/security/BinaryEncodable.java +++ b/src/java.base/share/classes/java/security/BinaryEncodable.java @@ -32,15 +32,35 @@ import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import jdk.internal.javac.PreviewFeature; +import sun.security.internal.InternalBinaryEncodable; + /** - * This interface is implemented by security API classes that contain - * binary-encodable cryptographic material. + * This interface identifies the cryptographic objects that can be converted + * to and from binary data, and thereby encoded and decoded as PEM text. * - *

This sealed interface may evolve. When using {@code switch}, always include a - * {@code default} case rather than relying on the classes specified in the - * {@code permits} clause to remain fixed. An exhaustive {@code switch} may - * result in a {@link MatchException}. + *

The APIs for cryptographic objects such as public keys, private keys, + * certificates, and certificate revocation lists all provide the means to + * convert their instances to and from standardized binary representations. + * Other kinds of cryptographic objects, such as certificate requests, have + * no corresponding API but can still be expressed as standardized binary + * representations. The {@code BinaryEncodable} interface allows the + * {@link PEMEncoder} and {@link PEMDecoder} classes to operate uniformly on + * binary representations of key or certificate material. + * + *

The permitted subtype {@code PEM} is notable for supporting the encoding + * and decoding of PEM text that represents cryptographic objects for which no + * API exists. In future releases, other permitted subtypes may be added to + * support the encoding and decoding of such cryptographic objects. + * + *

The list of permitted subtypes shown after {@code permits} is not + * exhaustive. This means if application code switches over a + * {@code BinaryEncodable} value, the {@code switch} cannot be made exhaustive + * simply by providing a {@code case} label for every permitted subtype shown + * in the list; there also must be a {@code default} or + * {@code case BinaryEncodable} label to handle additional subtypes. This + * allows the list of permitted subtypes to change over time without causing + * pre-existing switches to fail because of an unrecognized subtype. * * @see AsymmetricKey * @see KeyPair @@ -57,5 +77,5 @@ import jdk.internal.javac.PreviewFeature; @PreviewFeature(feature = PreviewFeature.Feature.PEM_API) public sealed interface BinaryEncodable permits AsymmetricKey, KeyPair, PKCS8EncodedKeySpec, X509EncodedKeySpec, EncryptedPrivateKeyInfo, - X509Certificate, X509CRL, PEM { + X509Certificate, X509CRL, PEM, InternalBinaryEncodable { } diff --git a/src/java.base/share/classes/java/security/PEMDecoder.java b/src/java.base/share/classes/java/security/PEMDecoder.java index f5a6a70d0f5..8ebc83f93d1 100644 --- a/src/java.base/share/classes/java/security/PEMDecoder.java +++ b/src/java.base/share/classes/java/security/PEMDecoder.java @@ -48,10 +48,10 @@ import java.util.Objects; * PEM is a textual encoding used to store and transfer cryptographic * objects, such as asymmetric keys, certificates, and certificate revocation * lists (CRLs). It is defined in RFC 1421 and RFC 7468. PEM consists of - * Base64-encoded content enclosed by a type-identifying header - * and footer. + * Base64-encoded content enclosed by a header and footer that identify the + * type of the content. * - *

The {@link #decode(String)} and {@link #decode(InputStream)} methods + *

The {@link #decode(String)} and {@link #decode(InputStream)} methods * return an instance of a class that matches the PEM type and implements * {@link BinaryEncodable}, as follows: *

    @@ -70,11 +70,18 @@ import java.util.Objects; *
* *

If the PEM type has no corresponding class, {@code decode(String)} and - * {@code decode(InputStream)} will return a {@code PEM} object. + * {@code decode(InputStream)} return a {@code PEM} object. + * + *

If application code switches over the {@code BinaryEncodable} result of + * {@link #decode(String)} or {@link #decode(InputStream)}, the {@code switch} cannot + * be made exhaustive simply by providing a {@code case} label for every permitted + * subtype listed for {@code BinaryEncodable}; there also must be a {@code default} + * or {@code case BinaryEncodable} label to handle additional subtypes that + * might be added in the future. * *

The {@link #decode(String, Class)} and {@link #decode(InputStream, Class)} - * methods accept a class parameter specifying the desired {@code BinaryEncodable} - * type. These methods avoid the need for casting and are useful when multiple + * methods accept a parameter specifying the desired {@code BinaryEncodable} + * result. These methods avoid the need for casting and are useful when multiple * representations are possible. For example, if the PEM contains both public and * private keys, specifying {@code PrivateKey.class} returns only the private key. * If {@code X509EncodedKeySpec.class} is provided, the public key encoding is @@ -109,11 +116,6 @@ import java.util.Objects; * for decryption, an {@link EncryptedPrivateKeyInfo} is returned. * A {@code PEMDecoder} configured for decryption can also decode unencrypted PEM. * - *

The {@code BinaryEncodable} interface may evolve. When using a decode method - * with {@code switch}, always include a {@code default} case rather than - * relying on the classes specified in the permits clause to remain fixed. - * An exhaustive {@code switch} may result in a {@link MatchException}. - * *

This class is immutable and thread-safe. * *

Example: decode a private key: @@ -136,6 +138,7 @@ import java.util.Objects; * @see PEMEncoder * @see PEM * @see EncryptedPrivateKeyInfo + * @see BinaryEncodable * * @spec https://www.rfc-editor.org/info/rfc1421 * RFC 1421: Privacy Enhancement for Internet Electronic Mail diff --git a/src/java.base/share/classes/sun/security/internal/InternalBinaryEncodable.java b/src/java.base/share/classes/sun/security/internal/InternalBinaryEncodable.java new file mode 100644 index 00000000000..72d0008a505 --- /dev/null +++ b/src/java.base/share/classes/sun/security/internal/InternalBinaryEncodable.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.security.internal; + +import java.security.BinaryEncodable; + +/** + * This class is a non-public subtype of BinaryEncodable. This type + * allows the BinaryEncodable list of permitted subtypes to change + * over time without causing pre-existing switches to fail because of an + * unrecognized subtype. + */ + +public final class InternalBinaryEncodable implements BinaryEncodable { + private InternalBinaryEncodable() {} +} diff --git a/test/jdk/sun/security/internal/CheckIBE.java b/test/jdk/sun/security/internal/CheckIBE.java new file mode 100644 index 00000000000..802cd336ebc --- /dev/null +++ b/test/jdk/sun/security/internal/CheckIBE.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * 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 8383608 + * @summary check that InternalBinaryEncodable exists + * @enablePreview + * @modules java.base/sun.security.internal + * @run main CheckIBE + */ + +import javax.crypto.EncryptedPrivateKeyInfo; +import java.security.AsymmetricKey; +import java.security.BinaryEncodable; +import java.security.KeyPair; +import java.security.PEM; +import java.security.cert.X509CRL; +import java.security.cert.X509Certificate; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; + +import sun.security.internal.InternalBinaryEncodable; + +/* + * This test verifies that BinaryEncodable has the expected set of permitted + * subtypes, including InternalBinaryEncodable. If this switch stops compiling, + * update the cases to match the BinaryEncodable permits list. + */ + +public class CheckIBE { + public static void main(String[] args) { + BinaryEncodable be = new PEM("TEST", "TEST"); + + switch (be) { + case AsymmetricKey ignored -> {} + case KeyPair ignored -> {} + case PKCS8EncodedKeySpec ignored -> {} + case X509EncodedKeySpec ignored -> {} + case EncryptedPrivateKeyInfo ignored -> {} + case X509Certificate ignored -> {} + case X509CRL ignored -> {} + case PEM ignored -> {} + case InternalBinaryEncodable ignored -> {} + } + } +} diff --git a/test/jdk/sun/security/internal/ExhaustiveBE.java b/test/jdk/sun/security/internal/ExhaustiveBE.java new file mode 100644 index 00000000000..37222a0310a --- /dev/null +++ b/test/jdk/sun/security/internal/ExhaustiveBE.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * 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 8383608 + * @summary verify switches over BinaryEncodable are not exhaustive + * @enablePreview + * @compile/fail ExhaustiveBE.java + */ + +import javax.crypto.EncryptedPrivateKeyInfo; +import java.security.AsymmetricKey; +import java.security.BinaryEncodable; +import java.security.KeyPair; +import java.security.PEM; +import java.security.cert.X509CRL; +import java.security.cert.X509Certificate; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; + +/* + * This test verifies that application code cannot exhaustively switch over + * BinaryEncodable by naming only the public permitted subtypes. Compilation + * must fail because application code needs a default case, or a + * BinaryEncodable case, to cover the internal permitted subtype + * InternalBinaryEncodable. + */ + +public class ExhaustiveBE { + public static void main(String[] args) { + BinaryEncodable be = new PEM("TEST", "TEST"); + + switch (be) { + case AsymmetricKey ignored -> {} + case KeyPair ignored -> {} + case PKCS8EncodedKeySpec ignored -> {} + case X509EncodedKeySpec ignored -> {} + case EncryptedPrivateKeyInfo ignored -> {} + case X509Certificate ignored -> {} + case X509CRL ignored -> {} + case PEM ignored -> {} + } + } +}