Merge master

This commit is contained in:
Alexey Ivanov 2026-06-09 13:00:42 +01:00
commit b12060246d
No known key found for this signature in database
GPG Key ID: 17F9DC22D25CB1D2
82 changed files with 3913 additions and 547 deletions

184
.git-blame-ignore-revs Normal file
View File

@ -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

View File

@ -1192,8 +1192,8 @@ var getJibProfilesDependencies = function (input, common) {
server: "jpg",
product: "jcov",
version: "3.0",
build_number: "5",
file: "bundles/jcov-3.0+5.zip",
build_number: "6",
file: "bundles/jcov-3.0+6.zip",
environment_name: "JCOV_HOME",
},

View File

@ -33,7 +33,7 @@ DEFAULT_VERSION_PATCH=0
DEFAULT_VERSION_EXTRA1=0
DEFAULT_VERSION_EXTRA2=0
DEFAULT_VERSION_EXTRA3=0
DEFAULT_VERSION_DATE=2027-03-27
DEFAULT_VERSION_DATE=2027-03-23
DEFAULT_VERSION_CLASSFILE_MAJOR=72 # "`$EXPR $DEFAULT_VERSION_FEATURE + 44`"
DEFAULT_VERSION_CLASSFILE_MINOR=0
DEFAULT_VERSION_DOCS_API_SINCE=11

View File

@ -109,7 +109,7 @@ endif
EMPTY :=
SPACE := $(EMPTY) $(EMPTY)
COMMA := ,
DNF_ARCHS := $(subst $(SPACE),$(COMMA),$(RPM_ARCHS))
DNF_ARCHS := $(foreach arch,$(RPM_ARCHS),--arch $(arch))
# Specify a dummy installation root, otherwise dnf will run into
# problems trying to reconcile with the local/system state
@ -123,7 +123,7 @@ DNF_DOWNLOAD_FLAGS := \
--disablerepo='*' \
$(DNF_REPOS) \
--resolve \
--archlist $(DNF_ARCHS) \
$(DNF_ARCHS) \
--forcearch $(RPM_ARCH) \
--installroot $(DNF_DUMMY_INSTALL_ROOT) \
--releasever $(BASE_OS_VERSION) \

View File

@ -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]);
%}
%}

View File

@ -4904,6 +4904,11 @@ void StubGenerator::generate_compiler_stubs() {
StubRoutines::_intpoly_assign = generate_intpoly_assign();
}
if (UseIntPoly25519Intrinsics) {
StubRoutines::_intpoly_mult_25519 = generate_intpoly_mult_25519();
StubRoutines::_intpoly_square_25519 = generate_intpoly_square_25519();
}
if (UseMD5Intrinsics) {
StubRoutines::_md5_implCompress = generate_md5_implCompress(StubId::stubgen_md5_implCompress_id);
StubRoutines::_md5_implCompressMB = generate_md5_implCompress(StubId::stubgen_md5_implCompressMB_id);

View File

@ -496,6 +496,9 @@ class StubGenerator: public StubCodeGenerator {
address generate_intpoly_montgomeryMult_P256();
address generate_intpoly_assign();
address generate_intpoly_mult_25519();
address generate_intpoly_square_25519();
// SHA3 stubs
void generate_sha3_stubs();

View File

@ -0,0 +1,306 @@
/*
* 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.
*/
#include "macroAssembler_x86.hpp"
#include "stubGenerator_x86_64.hpp"
#define __ _masm->
const int32_t term = 19;
const int32_t limbs = 5;
const int32_t bpl = 51;
const int32_t rem = 64 - bpl;
const uint64_t MASK = 0x7FFFFFFFFFFFF;
const uint64_t CARRY_ADD = 0x4000000000000;
// Multiplication operation for polynomial arithmetic in Curve25519.
//
// This is the same algorithm as used in Java, except we use pseudo-Mersenne
// reduction to reduce register pressure instead of using the full 10 columns
// in Java.
void multiply_25519_scalar(const Register aLimbs, const Register bLimbs, const Register rLimbs, Register c[], Register bArg, Register d, Register b, Register mask, MacroAssembler* _masm) {
for (int i = 0; i < limbs; i++) {
__ xorq(c[i], c[i]);
}
__ mov64(mask, MASK);
__ movq(bArg, bLimbs);
// Perform high/low multiplication with signed 5x51 bit limbs
for (int i = 0; i < limbs; i++) {
__ movq(b, Address(bArg, i * 8));
for (int j = 0; j < limbs; j++) {
__ movq(rax, Address(aLimbs, j * 8));
__ imulq(b); // rdx:rax = a * b
__ movq(d, rax);
__ andq(d, mask);
__ shrq(rax, bpl);
__ shlq(rdx, rem);
__ orq(rax, rdx);
// Fold in pseudo-Mersenne reduction
if ((i + j + 1) >= limbs) {
__ imulq(rax, rax, term);
}
if ((i + j) >= limbs) {
__ imulq(d, d, term);
}
__ addq(c[(i + j) % limbs], d);
__ addq(c[(i + j + 1) % limbs], rax);
}
}
// Carry-add with reduction from high limb
Register carry = bArg;
__ mov64(mask, CARRY_ADD);
__ movq(carry, mask);
// Limb 3
__ addq(carry, c[3]);
__ sarq(carry, bpl);
__ addq(c[4], carry);
__ shlq(carry, bpl);
__ subq(c[3], carry);
// Limb 4
__ movq(carry, mask);
__ addq(carry, c[4]);
__ sarq(carry, bpl);
// Reduce high order limb and fold back into low order limb
__ mov64(rax, term);
__ imulq(carry);
__ addq(c[0], rax);
__ shlq(carry, bpl);
__ subq(c[4], carry);
// Limbs 0 - 3
for (int i = 0; i < (limbs - 1); i++) {
__ movq(carry, mask);
__ addq(carry, c[i]);
__ sarq(carry, bpl);
__ addq(c[i + 1], carry);
__ shlq(carry, bpl);
__ subq(c[i], carry);
}
__ pop_ppx(rdx);
for (int i = 0; i < limbs; i++) {
__ movq(Address(rLimbs, i * 8), c[i]);
}
}
// Squaring operation for polynomial arithmetic in Curve25519.
//
// This is the same algorithm as used in Java, except we use pseudo-Mersenne
// reduction to reduce register pressure instead of using the full 10 columns
// in Java.
void square_25519_scalar(const Register aLimbs, const Register rLimbs, Register c[], Register aArg, Register d, Register carry, Register mask, MacroAssembler* _masm) {
for (int i = 0; i < limbs; i++) {
__ xorq(c[i], c[i]);
}
__ mov64(mask, MASK);
// Perform high/low multiplication with signed 5x51 bit limbs
for (int i = 0; i < limbs; i++) {
__ movq(aArg, Address(aLimbs, i * 8));
__ movq(rax, aArg);
__ imulq(aArg); // rdx:rax = a[j] * a[i]
__ movq(d, rax);
__ andq(d, mask);
__ shrq(rax, bpl);
__ shlq(rdx, rem);
__ orq(rax, rdx); // rax = dd
if ((i * 2 + 1) >= limbs) {
__ imulq(rax, rax, term);
}
if ((i * 2) >= limbs) {
__ imulq(d, d, term);
}
__ addq(c[(i * 2) % limbs], d);
__ addq(c[(i * 2 + 1) % limbs], rax);
for (int j = i + 1; j < limbs; j++) {
__ movq(rax, Address(aLimbs, j * 8));
__ imulq(aArg); // rdx:rax = a * a
__ movq(d, rax);
__ andq(d, mask);
__ shlq(d, 1);
__ shrq(rax, bpl);
__ shlq(rdx, rem);
__ orq(rax, rdx); // rax = dd
__ shlq(rax, 1);
if ((j + i + 1) >= limbs) {
__ imulq(rax, rax, term);
}
if ((j + i) >= limbs) {
__ imulq(d, d, term);
}
__ addq(c[(i + j) % limbs], d);
__ addq(c[(i + j + 1) % limbs], rax);
}
}
// Carry-add with reduction from high limb
// Limb 3
__ mov64(mask, CARRY_ADD);
__ movq(carry, mask);
__ addq(carry, c[3]);
__ sarq(carry, bpl);
__ addq(c[4], carry);
__ shlq(carry, bpl);
__ subq(c[3], carry);
// Limb 4
__ movq(carry, mask);
__ addq(carry, c[4]);
__ sarq(carry, bpl);
// Reduce high order limb and fold back into low order limb
__ mov64(rax, term);
__ imulq(carry);
__ addq(c[0], rax);
__ shlq(carry, bpl);
__ subq(c[4], carry);
// Limbs 0 - 3
for (int i = 0; i < (limbs - 1); i++) {
__ movq(carry, mask);
__ addq(carry, c[i]);
__ sarq(carry, bpl);
__ addq(c[i + 1], carry);
__ shlq(carry, bpl);
__ subq(c[i], carry);
}
__ pop_ppx(rdx);
for (int i = 0; i < limbs; i++) {
__ movq(Address(rLimbs, i * 8), c[i]);
}
}
address StubGenerator::generate_intpoly_mult_25519() {
StubId stub_id = StubId::stubgen_intpoly_mult_25519_id;
int entry_count = StubInfo::entry_count(stub_id);
assert(entry_count == 1, "sanity check");
address start = load_archive_data(stub_id);
if (start != nullptr) {
return start;
}
__ align(CodeEntryAlignment);
StubCodeMark mark(this, stub_id);
start = __ pc();
__ enter();
// Register Map
const Register aLimbs = c_rarg0; // rdi | rcx
const Register bLimbs = c_rarg1; // rsi | rdx
const Register rLimbs = c_rarg2; // rdx | r8
Register c[] = {r9, r10, r11, r12, r13};
Register bArg = r14;
Register d = r15;
Register b = rbp;
Register mask = rbx;
__ push_ppx(rbp);
__ push_ppx(rbx);
__ push_ppx(r12);
__ push_ppx(r13);
__ push_ppx(r14);
__ push_ppx(r15);
__ push_ppx(rdx);
multiply_25519_scalar(aLimbs, bLimbs, rLimbs, c, bArg, d, b, mask, _masm);
// __ pop_ppx(rdx); // restored in the helper already
__ pop_ppx(r15);
__ pop_ppx(r14);
__ pop_ppx(r13);
__ pop_ppx(r12);
__ pop_ppx(rbx);
__ pop_ppx(rbp);
__ leave();
__ ret(0);
// Record the stub entry and end
store_archive_data(stub_id, start, __ pc());
return start;
}
address StubGenerator::generate_intpoly_square_25519() {
StubId stub_id = StubId::stubgen_intpoly_square_25519_id;
int entry_count = StubInfo::entry_count(stub_id);
assert(entry_count == 1, "sanity check");
address start = load_archive_data(stub_id);
if (start != nullptr) {
return start;
}
__ align(CodeEntryAlignment);
StubCodeMark mark(this, stub_id);
start = __ pc();
__ enter();
// Register Map
const Register aLimbs = c_rarg0; // rdi | rcx
const Register rLimbs = c_rarg1; // rsi | rdx
Register c[] = {r9, r10, r11, r12, r13};
Register aArg = r14;
Register d = r15;
Register carry = rbp;
Register mask = rbx;
__ push_ppx(rbp);
__ push_ppx(rbx);
__ push_ppx(r12);
__ push_ppx(r13);
__ push_ppx(r14);
__ push_ppx(r15);
__ push_ppx(rdx);
square_25519_scalar(aLimbs, rLimbs, c, aArg, d, carry, mask, _masm);
// __ pop_ppx(rdx); // restored in the helper already
__ pop_ppx(r15);
__ pop_ppx(r14);
__ pop_ppx(r13);
__ pop_ppx(r12);
__ pop_ppx(rbx);
__ pop_ppx(rbp);
__ leave();
__ ret(0);
// Record the stub entry and end
store_archive_data(stub_id, start, __ pc());
return start;
}
#undef __

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2024, 2025, Intel Corporation. All rights reserved.
* Copyright (c) 2024, 2026, Intel Corporation. All rights reserved.
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -676,7 +676,7 @@ address StubGenerator::generate_intpoly_assign() {
// KNOWN Lengths:
// MontgomeryIntPolynP256: 5 = 4 + 1
// IntegerPolynomial1305: 5 = 4 + 1
// IntegerPolynomial25519: 10 = 8 + 2
// IntegerPolynomial25519: 5 = 4 + 1
// IntegerPolynomialP256: 10 = 8 + 2
// Curve25519OrderField: 10 = 8 + 2
// Curve25519OrderField: 10 = 8 + 2

View File

@ -1407,6 +1407,10 @@ void VM_Version::get_processor_features() {
FLAG_SET_DEFAULT(UseIntPolyIntrinsics, false);
}
if (FLAG_IS_DEFAULT(UseIntPoly25519Intrinsics)) {
UseIntPoly25519Intrinsics = true;
}
if (FLAG_IS_DEFAULT(UseMultiplyToLenIntrinsic)) {
UseMultiplyToLenIntrinsic = true;
}

View File

@ -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;

View File

@ -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 {

View File

@ -243,6 +243,16 @@ static LPVOID virtualAllocExNuma(HANDLE hProcess, LPVOID lpAddress, SIZE_T dwSiz
return result;
}
void* os::win32::lookup_kernelbase_symbol(const char* name) {
// Pass a small ebuf so dll_load logs failures, but don't use it here to avoid redundancy.
char ebuf[1024];
static void* const handle = os::dll_load("KernelBase", ebuf, sizeof(ebuf));
if (handle == nullptr) {
return nullptr;
}
return os::dll_lookup(handle, name);
}
// Logging wrapper for MapViewOfFileEx
static LPVOID mapViewOfFileEx(HANDLE hFileMappingObject, DWORD dwDesiredAccess, DWORD dwFileOffsetHigh,
DWORD dwFileOffsetLow, SIZE_T dwNumberOfBytesToMap, LPVOID lpBaseAddress) {
@ -3250,9 +3260,9 @@ char* os::map_memory_to_file(char* base, size_t size, int fd) {
assert(fd != -1, "File descriptor is not valid");
HANDLE fh = (HANDLE)_get_osfhandle(fd);
HANDLE fileMapping = CreateFileMapping(fh, nullptr, PAGE_READWRITE,
HANDLE file_mapping = CreateFileMapping(fh, nullptr, PAGE_READWRITE,
(DWORD)(size >> 32), (DWORD)(size & 0xFFFFFFFF), nullptr);
if (fileMapping == nullptr) {
if (file_mapping == nullptr) {
if (GetLastError() == ERROR_DISK_FULL) {
vm_exit_during_initialization(err_msg("Could not allocate sufficient disk space for Java heap"));
}
@ -3263,9 +3273,9 @@ char* os::map_memory_to_file(char* base, size_t size, int fd) {
return nullptr;
}
LPVOID addr = mapViewOfFileEx(fileMapping, FILE_MAP_WRITE, 0, 0, size, base);
LPVOID addr = mapViewOfFileEx(file_mapping, FILE_MAP_WRITE, 0, 0, size, base);
CloseHandle(fileMapping);
CloseHandle(file_mapping);
return (char*)addr;
}
@ -3278,40 +3288,75 @@ char* os::replace_existing_mapping_with_file_mapping(char* base, size_t size, in
return map_memory_to_file(base, size, fd);
}
// VirtualAlloc2 / MapViewOfFile3 (Windows 1803+). Resolved in os::init_2() via lookup_kernelbase_symbol.
os::win32::VirtualAlloc2Fn os::win32::VirtualAlloc2 = nullptr;
os::win32::MapViewOfFile3Fn os::win32::MapViewOfFile3 = nullptr;
static bool is_VirtualAlloc2_supported() {
return os::win32::VirtualAlloc2 != nullptr;
}
static bool is_MapViewOfFile3_supported() {
return os::win32::MapViewOfFile3 != nullptr;
}
// Multiple threads can race in this code but it's not possible to unmap small sections of
// virtual space to get requested alignment, like posix-like os's.
// Windows prevents multiple thread from remapping over each other so this loop is thread-safe.
static char* map_or_reserve_memory_aligned(size_t size, size_t alignment, int file_desc, MemTag mem_tag) {
static char* reserve_memory_aligned(size_t size, size_t alignment, MemTag mem_tag) {
assert(is_aligned(alignment, os::vm_allocation_granularity()),
"Alignment must be a multiple of allocation granularity (page size)");
"Alignment must be a multiple of allocation granularity");
assert(is_aligned(size, os::vm_allocation_granularity()),
"Size must be a multiple of allocation granularity (page size)");
"Size must be a multiple of allocation granularity");
size_t extra_size = size + alignment;
assert(extra_size >= size, "overflow, size is too large to allow alignment");
char* aligned_base = nullptr;
static const int max_attempts = 20;
constexpr int max_attempts = 20;
for (int attempt = 0; attempt < max_attempts && aligned_base == nullptr; attempt ++) {
char* extra_base = file_desc != -1 ? os::map_memory_to_file(extra_size, file_desc, mem_tag) :
os::reserve_memory(extra_size, mem_tag);
char* extra_base = os::reserve_memory(extra_size, mem_tag);
if (extra_base == nullptr) {
return nullptr;
}
// Do manual alignment
aligned_base = align_up(extra_base, alignment);
os::release_memory(extra_base, extra_size);
if (file_desc != -1) {
os::unmap_memory(extra_base, extra_size);
} else {
os::release_memory(extra_base, extra_size);
// A racing thread may have taken this region instead of us, which is why we loop and retry.
aligned_base = os::attempt_reserve_memory_at(aligned_base, size, mem_tag);
}
assert(aligned_base != nullptr,
"Did not manage to reserve after %d attempts (size %zu, alignment %zu)", max_attempts, size, alignment);
return aligned_base;
}
// Similar to reserve_memory_aligned, other reservation/mapping requests can race with this function.
static char* map_memory_aligned(size_t size, size_t alignment, int file_desc, MemTag mem_tag) {
assert(is_aligned(alignment, os::vm_allocation_granularity()),
"Alignment must be a multiple of allocation granularity");
assert(is_aligned(size, os::vm_allocation_granularity()),
"Size must be a multiple of allocation granularity");
size_t extra_size = size + alignment;
assert(extra_size >= size, "overflow, size is too large to allow alignment");
char* aligned_base = nullptr;
constexpr int max_attempts = 20;
for (int attempt = 0; attempt < max_attempts && aligned_base == nullptr; attempt ++) {
char* extra_base = os::map_memory_to_file(extra_size, file_desc, mem_tag);
if (extra_base == nullptr) {
return nullptr;
}
aligned_base = align_up(extra_base, alignment);
os::unmap_memory(extra_base, extra_size);
// Attempt to map, into the just vacated space, the slightly smaller aligned area.
// Which may fail, hence the loop.
aligned_base = file_desc != -1 ? os::attempt_map_memory_to_file_at(aligned_base, size, file_desc, mem_tag) :
os::attempt_reserve_memory_at(aligned_base, size, mem_tag);
// A racing thread may have taken this region instead of us, which is why we loop and retry.
aligned_base = os::attempt_map_memory_to_file_at(aligned_base, size, file_desc, mem_tag);
}
assert(aligned_base != nullptr,
@ -3320,6 +3365,84 @@ static char* map_or_reserve_memory_aligned(size_t size, size_t alignment, int fi
return aligned_base;
}
// MapViewOfFile3 supports alignment natively.
static char* map_memory_aligned_va2(size_t size, size_t alignment, int file_desc, MemTag mem_tag) {
assert(file_desc != -1, "File descriptor should not be -1");
assert(is_aligned(alignment, os::vm_allocation_granularity()),
"Alignment must be a multiple of allocation granularity");
assert(is_aligned(size, os::vm_allocation_granularity()),
"Size must be a multiple of allocation granularity");
MEM_ADDRESS_REQUIREMENTS requirements = {0};
requirements.Alignment = alignment;
MEM_EXTENDED_PARAMETER param = {0};
param.Type = MemExtendedParameterAddressRequirements;
param.Pointer = &requirements;
char* aligned_base = nullptr;
// File-backed aligned mapping.
HANDLE fh = (HANDLE)_get_osfhandle(file_desc);
HANDLE file_mapping = CreateFileMapping(fh, nullptr, PAGE_READWRITE,(DWORD)(size >> 32), (DWORD)(size & 0xFFFFFFFF), nullptr);
DWORD err = GetLastError();
if (file_mapping != nullptr) {
aligned_base = (char*)os::win32::MapViewOfFile3(
file_mapping,
GetCurrentProcess(),
nullptr, // let the system choose an aligned address
0, // offset
size,
0, // no special allocation type flags
PAGE_READWRITE,
&param, 1);
err = GetLastError();
CloseHandle(file_mapping);
}
if (aligned_base != nullptr) {
assert(is_aligned(aligned_base, alignment), "Result must be aligned");
MemTracker::record_virtual_memory_reserve_and_commit(aligned_base, size, CALLER_PC, mem_tag);
return aligned_base;
}
log_trace(os)("Aligned allocation via MapViewOfFile3 failed, falling back to retry loop. GetLastError->%lu.", err);
return map_memory_aligned(size, alignment, file_desc, mem_tag);
}
// VirtualAlloc2 supports alignment natively.
static char* reserve_memory_aligned_va2(size_t size, size_t alignment, MemTag mem_tag) {
assert(is_aligned(alignment, os::vm_allocation_granularity()),
"Alignment must be a multiple of allocation granularity");
assert(is_aligned(size, os::vm_allocation_granularity()),
"Size must be a multiple of allocation granularity");
MEM_ADDRESS_REQUIREMENTS requirements = {0};
requirements.Alignment = alignment;
MEM_EXTENDED_PARAMETER param = {0};
param.Type = MemExtendedParameterAddressRequirements;
param.Pointer = &requirements;
char* aligned_base = nullptr;
// Anonymous aligned reservation.
aligned_base = (char*)os::win32::VirtualAlloc2(
GetCurrentProcess(),
nullptr, // let the system choose an aligned address
size,
MEM_RESERVE,
PAGE_READWRITE,
&param, 1);
if (aligned_base != nullptr) {
assert(is_aligned(aligned_base, alignment), "Result must be aligned");
MemTracker::record_virtual_memory_reserve(aligned_base, size, CALLER_PC, mem_tag);
return aligned_base;
}
log_trace(os)("Aligned allocation via VirtualAlloc2 failed, falling back to retry loop. GetLastError->%lu.", GetLastError());
return reserve_memory_aligned(size, alignment, mem_tag);
}
size_t os::commit_memory_limit() {
BOOL is_in_job_object = false;
BOOL res = IsProcessInJob(GetCurrentProcess(), nullptr, &is_in_job_object);
@ -3367,11 +3490,17 @@ size_t os::reserve_memory_limit() {
char* os::reserve_memory_aligned(size_t size, size_t alignment, MemTag mem_tag, bool exec) {
// exec can be ignored
return map_or_reserve_memory_aligned(size, alignment, -1/* file_desc */, mem_tag);
if (is_VirtualAlloc2_supported()) {
return reserve_memory_aligned_va2(size, alignment, mem_tag);
}
return reserve_memory_aligned(size, alignment, mem_tag);
}
char* os::map_memory_to_file_aligned(size_t size, size_t alignment, int fd, MemTag mem_tag) {
return map_or_reserve_memory_aligned(size, alignment, fd, mem_tag);
if (is_MapViewOfFile3_supported()) {
return map_memory_aligned_va2(size, alignment, fd, mem_tag);
}
return map_memory_aligned(size, alignment, fd, mem_tag);
}
char* os::pd_reserve_memory(size_t bytes, bool exec) {
@ -4588,21 +4717,21 @@ jint os::init_2(void) {
// Lookup SetThreadDescription - the docs state we must use runtime-linking of
// kernelbase.dll, so that is what we do.
HINSTANCE _kernelbase = LoadLibrary(TEXT("kernelbase.dll"));
if (_kernelbase != nullptr) {
_SetThreadDescription =
reinterpret_cast<SetThreadDescriptionFnPtr>(
GetProcAddress(_kernelbase,
"SetThreadDescription"));
_SetThreadDescription = reinterpret_cast<SetThreadDescriptionFnPtr>(
os::win32::lookup_kernelbase_symbol("SetThreadDescription"));
#ifdef ASSERT
_GetThreadDescription =
reinterpret_cast<GetThreadDescriptionFnPtr>(
GetProcAddress(_kernelbase,
"GetThreadDescription"));
_GetThreadDescription = reinterpret_cast<GetThreadDescriptionFnPtr>(
os::win32::lookup_kernelbase_symbol("GetThreadDescription"));
#endif
}
log_info(os, thread)("The SetThreadDescription API is%s available.", _SetThreadDescription == nullptr ? " not" : "");
// Prepare KernelBase APIs (VirtualAlloc2, MapViewOfFile3) if available (Windows version 1803).
os::win32::VirtualAlloc2 = reinterpret_cast<os::win32::VirtualAlloc2Fn>(
os::win32::lookup_kernelbase_symbol("VirtualAlloc2"));
os::win32::MapViewOfFile3 = reinterpret_cast<os::win32::MapViewOfFile3Fn>(
os::win32::lookup_kernelbase_symbol("MapViewOfFile3"));
log_debug(os)("VirtualAlloc2 is%s available.", os::win32::VirtualAlloc2 == nullptr ? " not" : "");
log_debug(os)("MapViewOfFile3 is%s available.", os::win32::MapViewOfFile3 == nullptr ? " not" : "");
return JNI_OK;
}

View File

@ -109,6 +109,19 @@ class os::win32 {
// load dll from Windows system directory or Windows directory
static HINSTANCE load_Windows_dll(const char* name, char *ebuf, int ebuflen);
// Resolve a symbol from KernelBase.dll, returns nullptr if not found.
static void* lookup_kernelbase_symbol(const char* name);
// VirtualAlloc2 (since Windows version 1803)
// Resolved from KernelBase during os::init_2() or nullptr if unavailable.
typedef PVOID (WINAPI *VirtualAlloc2Fn)(HANDLE, PVOID, SIZE_T, ULONG, ULONG, MEM_EXTENDED_PARAMETER*, ULONG);
static VirtualAlloc2Fn VirtualAlloc2;
// MapViewOfFile3 (since Windows version 1803)
// Resolved from KernelBase during os::init_2() or nullptr if unavailable.
typedef PVOID (WINAPI *MapViewOfFile3Fn)(HANDLE, HANDLE, PVOID, ULONG64, SIZE_T, ULONG, ULONG, MEM_EXTENDED_PARAMETER*, ULONG);
static MapViewOfFile3Fn MapViewOfFile3;
private:
static void initialize_performance_counter();

View File

@ -31,7 +31,10 @@
#include "memory/metaspaceClosure.hpp"
#include "memory/resourceArea.hpp"
#include "oops/instanceKlass.hpp"
#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/timerTrace.hpp"
#include "utilities/concurrentHashTable.inline.hpp"
#include "utilities/concurrentHashTableTasks.inline.hpp"
#include "utilities/ostream.hpp"
#include "utilities/tableStatistics.hpp"
@ -239,10 +242,24 @@ void Dictionary::verify() {
}
void Dictionary::print_table_statistics(outputStream* st, const char* table_name) {
static TableStatistics ts;
TableStatistics stats;
auto sz = [&] (InstanceKlass** val) {
return sizeof(**val);
};
ts = _table->statistics_get(Thread::current(), sz, ts);
ts.print(st, table_name);
Thread* thread = Thread::current();
ConcurrentTable::StatisticsTask sts(_table);
if (!sts.prepare(thread)) {
st->print_cr("Failed to take statistics");
return;
}
TraceTime timer("GetStatistics", TRACETIME_LOG(Debug, perf));
while (sts.do_task(thread, sz)) {
sts.pause(thread);
if (thread->is_Java_thread()) {
ThreadBlockInVM tbivm(JavaThread::cast(thread));
}
sts.cont(thread);
}
stats = sts.done(thread);
stats.print(st, table_name);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2025, 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
@ -527,6 +527,10 @@ bool vmIntrinsics::disabled_by_jvm_flags(vmIntrinsics::ID id) {
case vmIntrinsics::_intpoly_assign:
if (!UseIntPolyIntrinsics) return true;
break;
case vmIntrinsics::_intpoly_mult_25519:
case vmIntrinsics::_intpoly_square_25519:
if (!UseIntPoly25519Intrinsics) return true;
break;
case vmIntrinsics::_updateBytesCRC32C:
case vmIntrinsics::_updateDirectByteBufferCRC32C:
if (!UseCRC32CIntrinsics) return true;

View File

@ -549,6 +549,13 @@ class methodHandle;
do_name(intPolyAssign_name, "conditionalAssign") \
do_signature(intPolyAssign_signature, "(I[J[J)V") \
\
/* support for sun.security.util.math.intpoly.IntegerPolynomial25519 */ \
do_class(sun_security_util_math_intpoly_IntegerPolynomial25519, "sun/security/util/math/intpoly/IntegerPolynomial25519") \
do_intrinsic(_intpoly_mult_25519, sun_security_util_math_intpoly_IntegerPolynomial25519, intPolyMult_name, intPolyMult_signature, F_R) \
do_intrinsic(_intpoly_square_25519, sun_security_util_math_intpoly_IntegerPolynomial25519, intPolySquare_name, intPolySquare_signature, F_R) \
do_name(intPolySquare_name, "square") \
do_signature(intPolySquare_signature, "([J[J)V") \
\
/* support for java.util.Base64.Encoder*/ \
do_class(java_util_Base64_Encoder, "java/util/Base64$Encoder") \
do_intrinsic(_base64_encodeBlock, java_util_Base64_Encoder, encodeBlock_name, encodeBlock_signature, F_R) \

View File

@ -49,7 +49,14 @@ void CardTableRS::scan_old_to_young_refs(TenuredGeneration* tg, HeapWord* saved_
void CardTableRS::maintain_old_to_young_invariant(TenuredGeneration* old_gen,
bool is_young_gen_empty) {
if (is_young_gen_empty) {
clear_MemRegion(old_gen->prev_used_region());
MemRegion prev_used_mr = old_gen->prev_used_region();
if (!prev_used_mr.is_empty()) {
clear_MemRegion(prev_used_mr);
}
{
MemRegion old_gen_committed{old_gen->space()->bottom(), old_gen->space()->end()};
verify_region(old_gen_committed, clean_card_val(), true);
}
} else {
MemRegion used_mr = old_gen->used_region();
MemRegion prev_used_mr = old_gen->prev_used_region();
@ -59,7 +66,9 @@ void CardTableRS::maintain_old_to_young_invariant(TenuredGeneration* old_gen,
}
// No idea which card contains old-to-young pointer, so dirtying cards for
// the entire used part of old-gen conservatively.
dirty_MemRegion(used_mr);
if (!used_mr.is_empty()) {
dirty_MemRegion(used_mr);
}
}
}

View File

@ -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 " \

View File

@ -1203,19 +1203,13 @@ void ShenandoahConcurrentGC::op_final_update_refs() {
heap->verifier()->verify_roots_in_to_space(_generation);
}
// If we are running in generational mode and this is an aging cycle, this will also age active
// regions that haven't been used for allocation.
// If we are running in generational mode, this will also age active regions that
// haven't been used for allocation.
heap->update_heap_region_states(true /*concurrent*/);
heap->set_update_refs_in_progress(false);
heap->set_has_forwarded_objects(false);
if (heap->mode()->is_generational() && heap->is_concurrent_old_mark_in_progress()) {
// Aging_cycle is only relevant during evacuation cycle for individual objects and during final mark for
// entire regions. Both of these relevant operations occur before final update refs.
ShenandoahGenerationalHeap::heap()->set_aging_cycle(false);
}
if (ShenandoahVerify) {
ShenandoahTimingsTracker v(ShenandoahPhaseTimings::final_update_refs_verify);
heap->verifier()->verify_after_update_refs(_generation);

View File

@ -53,8 +53,7 @@ ShenandoahGenerationalControlThread::ShenandoahGenerationalControlThread() :
_requested_generation(nullptr),
_gc_mode(none),
_degen_point(ShenandoahGC::_degenerated_unset),
_heap(ShenandoahGenerationalHeap::heap()),
_age_period(0) {
_heap(ShenandoahGenerationalHeap::heap()) {
shenandoah_assert_generational();
set_name("ShenControl");
create_and_start();
@ -230,15 +229,6 @@ void ShenandoahGenerationalControlThread::maybe_print_young_region_ages() const
}
}
void ShenandoahGenerationalControlThread::maybe_set_aging_cycle() {
if (_age_period-- == 0) {
_heap->set_aging_cycle(true);
_age_period = ShenandoahAgingCyclePeriod - 1;
} else {
_heap->set_aging_cycle(false);
}
}
void ShenandoahGenerationalControlThread::run_gc_cycle(const ShenandoahGCRequest& request) {
log_debug(gc, thread)("Starting GC (%s): %s, %s", gc_mode_name(gc_mode()), GCCause::to_string(request.cause), request.generation->name());
@ -534,9 +524,6 @@ void ShenandoahGenerationalControlThread::service_concurrent_cycle(ShenandoahGen
// At this point:
// if (generation == YOUNG), this is a normal young cycle or a bootstrap cycle
// if (generation == GLOBAL), this is a GLOBAL cycle
// In either case, we want to age old objects if this is an aging cycle
maybe_set_aging_cycle();
ShenandoahGCSession session(cause, generation);
TraceCollectorStats tcs(_heap->monitoring_support()->concurrent_collection_counters());
@ -615,7 +602,6 @@ bool ShenandoahGenerationalControlThread::check_cancellation_or_degen(Shenandoah
void ShenandoahGenerationalControlThread::service_stw_full_cycle(GCCause::Cause cause) {
_heap->increment_total_collections(true);
ShenandoahGCSession session(cause, _heap->global_generation());
maybe_set_aging_cycle();
ShenandoahFullGC gc;
gc.collect(cause);
_degen_point = ShenandoahGC::_degenerated_unset;

View File

@ -80,9 +80,6 @@ private:
// A reference to the heap
ShenandoahGenerationalHeap* _heap;
// This is used to keep track of whether to age objects during the current cycle.
uint _age_period;
// This is true when the old generation cycle is in an interruptible phase (i.e., marking or
// preparing for mark).
ShenandoahSharedFlag _allow_old_preemption;
@ -142,9 +139,6 @@ private:
void notify_control_thread(GCCause::Cause cause, ShenandoahGeneration* generation);
void notify_control_thread(MonitorLocker& ml, GCCause::Cause cause, ShenandoahGeneration* generation);
// Configure the heap to age objects and regions if the aging period has elapsed.
void maybe_set_aging_cycle();
// Take the _control_lock and check for a request to run a gc cycle. If a request is found,
// the `prepare` methods are used to configure the heap and update heuristics accordingly.
void check_for_request(ShenandoahGCRequest& request);

View File

@ -312,11 +312,7 @@ void ShenandoahPrepareForGenerationalCompactionObjectClosure::do_object(oop p) {
// After full gc compaction, all regions have age 0. Embed the region's age into the object's age in order to preserve
// tenuring progress.
if (_heap->is_aging_cycle()) {
ShenandoahHeap::increase_object_age(p, from_region_age + 1);
} else {
ShenandoahHeap::increase_object_age(p, from_region_age);
}
ShenandoahHeap::increase_object_age(p, from_region_age + 1);
if (_young_compact_point + obj_size > _young_to_region->end()) {
ShenandoahHeapRegion* new_to_region;

View File

@ -347,7 +347,7 @@ oop ShenandoahGenerationalHeap::try_evacuate_object(oop p, Thread* thread, uint
oop copy_val = cast_to_oop(copy);
// Update the age of the evacuated object
if (TO_GENERATION == YOUNG_GENERATION && is_aging_cycle()) {
if (TO_GENERATION == YOUNG_GENERATION) {
increase_object_age(copy_val, from_region_age + 1);
}
@ -975,7 +975,7 @@ public:
// There have been allocations in this region since the start of the cycle.
// Any objects new to this region must not assimilate elevated age.
r->reset_age();
} else if (ShenandoahGenerationalHeap::heap()->is_aging_cycle()) {
} else {
r->increment_age();
}
}

View File

@ -61,21 +61,10 @@ public:
private:
// ---------- Evacuations and Promotions
//
// True when regions and objects should be aged during the current cycle
ShenandoahSharedFlag _is_aging_cycle;
// Age census used for adapting tenuring threshold
ShenandoahAgeCensus* _age_census;
public:
void set_aging_cycle(bool cond) {
_is_aging_cycle.set_cond(cond);
}
inline bool is_aging_cycle() const {
return _is_aging_cycle.is_set();
}
// Return the age census object for young gen
ShenandoahAgeCensus* age_census() const {
return _age_census;

View File

@ -66,7 +66,6 @@ class ShenandoahFreeSet;
class ShenandoahConcurrentMark;
class ShenandoahFullGC;
class ShenandoahMonitoringSupport;
class ShenandoahPacer;
class ShenandoahReferenceProcessor;
class ShenandoahUncommitThread;
class ShenandoahVerifier;
@ -534,7 +533,6 @@ private:
ShenandoahCollectorPolicy* _shenandoah_policy;
ShenandoahMode* _gc_mode;
ShenandoahFreeSet* _free_set;
ShenandoahPacer* _pacer;
ShenandoahVerifier* _verifier;
ShenandoahPhaseTimings* _phase_timings;
@ -559,7 +557,6 @@ public:
ShenandoahCollectorPolicy* shenandoah_policy() const { return _shenandoah_policy; }
ShenandoahMode* mode() const { return _gc_mode; }
ShenandoahFreeSet* free_set() const { return _free_set; }
ShenandoahPacer* pacer() const { return _pacer; }
ShenandoahPhaseTimings* phase_timings() const { return _phase_timings; }

View File

@ -529,10 +529,6 @@
"Allow young generation collections to suspend concurrent" \
" marking in the old generation.") \
\
product(uintx, ShenandoahAgingCyclePeriod, 1, EXPERIMENTAL, \
"With generational mode, increment the age of objects and" \
"regions each time this many young-gen GC cycles are completed.") \
\
develop(bool, ShenandoahEnableCardStats, false, \
"Enable statistics collection related to clean & dirty cards") \
\

View File

@ -819,6 +819,8 @@ bool C2Compiler::is_intrinsic_supported(vmIntrinsics::ID id) {
case vmIntrinsics::_poly1305_processBlocks:
case vmIntrinsics::_intpoly_montgomeryMult_P256:
case vmIntrinsics::_intpoly_assign:
case vmIntrinsics::_intpoly_mult_25519:
case vmIntrinsics::_intpoly_square_25519:
case vmIntrinsics::_updateCRC32:
case vmIntrinsics::_updateBytesCRC32:
case vmIntrinsics::_updateByteBufferCRC32:

View File

@ -2272,6 +2272,8 @@ void ConnectionGraph::process_call_arguments(CallNode *call) {
strcmp(call->as_CallLeaf()->_name, "poly1305_processBlocks") == 0 ||
strcmp(call->as_CallLeaf()->_name, "intpoly_montgomeryMult_P256") == 0 ||
strcmp(call->as_CallLeaf()->_name, "intpoly_assign") == 0 ||
strcmp(call->as_CallLeaf()->_name, "intpoly_mult_25519") == 0 ||
strcmp(call->as_CallLeaf()->_name, "intpoly_square_25519") == 0 ||
strcmp(call->as_CallLeaf()->_name, "ghash_processBlocks") == 0 ||
strcmp(call->as_CallLeaf()->_name, "chacha20Block") == 0 ||
strcmp(call->as_CallLeaf()->_name, "kyberNtt") == 0 ||

View File

@ -666,6 +666,10 @@ bool LibraryCallKit::try_to_inline(int predicate) {
return inline_intpoly_montgomeryMult_P256();
case vmIntrinsics::_intpoly_assign:
return inline_intpoly_assign();
case vmIntrinsics::_intpoly_mult_25519:
return inline_intpoly_mult_25519();
case vmIntrinsics::_intpoly_square_25519:
return inline_intpoly_square_25519();
case vmIntrinsics::_encodeISOArray:
case vmIntrinsics::_encodeByteISOArray:
return inline_encodeISOArray(false);
@ -8373,6 +8377,70 @@ bool LibraryCallKit::inline_intpoly_assign() {
return true;
}
bool LibraryCallKit::inline_intpoly_mult_25519() {
address stubAddr;
const char *stubName;
assert(UseIntPoly25519Intrinsics, "need intpoly25519 intrinsics support");
assert(callee()->signature()->size() == 3, "intpoly_mult_25519 has %d parameters", callee()->signature()->size());
stubAddr = StubRoutines::intpoly_mult_25519();
stubName = "intpoly_mult_25519";
if (!stubAddr) return false;
null_check_receiver(); // null-check receiver
if (stopped()) return true;
Node* a = argument(1);
Node* b = argument(2);
Node* r = argument(3);
a = must_be_not_null(a, true);
b = must_be_not_null(b, true);
r = must_be_not_null(r, true);
Node* a_start = array_element_address(a, intcon(0), T_LONG);
assert(a_start, "a array is null");
Node* b_start = array_element_address(b, intcon(0), T_LONG);
assert(b_start, "b array is null");
Node* r_start = array_element_address(r, intcon(0), T_LONG);
assert(r_start, "r array is null");
Node* call = make_runtime_call(RC_LEAF | RC_NO_FP,
OptoRuntime::intpoly_mult_25519_Type(),
stubAddr, stubName, TypePtr::BOTTOM,
a_start, b_start, r_start);
return true;
}
bool LibraryCallKit::inline_intpoly_square_25519() {
address stubAddr;
const char *stubName;
assert(UseIntPoly25519Intrinsics, "need intpoly25519 intrinsics support");
assert(callee()->signature()->size() == 2, "intpoly_mult_25519 has %d parameters", callee()->signature()->size());
stubAddr = StubRoutines::intpoly_square_25519();
stubName = "intpoly_square_25519";
if (!stubAddr) return false;
null_check_receiver(); // null-check receiver
if (stopped()) return true;
Node* a = argument(1);
Node* r = argument(2);
a = must_be_not_null(a, true);
r = must_be_not_null(r, true);
Node* a_start = array_element_address(a, intcon(0), T_LONG);
assert(a_start, "a array is null");
Node* r_start = array_element_address(r, intcon(0), T_LONG);
assert(r_start, "r array is null");
Node* call = make_runtime_call(RC_LEAF | RC_NO_FP,
OptoRuntime::intpoly_square_25519_Type(),
stubAddr, stubName, TypePtr::BOTTOM,
a_start, r_start);
return true;
}
//------------------------------inline_digestBase_implCompress-----------------------
//
// Calculate MD5 for single-block byte[] array.

View File

@ -343,6 +343,8 @@ class LibraryCallKit : public GraphKit {
bool inline_poly1305_processBlocks();
bool inline_intpoly_montgomeryMult_P256();
bool inline_intpoly_assign();
bool inline_intpoly_mult_25519();
bool inline_intpoly_square_25519();
bool inline_digestBase_implCompress(vmIntrinsics::ID id);
bool inline_keccak(vmIntrinsics::ID id);
bool inline_digestBase_implCompressMB(int predicate);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 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
@ -237,6 +237,8 @@ const TypeFunc* OptoRuntime::_string_IndexOf_Type = nullptr;
const TypeFunc* OptoRuntime::_poly1305_processBlocks_Type = nullptr;
const TypeFunc* OptoRuntime::_intpoly_montgomeryMult_P256_Type = nullptr;
const TypeFunc* OptoRuntime::_intpoly_assign_Type = nullptr;
const TypeFunc* OptoRuntime::_intpoly_mult_25519_Type = nullptr;
const TypeFunc* OptoRuntime::_intpoly_square_25519_Type = nullptr;
const TypeFunc* OptoRuntime::_updateBytesCRC32_Type = nullptr;
const TypeFunc* OptoRuntime::_updateBytesCRC32C_Type = nullptr;
const TypeFunc* OptoRuntime::_updateBytesAdler32_Type = nullptr;
@ -1786,6 +1788,41 @@ static const TypeFunc* make_intpoly_assign_Type() {
return TypeFunc::make(domain, range);
}
static const TypeFunc* make_intpoly_mult_25519_Type() {
int argcnt = 3;
const Type** fields = TypeTuple::fields(argcnt);
int argp = TypeFunc::Parms;
fields[argp++] = TypePtr::NOTNULL; // a array
fields[argp++] = TypePtr::NOTNULL; // b array
fields[argp++] = TypePtr::NOTNULL; // r(esult) array
assert(argp == TypeFunc::Parms + argcnt, "correct decoding");
const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
// result type needed
fields = TypeTuple::fields(1);
fields[TypeFunc::Parms + 0] = nullptr; // void
const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
return TypeFunc::make(domain, range);
}
static const TypeFunc* make_intpoly_square_25519_Type() {
int argcnt = 2;
const Type** fields = TypeTuple::fields(argcnt);
int argp = TypeFunc::Parms;
fields[argp++] = TypePtr::NOTNULL; // a array
fields[argp++] = TypePtr::NOTNULL; // r(esult) array
assert(argp == TypeFunc::Parms + argcnt, "correct decoding");
const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
// result type needed
fields = TypeTuple::fields(1);
fields[TypeFunc::Parms + 0] = nullptr; // void
const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
return TypeFunc::make(domain, range);
}
//------------- Interpreter state for on stack replacement
static const TypeFunc* make_osr_end_Type() {
// create input type (domain)
@ -2354,6 +2391,8 @@ void OptoRuntime::initialize_types() {
_poly1305_processBlocks_Type = make_poly1305_processBlocks_Type();
_intpoly_montgomeryMult_P256_Type = make_intpoly_montgomeryMult_P256_Type();
_intpoly_assign_Type = make_intpoly_assign_Type();
_intpoly_mult_25519_Type = make_intpoly_mult_25519_Type();
_intpoly_square_25519_Type = make_intpoly_square_25519_Type();
_updateBytesCRC32_Type = make_updateBytesCRC32_Type();
_updateBytesCRC32C_Type = make_updateBytesCRC32C_Type();
_updateBytesAdler32_Type = make_updateBytesAdler32_Type();

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 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
@ -190,6 +190,8 @@ class OptoRuntime : public AllStatic {
static const TypeFunc* _poly1305_processBlocks_Type;
static const TypeFunc* _intpoly_montgomeryMult_P256_Type;
static const TypeFunc* _intpoly_assign_Type;
static const TypeFunc* _intpoly_mult_25519_Type;
static const TypeFunc* _intpoly_square_25519_Type;
static const TypeFunc* _updateBytesCRC32_Type;
static const TypeFunc* _updateBytesCRC32C_Type;
static const TypeFunc* _updateBytesAdler32_Type;
@ -687,6 +689,18 @@ private:
return _intpoly_assign_Type;
}
// IntegerPolynomial25519 multiply function
static inline const TypeFunc* intpoly_mult_25519_Type() {
assert(_intpoly_mult_25519_Type != nullptr, "should be initialized");
return _intpoly_mult_25519_Type;
}
// IntegerPolynomial25519 square function
static inline const TypeFunc* intpoly_square_25519_Type() {
assert(_intpoly_square_25519_Type != nullptr, "should be initialized");
return _intpoly_square_25519_Type;
}
/**
* int updateBytesCRC32(int crc, byte* b, int len)
*/

View File

@ -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

View File

@ -1237,9 +1237,6 @@ void frame::interpreter_frame_verify_monitor(BasicObjectLock* value) const {
#ifndef PRODUCT
// Returns true iff the address p is readable and *(intptr_t*)p != errvalue
extern "C" bool dbg_is_safe(const void* p, intptr_t errvalue);
class FrameValuesOopClosure: public OopClosure, public DerivedOopClosure {
private:
GrowableArray<oop*>* _oops;
@ -1269,17 +1266,13 @@ public:
_derived->push(derived_loc);
}
bool is_good(oop* p) {
return *p == nullptr || (dbg_is_safe(*p, -1) && dbg_is_safe((*p)->klass_without_asserts(), -1) && oopDesc::is_oop_or_null(*p));
}
void describe(FrameValues& values, int frame_no) {
for (int i = 0; i < _oops->length(); i++) {
oop* p = _oops->at(i);
values.describe(frame_no, (intptr_t*)p, err_msg("oop%s for #%d", is_good(p) ? "" : " (BAD)", frame_no));
values.describe(frame_no, (intptr_t*)p, err_msg("oop for #%d", frame_no));
}
for (int i = 0; i < _narrow_oops->length(); i++) {
narrowOop* p = _narrow_oops->at(i);
// we can't check for bad compressed oops, as decoding them might crash
values.describe(frame_no, (intptr_t*)p, err_msg("narrow oop for #%d", frame_no));
}
assert(_base->length() == _derived->length(), "should be the same");

View File

@ -229,9 +229,13 @@ const int ObjectAlignmentInBytes = 8;
\
product(bool, UsePoly1305Intrinsics, false, DIAGNOSTIC, \
"Use intrinsics for sun.security.util.math.intpoly") \
product(bool, UseIntPolyIntrinsics, false, DIAGNOSTIC, \
\
product(bool, UseIntPolyIntrinsics, false, DIAGNOSTIC, \
"Use intrinsics for sun.security.util.math.intpoly.MontgomeryIntegerPolynomialP256") \
\
product(bool, UseIntPoly25519Intrinsics, false, DIAGNOSTIC, \
"Use intrinsics for sun.security.util.math.intpoly.IntegerPolynomial25519") \
\
product(size_t, LargePageSizeInBytes, 0, \
"Maximum large page size used (0 will use the default large " \
"page size for the environment as the maximum) " \

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2025, Red Hat, Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -801,6 +801,12 @@
intpoly_montgomeryMult_P256, intpoly_montgomeryMult_P256) \
do_stub(compiler, intpoly_assign) \
do_entry(compiler, intpoly_assign, intpoly_assign, intpoly_assign) \
do_stub(compiler, intpoly_mult_25519) \
do_entry(compiler, intpoly_mult_25519, \
intpoly_mult_25519, intpoly_mult_25519) \
do_stub(compiler, intpoly_square_25519) \
do_entry(compiler, intpoly_square_25519, \
intpoly_square_25519, intpoly_square_25519) \
do_stub(compiler, md5_implCompress) \
do_entry(compiler, md5_implCompress, md5_implCompress, \
md5_implCompress) \

View File

@ -654,17 +654,20 @@ public:
// VM.systemdictionary -verbose: for dumping the system dictionary table
//
class VM_DumpHashtable : public VM_Operation {
public:
enum DumpKind {
DumpSymbols,
DumpStrings,
DumpSysDict
};
private:
outputStream* _out;
int _which;
DumpKind _which;
bool _verbose;
public:
enum {
DumpSymbols = 1 << 0,
DumpStrings = 1 << 1,
DumpSysDict = 1 << 2 // not implemented yet
};
VM_DumpHashtable(outputStream* out, int which, bool verbose) {
VM_DumpHashtable(outputStream* out, DumpKind which, bool verbose) {
_out = out;
_which = which;
_verbose = verbose;

View File

@ -534,11 +534,6 @@ class ConcurrentHashTable : public CHeapObj<MT> {
template <typename EVALUATE_FUNC, typename DELETE_FUNC>
void bulk_delete(Thread* thread, EVALUATE_FUNC& eval_f, DELETE_FUNC& del_f);
// Gets statistics if available, if not return old one. Item sizes are calculated with
// VALUE_SIZE_FUNC.
template <typename VALUE_SIZE_FUNC>
TableStatistics statistics_get(Thread* thread, VALUE_SIZE_FUNC& vs_f, TableStatistics old);
// Moves all nodes from this table to to_cht with new hash code.
// Must be done at a safepoint.
void rehash_nodes_to(Thread* thread, ConcurrentHashTable<CONFIG, MT>* to_cht);

View File

@ -1266,22 +1266,6 @@ inline TableStatistics ConcurrentHashTable<CONFIG, MT>::
}
}
template <typename CONFIG, MemTag MT>
template <typename VALUE_SIZE_FUNC>
inline TableStatistics ConcurrentHashTable<CONFIG, MT>::
statistics_get(Thread* thread, VALUE_SIZE_FUNC& vs_f, TableStatistics old)
{
if (!try_resize_lock(thread)) {
return old;
}
InternalTable* table = get_table();
NumberSeq summary;
size_t literal_bytes = 0;
internal_statistics_range(thread, 0, table->_size, vs_f, summary, literal_bytes);
return internal_statistics_epilog(thread, summary, literal_bytes);
}
template <typename CONFIG, MemTag MT>
inline void ConcurrentHashTable<CONFIG, MT>::
rehash_nodes_to(Thread* thread, ConcurrentHashTable<CONFIG, MT>* to_cht)

View File

@ -84,9 +84,9 @@ import sun.util.locale.provider.LocaleProviderAdapter;
* Note: these examples are from CLDR, there could be different results from other locale providers.
* <p>
* Alternatively, Locale, Type, and/or Style independent instances
* can be created with {@link #getInstance(String[])}. The String array to the
* method specifies the delimiting patterns for the start/middle/end portion of
* the formatted string, as well as optional specialized patterns for two or three
* can be created with {@link #getInstance(String[])}. The String array passed to the
* method specifies the delimiting patterns for the {@code start}/{@code middle}/{@code end}
* portion of the formatted string, as well as optional specialized patterns for two or three
* elements. Refer to the method description for more detail.
* <p>
* On parsing, if some ambiguity is found in the input string, such as delimiting
@ -121,7 +121,8 @@ public final class ListFormat extends Format {
/**
* The array of five pattern Strings. Each element corresponds to the Unicode LDML's
* `listPatternsPart` type, i.e, start/middle/end/two/three.
* {@code listPatternPart} type, i.e,
* {@code start}/{@code middle}/{@code end}/{@code two}/{@code three}.
* @serial
*/
private final String[] patterns;
@ -153,6 +154,7 @@ public final class ListFormat extends Format {
var pattern = patterns[START];
var placeholderPositions = findPlaceholders(pattern);
if (placeholderPositions != null &&
placeholderPositions[2] == -1 &&
placeholderPositions[1] + PLACEHOLDER_LENGTH == pattern.length()) {
startBefore = pattern.substring(0, placeholderPositions[0]);
startBetween = pattern.substring(placeholderPositions[0] + PLACEHOLDER_LENGTH,
@ -164,6 +166,7 @@ public final class ListFormat extends Format {
pattern = patterns[MIDDLE];
placeholderPositions = findPlaceholders(pattern);
if (placeholderPositions != null &&
placeholderPositions[2] == -1 &&
placeholderPositions[0] == 0 &&
placeholderPositions[1] + PLACEHOLDER_LENGTH == pattern.length()) {
middleBetween = pattern.substring(placeholderPositions[0] + PLACEHOLDER_LENGTH,
@ -174,7 +177,9 @@ public final class ListFormat extends Format {
pattern = patterns[END];
placeholderPositions = findPlaceholders(pattern);
if (placeholderPositions != null && placeholderPositions[0] == 0) {
if (placeholderPositions != null &&
placeholderPositions[2] == -1 &&
placeholderPositions[0] == 0) {
endBetween = pattern.substring(placeholderPositions[0] + PLACEHOLDER_LENGTH,
placeholderPositions[1]);
endAfter = pattern.substring(placeholderPositions[1] + PLACEHOLDER_LENGTH);
@ -185,7 +190,8 @@ public final class ListFormat extends Format {
// Validate two/three patterns, if given. Otherwise, generate them
pattern = patterns[TWO];
if (!pattern.isEmpty()) {
if (findPlaceholders(pattern) == null) {
placeholderPositions = findPlaceholders(pattern);
if (placeholderPositions == null || placeholderPositions[2] >= 0) {
throw new IllegalArgumentException("pattern for two is incorrect: " + pattern);
}
} else {
@ -245,36 +251,43 @@ public final class ListFormat extends Format {
* instead of letting the runtime provide appropriate patterns for the {@code Locale},
* {@code Type}, or {@code Style}.
* <p>
* The patterns array should contain five String patterns, each corresponding to the Unicode LDML's
* {@code listPatternPart}, i.e., "start", "middle", "end", two element, and three element patterns
* in this order. Each pattern contains "{0}" and "{1}" (and "{2}" for the three element pattern)
* placeholders that are substituted with the passed input strings on formatting.
* If the length of the patterns array is not 5, an {@code IllegalArgumentException}
* is thrown.
* The patterns array should contain five String patterns, each corresponding
* to the Unicode LDML's {@code listPatternPart}, i.e., {@code start},
* {@code middle}, {@code end}, {@code two} element, and {@code three}
* element patterns in this order. Each pattern contains "{0}" and "{1}"
* (and "{2}" for the {@code three} element pattern) placeholders that are
* substituted with the passed input strings on formatting. If the length of
* the patterns array is not 5, an {@code IllegalArgumentException} is thrown.
* <p>
* Each pattern string is first parsed as follows. Literals in parentheses, such as
* "start_before", are optional:
* <blockquote><pre>
* {@snippet :
* start := (start_before){0}start_between{1}
* middle := {0}middle_between{1}
* end := {0}end_between{1}(end_after)
* two := (two_before){0}two_between{1}(two_after)
* three := (three_before){0}three_between1{1}three_between2{2}(three_after)
* </pre></blockquote>
* If two or three pattern string is empty, it falls back to
* {@code "(start_before){0}end_between{1}(end_after)"},
* {@code "(start_before){0}start_between{1}end_between{2}(end_after)"} respectively.
* If parsing of any pattern string for start, middle, end, two, or three fails,
* }
* If the {@code two} or {@code three} pattern string is empty, it falls back to
* {@snippet :
* (start_before){0}end_between{1}(end_after)
* (start_before){0}start_between{1}end_between{2}(end_after)
* }
* respectively.
* If parsing of any pattern string for {@code start}, {@code middle},
* {@code end}, {@code two}, or {@code three} fails, including duplicate
* placeholders, "{2}" in patterns other than the {@code three} element
* pattern, or any use of "{" or "}" other than "{0}", "{1}", or "{2}",
* it throws an {@code IllegalArgumentException}.
* <p>
* On formatting, the input string list with {@code n} elements substitutes above
* placeholders based on the number of elements:
* <blockquote><pre>
* {@snippet :
* n = 1: {0}
* n = 2: parsed pattern for "two"
* n = 3: parsed pattern for "three"
* n > 3: (start_before){0}start_between{1}middle_between{2} ... middle_between{m}end_between{n}(end_after)
* </pre></blockquote>
* }
* As an example, the following table shows a pattern array which is equivalent to
* {@code STANDARD} type, {@code FULL} style in US English:
* <table class="striped">
@ -664,15 +677,37 @@ public final class ListFormat extends Format {
/**
* {@return the positions of the "{0}", "{1}", and "{2}" placeholders in the
* given pattern string, or null if the pattern is invalid}
* Only "{0}", "{1}", or "{2}" placeholders are allowed. Any other use of
* curly braces is not allowed.
*
* The returned array contains -1 for "{2}" if that placeholder is absent.
*
* @param pattern pattern string to parse
*/
private static int[] findPlaceholders(String pattern) {
var positions = new int[3];
for (int i = 0; i < positions.length; i++) {
positions[i] = pattern.indexOf("{" + i + "}");
var positions = new int[] {-1, -1, -1};
for (int i = 0; i < pattern.length(); i++) {
var ch = pattern.charAt(i);
if (ch == '{') {
if (i + PLACEHOLDER_LENGTH > pattern.length() ||
pattern.charAt(i + 1) < '0' ||
pattern.charAt(i + 1) > '2' ||
pattern.charAt(i + 2) != '}') {
return null;
}
// Check for duplicate placeholders
var index = pattern.charAt(i + 1) - '0';
if (positions[index] != -1) {
return null;
}
positions[index] = i;
i += PLACEHOLDER_LENGTH - 1;
} else if (ch == '}') {
return null;
}
}
// Check the existence and order of the placeholders

View File

@ -418,19 +418,15 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
for (;;) {
if ((s = status) < 0)
break;
else if (interrupts < 0) {
s = ABNORMAL; // interrupted and not done
break;
}
else if (Thread.interrupted()) {
if (!ForkJoinPool.poolIsStopping(pool))
interrupts = interruptible ? -1 : 1;
else {
interrupts = 1; // re-assert if cleared
if (ForkJoinPool.poolIsStopping(pool)) {
try {
cancel(true);
} catch (Throwable ignore) {
}
} catch (Throwable ignore) { }
}
if ((interrupts = interruptible ? -1 : 1) < 0) {
s = ABNORMAL;
break;
}
}
else if (deadline != 0L) {

View File

@ -26,6 +26,7 @@
package sun.security.util.math.intpoly;
import java.math.BigInteger;
import jdk.internal.vm.annotation.IntrinsicCandidate;
public final class IntegerPolynomial25519 extends IntegerPolynomial {
private static final int BITS_PER_LIMB = 51;
@ -235,6 +236,7 @@ public final class IntegerPolynomial25519 extends IntegerPolynomial {
* @param b [in] the limb operand to multiply.
* @param r [out] the product of the limbs operands that is fully reduced.
*/
@IntrinsicCandidate
protected void mult(long[] a, long[] b, long[] r) {
long aa0 = a[0];
long aa1 = a[1];
@ -414,6 +416,7 @@ public final class IntegerPolynomial25519 extends IntegerPolynomial {
* @param a [in] the limb operand to square.
* @param r [out] the resulting square of the limb which is fully reduced.
*/
@IntrinsicCandidate
protected void square(long[] a, long[] r) {
long aa0 = a[0];
long aa1 = a[1];

View File

@ -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)

View File

@ -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
@ -351,4 +351,9 @@ class Http2ClientImpl {
public boolean stopping() {
return stopping;
}
// getConnections() is used only by tests.
Map<String, Http2Connection> getConnections() {
return connections;
}
}

View File

@ -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
@ -52,7 +52,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Function;
import java.util.function.Supplier;
@ -1610,16 +1609,37 @@ class Http2Connection implements Closeable {
return frames;
}
// Dedicated cache for headers encoding ByteBuffer.
// Dedicated reusable ByteBuffer for headers encoding.
// There can be no concurrent access to this buffer as all access to this buffer
// and its content happen within a single critical code block section protected
// by the sendLock. / (see sendFrame())
// private final ByteBufferPool headerEncodingPool = new ByteBufferPool();
// by the sendlock (see sendFrame()).
private ByteBuffer cachedHeaderBuffer;
// getCachedHeaderBuffer() is used only by tests and it should not be
// called in source code without also holding `sendlock`.
ByteBuffer getCachedHeaderBuffer() {
return cachedHeaderBuffer;
}
private ByteBuffer getHeaderBuffer(int size) {
ByteBuffer buf = ByteBuffer.allocate(size);
buf.limit(size);
return buf;
assert sendlock.isHeldByCurrentThread() : "current thread is not holding sendlock";
if (cachedHeaderBuffer == null || cachedHeaderBuffer.capacity() < size) {
cachedHeaderBuffer = ByteBuffer.allocate(size);
return cachedHeaderBuffer;
}
cachedHeaderBuffer.clear();
cachedHeaderBuffer.limit(size);
return cachedHeaderBuffer;
}
private static ByteBuffer copyBuffer(ByteBuffer buffer) {
buffer.flip();
ByteBuffer copy = ByteBuffer.allocate(buffer.remaining());
copy.put(buffer);
copy.flip();
return copy;
}
/*
@ -1634,8 +1654,8 @@ class Http2Connection implements Closeable {
* encoding in HTTP/2...
*/
private List<ByteBuffer> encodeHeadersImpl(int bufferSize, HttpHeaders... headers) {
ByteBuffer buffer = getHeaderBuffer(bufferSize);
List<ByteBuffer> buffers = new ArrayList<>();
ByteBuffer buffer = getHeaderBuffer(bufferSize);
for (HttpHeaders header : headers) {
for (Map.Entry<String, List<String>> e : header.map().entrySet()) {
String lKey = e.getKey().toLowerCase(Locale.US);
@ -1644,16 +1664,17 @@ class Http2Connection implements Closeable {
hpackOut.header(lKey, value);
while (!hpackOut.encode(buffer)) {
if (!buffer.hasRemaining()) {
buffer.flip();
buffers.add(buffer);
buffer = getHeaderBuffer(bufferSize);
ByteBuffer copy = copyBuffer(buffer);
buffers.add(copy);
buffer.clear();
buffer.limit(bufferSize);
}
}
}
}
}
buffer.flip();
buffers.add(buffer);
ByteBuffer copy = copyBuffer(buffer);
buffers.add(copy);
return buffers;
}
@ -1710,7 +1731,7 @@ class Http2Connection implements Closeable {
}
}
private final Lock sendlock = new ReentrantLock();
private final ReentrantLock sendlock = new ReentrantLock();
void sendFrame(Http2Frame frame) {
try {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 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,8 +58,8 @@ import java.util.ServiceLoader;
* for example, ships with attach providers that use the package name <i>"sun"</i>
* (for historical reasons). The
* <i>type</i> typically corresponds to the attach mechanism. For example, an
* implementation that uses the Doors inter-process communication mechanism
* might use the type <i>"doors"</i>. The purpose of the name and type is to
* implementation that uses the UNIX Domain Socket inter-process communication mechanism
* might use the type <i>"socket"</i>. The purpose of the name and type is to
* identify providers in environments where there are multiple providers
* installed.
*

View File

@ -137,6 +137,26 @@ public abstract class AbstractExecutableMemberWriter extends AbstractMemberWrite
.title(title)));
}
/**
* Returns a label for the given element to be used the table of contents sidebar.
*
* @param executableElement method or constructor
* @return the link label
*/
protected Content getTOCLabel(ExecutableElement executableElement) {
var signature = utils.makeSignature(executableElement, typeElement, false, true);
var label = new ContentBuilder(Text.of(utils.getSimpleName(executableElement)));
// Insert line break opportunity before first parameter.
if (signature.length() > 2) {
label.add(Text.of(signature.substring(0, 1)))
.add(HtmlTree.WBR())
.add(Text.of(signature.substring(1)));
} else {
label.add(signature);
}
return label;
}
/**
* Adds the generic type parameters.
*

View File

@ -119,9 +119,7 @@ public class ConstructorWriter extends AbstractExecutableMemberWriter {
constructorContent.add(div);
memberList.add(getMemberListItem(constructorContent));
writer.tableOfContents.addLink(htmlIds.forMember(currentConstructor).getFirst(),
Text.of(utils.getSimpleName(constructor)
+ utils.makeSignature(currentConstructor, typeElement, false, true)),
TableOfContents.Level.SECOND);
getTOCLabel(currentConstructor), TableOfContents.Level.SECOND);
}
Content constructorDetails = getConstructorDetails(constructorDetailsHeader, memberList);
target.add(constructorDetails);

View File

@ -118,9 +118,7 @@ public class MethodWriter extends AbstractExecutableMemberWriter {
methodContent.add(div);
memberList.add(writer.getMemberListItem(methodContent));
writer.tableOfContents.addLink(htmlIds.forMember(currentMethod).getFirst(),
Text.of(utils.getSimpleName(method)
+ utils.makeSignature(currentMethod, typeElement, false, true)),
TableOfContents.Level.SECOND);
getTOCLabel(currentMethod), TableOfContents.Level.SECOND);
}
Content methodDetails = getMethodDetails(methodDetailsHeader, memberList);
detailsList.add(methodDetails);

View File

@ -82,6 +82,8 @@
/* Search input colors */
--search-input-background-color: #ffffff;
--search-input-text-color: #000000;
--search-border-light-color: #eaeaea;
--search-border-dark-color: #a6a6a6;
--search-input-placeholder-color: #757575;
--overlay-background: rgba(153, 169, 183, 0.3);
/* Highlight color for active search tag target */
@ -107,23 +109,23 @@
:root[data-theme="theme-dark"] {
--body-text-color: #e8e8e8;
--block-text-color: #e8e8e8;
--body-background-color: #1f2124;
--body-background-color: #202226;
--section-background-color: var(--body-background-color);
--detail-background-color: var(--body-background-color);
--code-background-color: #303940;
--mark-background-color: #313131;
--detail-block-color: #31363c;
--navbar-background-color: #395A6F;
--navbar-background-color: #406074;
--navbar-text-color: #ffffff;
--subnav-background-color: #3d454d;
--subnav-background-color: #434c54;
--subnav-link-color: #d8dcdf;
--member-heading-background-color: var(--subnav-background-color);
--selected-background-color: #f8981d;
--selected-text-color: #253441;
--selected-link-color: #4a698a;
--table-header-color: #38444d;
--even-row-color: #222528;
--odd-row-color: #2d3135;
--even-row-color: #282c2f;
--odd-row-color: #33383b;
--title-color: #fff;
--link-color: #94badb;
--link-color-active: #e8a351;
@ -138,8 +140,10 @@
--border-color: #444444;
--table-border-color: #717171;
--tab-border-radius: 2px 2px 0 0;
--search-input-background-color: #303030;
--search-input-background-color: #202224;
--search-input-text-color: #d0d0d0;
--search-border-light-color: #505050;
--search-border-dark-color: #000000;
--search-input-placeholder-color: #979797;
--overlay-background: rgba(0, 0, 0, 0.45);
--search-tag-background-color: #c6c61e;
@ -192,7 +196,7 @@ body {
width:100%;
}
main [id] {
scroll-margin-top: calc(var(--nav-height) + 6px);
scroll-margin-top: calc(var(--nav-height) + 14px);
}
div.main-grid {
max-width: var(--max-content-width);
@ -246,6 +250,9 @@ h1, h2, h3, h4, h5, h6, div.member-signature, div.member-signature > span {
ul {
list-style-type:disc;
}
main li {
margin-top: 4px;
}
tt {
font-family:var(--code-font-family);
}
@ -486,12 +493,7 @@ body.class-declaration-page .details h3 {
}
body.class-declaration-page section.detail:target > h3,
body.class-declaration-page section.detail > h3:target {
background-color: var(--navbar-background-color);
color: var(--navbar-text-color);
}
body.class-declaration-page section.detail:target > h3 > a.anchor-link > img,
body.class-declaration-page section.detail > h3:target > a.anchor-link > img {
filter: invert(100%) brightness(160%);
box-shadow: -4px 0 0 rgb(from var(--link-color) r g b / 0.7);
}
h1 > sup {
font-size: small;
@ -522,6 +524,9 @@ section.class-description > div.horizontal-scroll > :is(dl, ol, ul, p, div, bloc
section.class-description > div.horizontal-scroll > :last-child > :is(li, dd):last-child {
margin-bottom:4px;
}
dl.notes {
margin-top: 14.2px;
}
dl.notes > dt {
font-family: var(--body-font-family);
font-size:0.856em;
@ -661,9 +666,12 @@ a.current-selection {
}
nav.toc a {
display: block;
padding: 8px;
padding: 7px 8px;
overflow: hidden;
text-overflow: ellipsis;
text-wrap: balance;
text-indent: 0.5em hanging;
line-height: 1.35;
}
nav.toc ol.toc-list ol.toc-list a {
padding-left: 24px;
@ -737,11 +745,13 @@ ul.tag-list li {
display: inline;
}
ul.tag-list li:not(:last-child):after,
ul.tag-list-long li:not(:last-child):after
{
ul.tag-list-long li:not(:last-child):after {
content: ", ";
white-space: pre-wrap;
}
ul.tag-list-long > li {
margin-top: 1px;
}
ul.preview-feature-list {
list-style: none;
margin:0;
@ -940,6 +950,9 @@ div.checkboxes > label > input {
.col-first, .col-second, .col-constructor-name {
overflow: auto;
}
.col-constructor-name, .method-summary .col-second {
text-indent: 0.5em hanging;
}
body:not(.class-declaration-page) .col-first a:link,
.col-summary-item-name a:link {
font-weight:bold;
@ -957,6 +970,12 @@ div.block {
font-size:var(--block-font-size);
font-family:var(--block-font-family);
line-height:var(--block-line-height);
display: block;
margin:0 10px 5px 0;
color:var(--block-text-color);
}
section.detail div.block {
margin-bottom: 14.4px;
}
.module-signature,
.package-signature,
@ -1006,11 +1025,6 @@ div.block {
color:var(--source-linenumber-color, green);
padding:0 30px 0 0;
}
.block {
display:block;
margin:0 10px 5px 0;
color:var(--block-text-color);
}
.deprecated-label, .description-from-type-label, .implementation-label, .member-name-link,
.package-hierarchy-label, .type-name-label, .type-name-link, .search-tag-link, .preview-label,
.restricted-label {
@ -1075,15 +1089,16 @@ input[type="text"] {
background-image:var(--glass-svg);
background-size:13px;
background-repeat:no-repeat;
background-position:3px 4px;
background-position:3px 5px;
background-color: var(--search-input-background-color);
color: var(--search-input-text-color);
border-color: var(--border-color);
border-style:solid;
border-color: var(--search-border-dark-color) var(--search-border-light-color) var(--search-border-light-color) var(--search-border-dark-color);
border-radius: 4px;
padding-left:20px;
padding-right: 18px;
font-size: var(--nav-font-size);
height: 19px;
height: 20px;
}
input#page-search-input {
width: calc(180px + 10vw);
@ -1585,8 +1600,7 @@ button.snippet-copy span {
table.borderless,
table.plain,
table.striped {
margin-top: 10px;
margin-bottom: 10px;
margin: 14px 0;
}
table.borderless > caption,
table.plain > caption,
@ -1780,6 +1794,9 @@ table.striped > tbody > tr > th {
main {
padding: 10px 12px;
}
main [id] {
scroll-margin-top: calc(var(--nav-height) + 10px);
}
body {
-webkit-text-size-adjust: none;
}

View File

@ -1200,16 +1200,22 @@ TEST_VM(os, map_unmap_memory) {
TEST_VM(os, map_memory_to_file_aligned) {
const char* letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const size_t size = strlen(letters) + 1;
const size_t content_size = strlen(letters) + 1;
const size_t granularity = os::vm_allocation_granularity();
const size_t alignments[] = { granularity, 2 * granularity, 4 * granularity, 16 * granularity, 1 * M };
int fd = os::open("map_memory_to_file.txt", O_RDWR | O_CREAT, 0666);
EXPECT_TRUE(fd > 0);
EXPECT_TRUE(os::write(fd, letters, size));
ASSERT_TRUE(os::write(fd, letters, content_size));
char* result = os::map_memory_to_file_aligned(os::vm_allocation_granularity(), os::vm_allocation_granularity(), fd, mtTest);
ASSERT_NOT_NULL(result);
EXPECT_EQ(strcmp(letters, result), 0);
os::unmap_memory(result, os::vm_allocation_granularity());
const size_t size = granularity;
for (size_t alignment : alignments) {
char* result = os::map_memory_to_file_aligned(size, alignment, fd, mtTest);
ASSERT_NOT_NULL(result) << "Mapping failed for alignment=" << alignment;
EXPECT_TRUE(is_aligned(result, alignment)) << "Failed to aligned to " << alignment;
EXPECT_EQ(strcmp(letters, result), 0) << "Text mismatch at alignment=" << alignment;
os::unmap_memory(result, size);
}
::close(fd);
}
@ -1220,3 +1226,36 @@ TEST_VM(os, dll_load_null_error_buf) {
void* lib = os::dll_load("NoSuchLib", nullptr, 0);
ASSERT_NULL(lib);
}
TEST_VM(os, reserve_memory_aligned_basic) {
const size_t granularity = os::vm_allocation_granularity();
const size_t alignments[] = { granularity, 2 * granularity, 4 * granularity, 16 * granularity };
for (size_t alignment : alignments) {
const size_t size = alignment;
char* result = os::reserve_memory_aligned(size, alignment, mtTest);
ASSERT_NE(result, (char*)nullptr) << "reserve_memory_aligned failed for alignment=" << alignment;
EXPECT_TRUE(is_aligned(result, alignment)) << "Result " << result << " not aligned to " << alignment;
ASSERT_TRUE(os::commit_memory(result, size, false));
memset(result, 0xCD, size);
EXPECT_EQ((unsigned char)result[0], 0xCD);
os::release_memory(result, size);
}
}
TEST_VM(os, reserve_memory_aligned_large) {
const size_t alignment = 1 * M;
const size_t size = alignment;
char* result = os::reserve_memory_aligned(size, alignment, mtTest);
ASSERT_NE(result, (char*)nullptr);
EXPECT_TRUE(is_aligned(result, alignment));
ASSERT_TRUE(os::commit_memory(result, size, false));
memset(result, 0xEF, size);
EXPECT_EQ((unsigned char)result[size - 1], 0xEF);
os::release_memory(result, size);
}

View File

@ -33,8 +33,6 @@ vmTestbase/vm/mlvm/mixed/stress/regression/b6969574/INDIFY_Test.java 8265295 lin
serviceability/AsyncGetCallTrace/MyPackage/ASGCTBaseTest.java 8303168 linux-all
serviceability/sa/ClhsdbInspect.java 8283578 windows-x64
vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manyDiff_a/TestDescription.java 8308367 generic-all
vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manySame_a/TestDescription.java 8308367 generic-all
vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2none_b/TestDescription.java 8308367 generic-all

View File

@ -103,7 +103,6 @@ runtime/os/TestTracePageSizes.java#compiler-options 8267460 linux-aarch64
runtime/os/TestTracePageSizes.java#G1 8267460 linux-aarch64
runtime/os/TestTracePageSizes.java#Parallel 8267460 linux-aarch64
runtime/os/TestTracePageSizes.java#Serial 8267460 linux-aarch64
runtime/StackGuardPages/TestStackGuardPagesNative.java 8303612 linux-all
runtime/ErrorHandling/MachCodeFramesInErrorFile.java 8313315 linux-ppc64le
runtime/NMT/VirtualAllocCommitMerge.java 8309698 linux-s390x
runtime/Thread/TestAlwaysPreTouchStacks.java 8383372 macosx-aarch64
@ -139,6 +138,8 @@ serviceability/sa/ClhsdbThreadContext.java 8356704 windows-x64
serviceability/jvmti/stress/StackTrace/NotSuspended/GetStackTraceNotSuspendedStressTest.java 8315980 linux-all,windows-x64
serviceability/jvmti/GetModulesInfo/JvmtiGetAllModulesTest.java 8385679 generic-all
#############################################################################
# :hotspot_misc

View File

@ -64,7 +64,7 @@ public class TestPrintMethodData {
private static final Generator<Long> GEN_LONG = Generators.G.longs();
private static final int SIZE = 1024;
static void main(String[] args) throws Exception {
public static void main(String[] args) throws Exception {
long[] longs = new long[SIZE];
Generators.G.fill(GEN_LONG, longs);

View File

@ -56,17 +56,13 @@ static jmp_buf context;
static volatile int _last_si_code = -1;
static volatile int _failures = 0;
static volatile int _rec_count = 0; // Number of allocations to hit stack guard page
static volatile int _kp_rec_count = 0; // Kept record of rec_count, for retrying
static volatile int _previous_rec_count = 0; // Kept record of rec_count, for retrying
static int _peek_value = 0; // Used for accessing memory to cause SIGSEGV
pid_t gettid() {
return (pid_t) syscall(SYS_gettid);
}
static void handler(int sig, siginfo_t *si, void *unused) {
_last_si_code = si->si_code;
printf("Got SIGSEGV(%d) at address: 0x%lx\n",si->si_code, (long) si->si_addr);
longjmp(context, 1);
siglongjmp(context, 1);
}
static char* altstack = NULL;
@ -159,8 +155,16 @@ void *run_java_overflow (void *p) {
void do_overflow(){
volatile int *p = NULL;
if (_kp_rec_count == 0 || _rec_count < _kp_rec_count) {
for(;;) {
if (_previous_rec_count == 0) {
// We need to find the appropriate depth to probe into
for (;;) {
_rec_count++;
p = (int*)alloca(128);
_peek_value = p[0]; // Peek
}
} else {
while (_rec_count < _previous_rec_count) {
// This is our second round, we can do exactly 1 less allocation
_rec_count++;
p = (int*)alloca(128);
_peek_value = p[0]; // Peek
@ -168,19 +172,19 @@ void do_overflow(){
}
}
void *run_native_overflow(void *p) {
void *run_native_overflow(void *is_other_thread) {
// Test that stack guard page is correctly set for initial and non initial thread
// and correctly removed for the initial thread
volatile int res;
printf("run_native_overflow %ld\n", (long) gettid());
printf("run_native_overflow, %s", *(int *)is_other_thread ? "in other thread\n" : "in initial thread\n");
call_method_on_jvm("printAlive");
// Initialize statics used in do_overflow
_kp_rec_count = 0;
_previous_rec_count = 0;
_rec_count = 0;
set_signal_handler();
if (! setjmp(context)) {
if (! sigsetjmp(context, 1)) {
do_overflow();
}
@ -194,7 +198,7 @@ void *run_native_overflow(void *p) {
exit(7);
}
if (getpid() != gettid()) {
if (*(int *)is_other_thread == 1) {
// For non-initial thread we don't unmap the region but call os::uncommit_memory and keep PROT_NONE
// so if host has enough swap space we will get the same SEGV with code SEGV_ACCERR(2) trying
// to access it as if the guard page is present.
@ -204,11 +208,11 @@ void *run_native_overflow(void *p) {
}
// Limit depth of recursion for second run. It can't exceed one for first run.
_kp_rec_count = _rec_count;
_previous_rec_count = _rec_count;
_rec_count = 0;
set_signal_handler();
if (! setjmp(context)) {
if (!sigsetjmp(context, 1)) {
do_overflow();
}
@ -314,8 +318,8 @@ int main (int argc, const char** argv) {
if (strcmp(argv[1], "test_native_overflow_initial") == 0) {
printf("\nTesting NATIVE_OVERFLOW\n");
printf("Testing stack guard page behaviour for initial thread\n");
run_native_overflow(NULL);
int is_other_thread = 0;
run_native_overflow(&is_other_thread);
exit((_failures > 0) ? 1 : 0);
}
@ -324,11 +328,11 @@ int main (int argc, const char** argv) {
init_thread_or_die(&thr, &thread_attr);
printf("\nTesting NATIVE_OVERFLOW\n");
printf("Testing stack guard page behaviour for other thread\n");
pthread_create(&thr, &thread_attr, run_native_overflow, NULL);
int is_other_thread = 1;
pthread_create(&thr, &thread_attr, run_native_overflow, &is_other_thread);
pthread_join(thr, NULL);
exit((_failures > 0) ? 1 : 0);
// Other-thread test cannot increase _failure count
exit(0);
}
fprintf(stderr, "Test ERROR. Unknown parameter %s\n", ((argc > 1) ? argv[1] : "none"));

View File

@ -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);

View File

@ -79,7 +79,10 @@ import java.util.concurrent.CountDownLatch;
import java.util.stream.Stream;
import java.util.stream.Collectors;
import jdk.test.lib.thread.VThreadRunner;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.junit.jupiter.params.provider.Arguments;
@ -96,6 +99,12 @@ class KlassInit {
private static final CountDownLatch finishPutStatic = new CountDownLatch(1);
private static final CountDownLatch finishFailedInit = new CountDownLatch(1);
@BeforeAll
static void setup() {
// need >=2 carriers for testing pinning
VThreadRunner.ensureParallelism(2);
}
/**
* Test that threads blocked waiting for klass to be initialized
* on invokestatic bytecode release the carrier.

View File

@ -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
@ -26,6 +26,9 @@ import java.lang.reflect.Field;
import java.net.http.HttpClient;
import java.util.Objects;
import java.util.Set;
import java.nio.ByteBuffer;
import java.util.Collection;
import java.util.Map;
public final class HttpClientImplAccess {
@ -64,4 +67,29 @@ public final class HttpClientImplAccess {
openedConnections.setAccessible(true);
return (Set<?>) openedConnections.get(clientImpl);
}
/**
* Returns all connections in the client's HTTP/2 pool.
*/
public static Collection<?> getHttp2Connections(final HttpClient client) {
Objects.requireNonNull(client, "client");
final HttpClientImpl clientImpl = impl(client);
if (clientImpl == null) {
throw new IllegalStateException("Unsupported HttpClient implementation");
}
Http2ClientImpl client2 = clientImpl.client2();
Map<String, Http2Connection> connections = client2.getConnections();
return connections.values();
}
/**
* Returns the cached header encoding buffer for the given Http2Connection.
*/
public static ByteBuffer getCachedHeaderBuffer(final Object conn) {
// The argument to this method is of type Object and not
// Http2Connection because callers outside the module cannot reference
// the package-private Http2Connection class.
Objects.requireNonNull(conn, "conn");
return ((Http2Connection) conn).getCachedHeaderBuffer();
}
}

View File

@ -0,0 +1,139 @@
/*
* 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.
*/
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpRequest.BodyPublishers;
import java.net.http.HttpResponse;
import java.net.http.HttpResponse.BodyHandlers;
import java.nio.ByteBuffer;
import java.util.Collection;
import javax.net.ssl.SSLContext;
import static java.net.http.HttpClient.Version.HTTP_2;
import jdk.httpclient.test.lib.common.HttpServerAdapters;
import jdk.httpclient.test.lib.common.HttpServerAdapters.HttpTestServer;
import jdk.httpclient.test.lib.common.HttpServerAdapters.HttpTestExchange;
import jdk.httpclient.test.lib.common.HttpServerAdapters.HttpTestHandler;
import jdk.internal.net.http.HttpClientImplAccess;
import jdk.test.lib.net.URIBuilder;
import jdk.test.lib.net.SimpleSSLContext;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
/*
* @test
* @bug 8383248
* @summary Verifies that Http2Connection.cachedHeaderBuffer is reused
* across multiple requests on the same connection.
* @library /test/lib /test/jdk/java/net/httpclient/lib
* /test/jdk/java/net/httpclient/access
* @build java.net.http/jdk.internal.net.http.HttpClientImplAccess
* jdk.httpclient.test.lib.common.HttpServerAdapters
* jdk.test.lib.net.SimpleSSLContext
* @run junit/othervm
* ${test.main.class}
*/
public class HeaderEncodingBufferReuseTest implements HttpServerAdapters {
static String httpUri;
static SSLContext sslContext;
static HttpTestServer testServer;
@BeforeAll
static void init() throws Exception {
sslContext = SimpleSSLContext.findSSLContext();
testServer = HttpTestServer.create(HTTP_2, sslContext);
testServer.addHandler(new OkHandler(), "/test");
testServer.start();
httpUri = URIBuilder.newBuilder()
.scheme("https")
.loopback()
.port(testServer.getAddress().getPort())
.path("/test")
.build()
.toString();
}
@AfterAll
static void teardown() {
testServer.stop();
}
@Test
void test() throws Exception {
try (HttpClient client = HttpClient.newBuilder()
.proxy(HttpClient.Builder.NO_PROXY)
.version(HttpClient.Version.HTTP_2)
.sslContext(sslContext)
.build()) {
// Send an initial request to allocate the header encoding buffer.
assertEquals(200, send(client, httpUri, 2).statusCode());
Collection<?> connections = HttpClientImplAccess.getHttp2Connections(client);
assertEquals(1, connections.size());
Object conn = connections.iterator().next();
ByteBuffer cached = HttpClientImplAccess.getCachedHeaderBuffer(conn);
assertNotNull(cached);
// Send another request and verify the same buffer is reused.
assertEquals(200, send(client, httpUri, 2).statusCode());
connections = HttpClientImplAccess.getHttp2Connections(client);
assertEquals(1, connections.size());
assertSame(conn, connections.iterator().next());
assertSame(cached, HttpClientImplAccess.getCachedHeaderBuffer(conn));
// Verify that the buffer is reused when headers span multiple frames.
assertEquals(200, send(client, httpUri, 300).statusCode());
connections = HttpClientImplAccess.getHttp2Connections(client);
assertEquals(1, connections.size());
assertSame(conn, connections.iterator().next());
assertSame(cached, HttpClientImplAccess.getCachedHeaderBuffer(conn));
}
}
static HttpResponse<Void> send(HttpClient client, String uri, int headerCount) throws Exception {
HttpRequest.Builder builder = HttpRequest.newBuilder(URI.create(uri))
.POST(BodyPublishers.ofString("test"));
for (int i = 0; i < headerCount; i++) {
builder.header("X-Header-" + i, "value-" + "x".repeat(50) + "-" + i);
}
return client.send(builder.build(), BodyHandlers.discarding());
}
static class OkHandler implements HttpTestHandler {
@Override
public void handle(HttpTestExchange exchange) throws IOException {
exchange.sendResponseHeaders(200, 0);
exchange.getResponseBody().close();
}
}
}

View File

@ -23,7 +23,7 @@
/*
* @test
* @bug 8041488 8316974 8318569 8306116 8385736
* @bug 8041488 8316974 8318569 8306116 8385736 8385834
* @summary Tests for ListFormat class
* @run junit TestListFormat
*/
@ -210,6 +210,10 @@ public class TestListFormat {
arguments(CUSTOM_PATTERNS_MINIMAL, SAMPLE2),
arguments(CUSTOM_PATTERNS_MINIMAL, SAMPLE3),
arguments(CUSTOM_PATTERNS_MINIMAL, SAMPLE4),
arguments(CUSTOM_PATTERNS_METACHAR, SAMPLE1),
arguments(CUSTOM_PATTERNS_METACHAR, SAMPLE2),
arguments(CUSTOM_PATTERNS_METACHAR, SAMPLE3),
arguments(CUSTOM_PATTERNS_METACHAR, SAMPLE4),
};
}
@ -237,13 +241,37 @@ public class TestListFormat {
};
}
private static Arguments[] getInstance_1Arg_InvalidLongPattern() {
private static final String ZERO_REPEAT = "{0}".repeat(100_000);
private static Arguments[] getInstance_1Arg_InvalidPlaceholder() {
return new Arguments[] {
arguments(0, "start pattern is incorrect:"),
arguments(1, "middle pattern is incorrect:"),
arguments(2, "end pattern is incorrect:"),
arguments(3, "pattern for two is incorrect:"),
arguments(4, "pattern for three is incorrect:"),
// Duplicate placeholders
arguments(0, "{0} {0} {1}", "start pattern is incorrect: {0} {0} {1}"),
arguments(0, "{0} {1} {1}", "start pattern is incorrect: {0} {1} {1}"),
arguments(0, "{0} {1} {2}", "start pattern is incorrect: {0} {1} {2}"),
arguments(1, "{0} {0} {1}", "middle pattern is incorrect: {0} {0} {1}"),
arguments(1, "{0} {1} {1}", "middle pattern is incorrect: {0} {1} {1}"),
arguments(1, "{0} {1} {2}", "middle pattern is incorrect: {0} {1} {2}"),
arguments(2, "{0} {0} {1}", "end pattern is incorrect: {0} {0} {1}"),
arguments(2, "{0} {1} {1}", "end pattern is incorrect: {0} {1} {1}"),
arguments(2, "{0} {1} {2}", "end pattern is incorrect: {0} {1} {2}"),
arguments(3, "{0} {0} {1}", "pattern for two is incorrect: {0} {0} {1}"),
arguments(3, "{0} {1} {1}", "pattern for two is incorrect: {0} {1} {1}"),
arguments(3, "{0} {1} {2}", "pattern for two is incorrect: {0} {1} {2}"),
arguments(4, "{0} {2} {1}", "pattern for three is incorrect: {0} {2} {1}"),
arguments(4, "{0} {0} {1} {2}", "pattern for three is incorrect: {0} {0} {1} {2}"),
arguments(4, "{0} {1} {1} {2}", "pattern for three is incorrect: {0} {1} {1} {2}"),
arguments(4, "{0} {1} {2} {2}", "pattern for three is incorrect: {0} {1} {2} {2}"),
arguments(4, ZERO_REPEAT + " {1} {2}", "pattern for three is incorrect: " + ZERO_REPEAT + " {1} {2}"),
// invalid placeholders
arguments(0, "{0} {1} {", "start pattern is incorrect: {0} {1} {"),
arguments(0, "{0} {1} }", "start pattern is incorrect: {0} {1} }"),
arguments(3, "{0} {1} {3}", "pattern for two is incorrect: {0} {1} {3}"),
arguments(4, "{3} {0} {1}", "pattern for three is incorrect: {3} {0} {1}"),
arguments(4, "{333} {0} {1}", "pattern for three is incorrect: {333} {0} {1}"),
arguments(4, "{0} {1} {abc}", "pattern for three is incorrect: {0} {1} {abc}"),
arguments(4, "{0} {1} {2, number}", "pattern for three is incorrect: {0} {1} {2, number}"),
arguments(4, "{0} {1} {2} {3}", "pattern for three is incorrect: {0} {1} {2} {3}"),
};
}
@ -264,7 +292,7 @@ public class TestListFormat {
@ParameterizedTest
@MethodSource
void getInstance_1Arg_InvalidLongPattern(int index, String expected) {
void getInstance_1Arg_InvalidPlaceholder(int index, String invalidPattern, String expected) {
var patterns = new String[]{
"{0}, {1}",
"{0}, {1}",
@ -272,13 +300,12 @@ public class TestListFormat {
"{0} and {1}",
"{0} {1} {2}"
};
patterns[index] = "{0}".repeat(100_000);
patterns[index] = invalidPattern;
// Ensures validation of invalid long patterns completes without timing out
var msg = assertThrows(IllegalArgumentException.class,
() -> ListFormat.getInstance(patterns))
.getMessage();
assertEquals(expected, msg.substring(0, Math.min(msg.length(), expected.length())));
assertEquals(expected, msg);
}
@ParameterizedTest

View File

@ -663,6 +663,23 @@ public class ForkJoinPoolTest extends JSR166TestCase {
}
}
public void testCallerInterruptedDuringSubmit() throws InterruptedException, ExecutionException {
final Thread submitter = Thread.currentThread();
final ExecutorService p = new ForkJoinPool(1);
try (PoolCleaner cleaner = cleaner(p)) {
for (int i = 0; i < 512; ++i) { // Enough repetitions such that any race condition is bound to materialize
try {
p.submit(submitter::interrupt).get();
// If we don't get an InterruptedException, then the current thread should be interrupted
assertTrue(Thread.interrupted());
} catch (InterruptedException e) {
// If we do get an InterruptedException, then the current thread should not be interrupted
assertTrue(!Thread.interrupted());
}
}
}
}
/**
* get of submit(callable) throws ExecutionException if callable
* throws exception

View File

@ -0,0 +1,145 @@
/*
* Copyright (c) 1997, 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
* @key headful
* @summary Checkbox Accessibility test.
* @library ../../swing/regtesthelpers/accessibility/
* @build AccessibleTestUtils AccessibleComponentTester AccessibleStateSetTester
* @run main CheckboxTest
*/
import java.awt.AWTException;
import java.awt.Checkbox;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Robot;
import java.lang.reflect.InvocationTargetException;
import javax.accessibility.AccessibleState;
import javax.accessibility.AccessibleStateSet;
public class CheckboxTest {
private static Checkbox checkbox;
private static Frame frame;
private static final String ACCESSIBLE_NAME = "Checkbox Test";
private static final String ACCESSIBLE_DESCRIPTION =
"Regression Test: javax.accessibility, Checkbox";
public static void main(String[] args) throws InterruptedException,
InvocationTargetException, AWTException {
CheckboxTest checkboxTest = new CheckboxTest();
EventQueue.invokeAndWait(checkboxTest::createGUI);
Robot robot = new Robot();
robot.waitForIdle();
robot.delay(5000);
try {
EventQueue.invokeAndWait(checkboxTest::test);
} finally {
checkboxTest.dispose();
}
}
private void createGUI() {
frame = new Frame("Checkbox Test");
checkbox = new Checkbox("This is a checkbox", true);
checkbox.getAccessibleContext().setAccessibleName(ACCESSIBLE_NAME);
checkbox.getAccessibleContext().setAccessibleDescription(
ACCESSIBLE_DESCRIPTION);
frame.add(checkbox);
frame.setSize(200, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void dispose() throws InterruptedException,
InvocationTargetException {
EventQueue.invokeAndWait(() -> {
if (frame != null) {
frame.dispose();
}
});
}
private void test() {
AccessibleTestUtils.verifyCheckboxAccessibility(
checkbox,
ACCESSIBLE_NAME,
ACCESSIBLE_DESCRIPTION
);
new CheckboxStateTester(
checkbox,
checkbox.getAccessibleContext().getAccessibleStateSet()
).testAll();
checkbox.setState(!checkbox.getState());
AccessibleTestUtils.verifyCheckboxAccessibility(
checkbox,
ACCESSIBLE_NAME,
ACCESSIBLE_DESCRIPTION
);
new CheckboxStateTester(
checkbox,
checkbox.getAccessibleContext().getAccessibleStateSet()
).testAll();
}
private static final class CheckboxStateTester
extends AccessibleStateSetTester {
private final Checkbox checkbox;
private final AccessibleStateSet set;
private CheckboxStateTester(Checkbox checkbox, AccessibleStateSet set) {
super(checkbox, set);
this.checkbox = checkbox;
this.set = set;
}
@Override
public void testChecked() {
if (set.contains(AccessibleState.CHECKED)) {
if (!checkbox.getState()) {
throw new RuntimeException(
"AccessibleStateSet contains CHECKED but " +
"this component is not checked");
}
} else {
if (checkbox.getState()) {
throw new RuntimeException(
"AccessibleStateSet does not contain CHECKED " +
"but this component is checked");
}
}
}
}
}

View File

@ -0,0 +1,158 @@
/*
* Copyright (c) 1997, 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
* @key headful
* @summary Frame Accessibility test.
* @library ../../swing/regtesthelpers/accessibility/
* @build AccessibleTestUtils AccessibleComponentTester AccessibleStateSetTester
* @run main FrameTest
*/
import java.awt.AWTException;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Robot;
import java.lang.reflect.InvocationTargetException;
import javax.accessibility.AccessibleState;
import javax.accessibility.AccessibleStateSet;
public class FrameTest {
private static Frame frame;
private static final String ACCESSIBLE_NAME = "Frame Test";
private static final String ACCESSIBLE_DESCRIPTION =
"Regression Test: javax.accessibility, Frame";
public static void main(String[] args) throws InterruptedException,
InvocationTargetException, AWTException {
FrameTest frameTest = new FrameTest();
EventQueue.invokeAndWait(frameTest::createGUI);
Robot robot = new Robot();
robot.waitForIdle();
robot.delay(5000);
try {
EventQueue.invokeAndWait(frameTest::test);
} finally {
frameTest.dispose();
}
}
private void createGUI() {
frame = new Frame("Frame Test");
frame.getAccessibleContext().setAccessibleName(ACCESSIBLE_NAME);
frame.getAccessibleContext().setAccessibleDescription(
ACCESSIBLE_DESCRIPTION);
frame.setSize(300, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void dispose() throws InterruptedException,
InvocationTargetException {
EventQueue.invokeAndWait(() -> {
if (frame != null) {
frame.dispose();
}
});
}
private void test() {
AccessibleTestUtils.verifyFrameAccessibility(
frame,
ACCESSIBLE_NAME,
ACCESSIBLE_DESCRIPTION
);
new FrameStateTester(
frame,
frame.getAccessibleContext().getAccessibleStateSet()
).testAll();
frame.setResizable(false);
AccessibleTestUtils.verifyFrameAccessibility(
frame,
ACCESSIBLE_NAME,
ACCESSIBLE_DESCRIPTION
);
new FrameStateTester(
frame,
frame.getAccessibleContext().getAccessibleStateSet()
).testAll();
}
private static final class FrameStateTester
extends AccessibleStateSetTester {
private final Frame component;
private final AccessibleStateSet set;
private FrameStateTester(Frame frame, AccessibleStateSet set) {
super(frame, set);
this.component = frame;
this.set = set;
}
@Override
public void testResizable() {
if (set.contains(AccessibleState.RESIZABLE)) {
if (!component.isResizable()) {
throw new RuntimeException(
"AccessibleStateSet contains RESIZABLE but " +
"this component is not resizable");
}
} else {
if (component.isResizable()) {
throw new RuntimeException(
"AccessibleStateSet does not contain RESIZABLE " +
"but this component is resizable");
}
}
}
@Override
public void testActive() {
if (set.contains(AccessibleState.ACTIVE)) {
if (component.getFocusOwner() == null) {
throw new RuntimeException(
"AccessibleStateSet contains ACTIVE but " +
"this component is not active");
}
} else {
if (component.getFocusOwner() != null) {
throw new RuntimeException(
"AccessibleStateSet does not contain ACTIVE but " +
"this component is active");
}
}
}
}
}

View File

@ -0,0 +1,100 @@
/*
* Copyright (c) 1997, 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
* @key headful
* @summary Label Accessibility test.
* @library ../../swing/regtesthelpers/accessibility/
* @build AccessibleTestUtils AccessibleComponentTester AccessibleStateSetTester
* @run main LabelTest
*/
import java.awt.AWTException;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Label;
import java.awt.Robot;
import java.lang.reflect.InvocationTargetException;
public class LabelTest {
private static Label label;
private static Frame frame;
private static final String ACCESSIBLE_NAME = "Label Test";
private static final String ACCESSIBLE_DESCRIPTION =
"Regression Test: javax.accessibility, Label";
public static void main(String[] args) throws InterruptedException,
InvocationTargetException, AWTException {
LabelTest labelTest = new LabelTest();
EventQueue.invokeAndWait(labelTest::createGUI);
Robot robot = new Robot();
robot.waitForIdle();
robot.delay(5000);
try {
EventQueue.invokeAndWait(labelTest::test);
} finally {
labelTest.dispose();
}
}
private void createGUI() {
frame = new Frame("Label Test");
label = new Label("This is a label");
label.getAccessibleContext().setAccessibleName(ACCESSIBLE_NAME);
label.getAccessibleContext().setAccessibleDescription(
ACCESSIBLE_DESCRIPTION);
frame.add(label);
frame.setSize(200, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void dispose() throws InterruptedException,
InvocationTargetException {
EventQueue.invokeAndWait(() -> {
if (frame != null) {
frame.dispose();
}
});
}
private void test() {
AccessibleTestUtils.verifyLabelAccessibility(
label,
ACCESSIBLE_NAME,
ACCESSIBLE_DESCRIPTION
);
new AccessibleStateSetTester(
label,
label.getAccessibleContext().getAccessibleStateSet()
).testAll();
}
}

View File

@ -0,0 +1,157 @@
/*
* Copyright (c) 1997, 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
* @key headful
* @summary List Accessibility test.
* @library ../../swing/regtesthelpers/accessibility/
* @build AccessibleTestUtils AccessibleComponentTester AccessibleStateSetTester
* @run main ListTest
*/
import java.awt.AWTException;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.List;
import java.awt.Robot;
import java.lang.reflect.InvocationTargetException;
import javax.accessibility.AccessibleState;
import javax.accessibility.AccessibleStateSet;
public class ListTest {
private static List list;
private static Frame frame;
private static final String ACCESSIBLE_NAME = "List Test";
private static final String ACCESSIBLE_DESCRIPTION =
"Regression Test: javax.accessibility, List";
public static void main(String[] args) throws InterruptedException,
InvocationTargetException, AWTException {
ListTest listTest = new ListTest();
EventQueue.invokeAndWait(listTest::createGUI);
Robot robot = new Robot();
robot.waitForIdle();
robot.delay(5000);
try {
EventQueue.invokeAndWait(listTest::test);
} finally {
listTest.dispose();
}
}
private void createGUI() {
frame = new Frame("List Test");
list = new List();
list.add("Mercury");
list.add("Venus");
list.add("Earth");
list.add("JavaSoft");
list.add("Mars");
list.add("Jupiter");
list.add("Saturn");
list.add("Uranus");
list.add("Neptune");
list.add("Pluto");
list.getAccessibleContext().setAccessibleName(ACCESSIBLE_NAME);
list.getAccessibleContext().setAccessibleDescription(
ACCESSIBLE_DESCRIPTION);
frame.add(list);
frame.setSize(200, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void dispose() throws InterruptedException,
InvocationTargetException {
EventQueue.invokeAndWait(() -> {
if (frame != null) {
frame.dispose();
}
});
}
private void test() {
AccessibleTestUtils.verifyListAccessibility(
list,
ACCESSIBLE_NAME,
ACCESSIBLE_DESCRIPTION
);
new ListStateTester(
list,
list.getAccessibleContext().getAccessibleStateSet()
).testAll();
list.setMultipleMode(!list.isMultipleMode());
AccessibleTestUtils.verifyListAccessibility(
list,
ACCESSIBLE_NAME,
ACCESSIBLE_DESCRIPTION
);
new ListStateTester(
list,
list.getAccessibleContext().getAccessibleStateSet()
).testAll();
}
private static final class ListStateTester
extends AccessibleStateSetTester {
private final List list;
private final AccessibleStateSet set;
private ListStateTester(List list, AccessibleStateSet set) {
super(list, set);
this.list = list;
this.set = set;
}
@Override
public void testMultiSelectable() {
if (set.contains(AccessibleState.MULTISELECTABLE)) {
if (!list.isMultipleMode()) {
throw new RuntimeException(
"AccessibleStateSet contains MULTISELECTABLE " +
"but this component is not multiselectable");
}
} else {
if (list.isMultipleMode()) {
throw new RuntimeException(
"AccessibleStateSet does not contain " +
"MULTISELECTABLE but this component is " +
"multiselectable");
}
}
}
}
}

View File

@ -0,0 +1,102 @@
/*
* Copyright (c) 1997, 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
* @key headful
* @summary MenuBar Accessibility test.
* @library ../../swing/regtesthelpers/accessibility/
* @build AccessibleTestUtils AccessibleMenuComponentTester
* @run main MenuBarTest
*/
import java.awt.AWTException;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.MenuItem;
import java.awt.Robot;
import java.lang.reflect.InvocationTargetException;
public class MenuBarTest {
private static MenuBar menuBar;
private static Frame frame;
private static final String ACCESSIBLE_NAME = "Menu Test";
private static final String ACCESSIBLE_DESCRIPTION =
"Regression Test: javax.accessibility, MenuBar";
public static void main(String[] args) throws InterruptedException,
InvocationTargetException, AWTException {
MenuBarTest menuBarTest = new MenuBarTest();
EventQueue.invokeAndWait(menuBarTest::createGUI);
Robot robot = new Robot();
robot.waitForIdle();
robot.delay(5000);
try {
EventQueue.invokeAndWait(menuBarTest::test);
} finally {
menuBarTest.dispose();
}
}
private void createGUI() {
frame = new Frame("MenuBar Test");
menuBar = new MenuBar();
Menu menu = new Menu("Menu 1");
menu.add(new MenuItem("One"));
menu.add(new MenuItem("Two"));
menuBar.add(menu);
menuBar.getAccessibleContext().setAccessibleName(ACCESSIBLE_NAME);
menuBar.getAccessibleContext().setAccessibleDescription(
ACCESSIBLE_DESCRIPTION);
frame.setMenuBar(menuBar);
frame.setSize(200, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void dispose() throws InterruptedException,
InvocationTargetException {
EventQueue.invokeAndWait(() -> {
if (frame != null) {
frame.dispose();
}
});
}
private void test() {
AccessibleTestUtils.verifyMenuBarAccessibility(
menuBar,
ACCESSIBLE_NAME,
ACCESSIBLE_DESCRIPTION
);
}
}

View File

@ -0,0 +1,103 @@
/*
* Copyright (c) 1997, 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
* @key headful
* @summary MenuItem Accessibility test.
* @library ../../swing/regtesthelpers/accessibility/
* @build AccessibleTestUtils AccessibleMenuComponentTester
* @run main MenuItemTest
*/
import java.awt.AWTException;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.MenuItem;
import java.awt.Robot;
import java.lang.reflect.InvocationTargetException;
public class MenuItemTest {
private static MenuItem menuItem;
private static Frame frame;
private static final String ACCESSIBLE_NAME = "MenuItem Test";
private static final String ACCESSIBLE_DESCRIPTION =
"Regression Test: javax.accessibility, MenuItem";
public static void main(String[] args) throws InterruptedException,
InvocationTargetException, AWTException {
MenuItemTest menuItemTest = new MenuItemTest();
EventQueue.invokeAndWait(menuItemTest::createGUI);
Robot robot = new Robot();
robot.waitForIdle();
robot.delay(5000);
try {
EventQueue.invokeAndWait(menuItemTest::test);
} finally {
menuItemTest.dispose();
}
}
private void createGUI() {
frame = new Frame("MenuItem Test");
MenuBar menuBar = new MenuBar();
Menu menu = new Menu("Menu");
menuItem = new MenuItem("This here's a MenuItem");
menu.add(menuItem);
menuBar.add(menu);
menuItem.getAccessibleContext().setAccessibleName(ACCESSIBLE_NAME);
menuItem.getAccessibleContext().setAccessibleDescription(
ACCESSIBLE_DESCRIPTION);
frame.setMenuBar(menuBar);
frame.setSize(300, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void dispose() throws InterruptedException,
InvocationTargetException {
EventQueue.invokeAndWait(() -> {
if (frame != null) {
frame.dispose();
}
});
}
private void test() {
AccessibleTestUtils.verifyMenuItemAccessibility(
menuItem,
ACCESSIBLE_NAME,
ACCESSIBLE_DESCRIPTION
);
}
}

View File

@ -0,0 +1,99 @@
/*
* Copyright (c) 1997, 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
* @key headful
* @summary Menu Accessibility test.
* @library ../../swing/regtesthelpers/accessibility/
* @build AccessibleTestUtils AccessibleMenuComponentTester
* @run main MenuTest
*/
import java.awt.AWTException;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.Robot;
import java.lang.reflect.InvocationTargetException;
public class MenuTest {
private static Menu menu;
private static Frame frame;
private static final String ACCESSIBLE_NAME = "Menu Test";
private static final String ACCESSIBLE_DESCRIPTION =
"Regression Test: javax.accessibility, Menu";
public static void main(String[] args) throws InterruptedException,
InvocationTargetException, AWTException {
MenuTest menuTest = new MenuTest();
EventQueue.invokeAndWait(menuTest::createGUI);
Robot robot = new Robot();
robot.waitForIdle();
robot.delay(5000);
try {
EventQueue.invokeAndWait(menuTest::test);
} finally {
menuTest.dispose();
}
}
private void createGUI() {
frame = new Frame("Menu Test");
MenuBar menuBar = new MenuBar();
menu = new Menu("File");
menuBar.add(menu);
menu.getAccessibleContext().setAccessibleName(ACCESSIBLE_NAME);
menu.getAccessibleContext().setAccessibleDescription(
ACCESSIBLE_DESCRIPTION);
frame.setMenuBar(menuBar);
frame.setSize(200, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void dispose() throws InterruptedException,
InvocationTargetException {
EventQueue.invokeAndWait(() -> {
if (frame != null) {
frame.dispose();
}
});
}
private void test() {
AccessibleTestUtils.verifyMenuAccessibility(
menu,
ACCESSIBLE_NAME,
ACCESSIBLE_DESCRIPTION
);
}
}

View File

@ -0,0 +1,105 @@
/*
* Copyright (c) 1997, 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
* @key headful
* @summary Panel Accessibility test.
* @library ../../swing/regtesthelpers/accessibility/
* @build AccessibleTestUtils AccessibleComponentTester AccessibleStateSetTester
* @run main PanelTest
*/
import java.awt.AWTException;
import java.awt.Button;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Panel;
import java.awt.Robot;
import java.lang.reflect.InvocationTargetException;
public class PanelTest {
private static Panel panel;
private static Frame frame;
private static final String ACCESSIBLE_NAME = "Panel Test";
private static final String ACCESSIBLE_DESCRIPTION =
"Regression Test: javax.accessibility, Panel";
public static void main(String[] args) throws InterruptedException,
InvocationTargetException, AWTException {
PanelTest panelTest = new PanelTest();
EventQueue.invokeAndWait(panelTest::createGUI);
Robot robot = new Robot();
robot.waitForIdle();
robot.delay(5000);
try {
EventQueue.invokeAndWait(panelTest::test);
} finally {
panelTest.dispose();
}
}
private void createGUI() {
frame = new Frame("Panel Test");
panel = new Panel();
for (int i = 0; i < 5; i++) {
panel.add(new Button("Button #" + i));
}
panel.getAccessibleContext().setAccessibleName(ACCESSIBLE_NAME);
panel.getAccessibleContext().setAccessibleDescription(
ACCESSIBLE_DESCRIPTION);
frame.add(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void dispose() throws InterruptedException,
InvocationTargetException {
EventQueue.invokeAndWait(() -> {
if (frame != null) {
frame.dispose();
}
});
}
private void test() {
AccessibleTestUtils.verifyPanelAccessibility(
panel,
ACCESSIBLE_NAME,
ACCESSIBLE_DESCRIPTION
);
new AccessibleStateSetTester(
panel,
panel.getAccessibleContext().getAccessibleStateSet()
).testAll();
}
}

View File

@ -0,0 +1,100 @@
/*
* Copyright (c) 1997, 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
* @key headful
* @summary PopupMenu Accessibility test.
* @library ../../swing/regtesthelpers/accessibility/
* @build AccessibleTestUtils AccessibleMenuComponentTester
* @run main PopupMenuTest
*/
import java.awt.AWTException;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.PopupMenu;
import java.awt.Robot;
import java.lang.reflect.InvocationTargetException;
public class PopupMenuTest {
private static PopupMenu popupMenu;
private static Frame frame;
private static final String ACCESSIBLE_NAME = "PopupMenu Test";
private static final String ACCESSIBLE_DESCRIPTION =
"Regression Test: javax.accessibility, PopupMenu";
public static void main(String[] args) throws InterruptedException,
InvocationTargetException, AWTException {
PopupMenuTest popupMenuTest = new PopupMenuTest();
EventQueue.invokeAndWait(popupMenuTest::createGUI);
Robot robot = new Robot();
robot.waitForIdle();
robot.delay(5000);
try {
EventQueue.invokeAndWait(popupMenuTest::test);
} finally {
popupMenuTest.dispose();
}
}
private void createGUI() {
frame = new Frame("PopupMenu Test");
popupMenu = new PopupMenu("PopupMenu");
popupMenu.add("Sleepy");
popupMenu.add("Happy");
popupMenu.add("Grumpy");
popupMenu.add("Dopey");
popupMenu.getAccessibleContext().setAccessibleName(ACCESSIBLE_NAME);
popupMenu.getAccessibleContext().setAccessibleDescription(
ACCESSIBLE_DESCRIPTION);
frame.add(popupMenu);
frame.setSize(200, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void dispose() throws InterruptedException,
InvocationTargetException {
EventQueue.invokeAndWait(() -> {
if (frame != null) {
frame.dispose();
}
});
}
private void test() {
AccessibleTestUtils.verifyPopupMenuAccessibility(
popupMenu,
ACCESSIBLE_NAME,
ACCESSIBLE_DESCRIPTION
);
}
}

View File

@ -0,0 +1,104 @@
/*
* Copyright (c) 1997, 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
* @key headful
* @summary ScrollPane Accessibility test.
* @library ../../swing/regtesthelpers/accessibility/
* @build AccessibleTestUtils AccessibleComponentTester AccessibleStateSetTester
* @run main ScrollPaneTest
*/
import java.awt.AWTException;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Label;
import java.awt.Robot;
import java.awt.ScrollPane;
import java.lang.reflect.InvocationTargetException;
public class ScrollPaneTest {
private static ScrollPane scrollPane;
private static Frame frame;
private static final String ACCESSIBLE_NAME = "ScrollPane Test";
private static final String ACCESSIBLE_DESCRIPTION =
"Regression Test: javax.accessibility, ScrollPane";
public static void main(String[] args) throws InterruptedException,
InvocationTargetException, AWTException {
ScrollPaneTest scrollPaneTest = new ScrollPaneTest();
EventQueue.invokeAndWait(scrollPaneTest::createGUI);
Robot robot = new Robot();
robot.waitForIdle();
robot.delay(5000);
try {
EventQueue.invokeAndWait(scrollPaneTest::test);
} finally {
scrollPaneTest.dispose();
}
}
private void createGUI() {
frame = new Frame("ScrollPane Test");
frame.setSize(300, 300);
frame.setLocationRelativeTo(null);
scrollPane = new ScrollPane(ScrollPane.SCROLLBARS_ALWAYS);
scrollPane.setSize(frame.getSize().width, frame.getSize().height);
scrollPane.add(new Label("This is a label with quite a bit of text."));
scrollPane.getAccessibleContext().setAccessibleName(ACCESSIBLE_NAME);
scrollPane.getAccessibleContext().setAccessibleDescription(
ACCESSIBLE_DESCRIPTION);
frame.add(scrollPane);
frame.setVisible(true);
}
private void dispose() throws InterruptedException,
InvocationTargetException {
EventQueue.invokeAndWait(() -> {
if (frame != null) {
frame.dispose();
}
});
}
private void test() {
AccessibleTestUtils.verifyScrollPaneAccessibility(
scrollPane,
ACCESSIBLE_NAME,
ACCESSIBLE_DESCRIPTION
);
new AccessibleStateSetTester(
scrollPane,
scrollPane.getAccessibleContext().getAccessibleStateSet()
).testAll();
}
}

View File

@ -0,0 +1,155 @@
/*
* Copyright (c) 1997, 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
* @key headful
* @summary TextArea Accessibility test.
* @library ../../swing/regtesthelpers/accessibility/
* @build AccessibleTestUtils AccessibleComponentTester AccessibleStateSetTester
* @run main TextAreaTest
*/
import java.awt.AWTException;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Robot;
import java.awt.TextArea;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.lang.reflect.InvocationTargetException;
import javax.accessibility.AccessibleState;
import javax.accessibility.AccessibleStateSet;
public class TextAreaTest {
private static TextArea textArea;
private static Frame frame;
private static final String ACCESSIBLE_NAME = "TextArea Test";
private static final String ACCESSIBLE_DESCRIPTION =
"Regression Test: javax.accessibility, TextArea";
public static void main(String[] args) throws InterruptedException,
InvocationTargetException, AWTException {
TextAreaTest textAreaTest = new TextAreaTest();
EventQueue.invokeAndWait(textAreaTest::createGUI);
Robot robot = new Robot();
robot.waitForIdle();
robot.delay(5000);
try {
EventQueue.invokeAndWait(textAreaTest::test);
} finally {
textAreaTest.dispose();
}
}
private void createGUI() {
frame = new Frame("TextAreaTest");
String TEXT_CONTENT = """
1. Test TextArea javax.accessibility methods
2. Test TextArea javax.accessibility setAccessibleName
3. Test TextArea javax.accessibility setAccessibleDescription
4. Test TextArea javax.accessibility setAccessibleStateSet
""";
textArea = new TextArea(TEXT_CONTENT, 24, 80);
textArea.getAccessibleContext().setAccessibleName(ACCESSIBLE_NAME);
textArea.getAccessibleContext().setAccessibleDescription(
ACCESSIBLE_DESCRIPTION);
frame.add(textArea);
frame.setSize(200, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void dispose() throws InterruptedException,
InvocationTargetException {
EventQueue.invokeAndWait(() -> {
if (frame != null) {
frame.dispose();
}
});
}
private void test() {
AccessibleTestUtils.verifyTextAreaAccessibility(
textArea,
ACCESSIBLE_NAME,
ACCESSIBLE_DESCRIPTION
);
new TextStateTester(
textArea,
textArea.getAccessibleContext().getAccessibleStateSet()
).testAll();
textArea.setEditable(false);
AccessibleTestUtils.verifyTextAreaAccessibility(
textArea,
ACCESSIBLE_NAME,
ACCESSIBLE_DESCRIPTION
);
new TextStateTester(
textArea,
textArea.getAccessibleContext().getAccessibleStateSet()
).testAll();
}
private static final class TextStateTester
extends AccessibleStateSetTester {
private final TextArea textArea;
private final AccessibleStateSet stateSet;
private TextStateTester(TextArea textArea,
AccessibleStateSet stateSet) {
super(textArea, stateSet);
this.textArea = textArea;
this.stateSet = stateSet;
}
@Override
public void testEditable() {
if (stateSet.contains(AccessibleState.EDITABLE)) {
if (!textArea.isEditable()) {
throw new RuntimeException(
"AccessibleStateSet contains EDITABLE but " +
"this component is not editable");
}
} else {
if (textArea.isEditable()) {
throw new RuntimeException(
"AccessibleStateSet does not contain EDITABLE " +
"but this component is editable");
}
}
}
}
}

View File

@ -0,0 +1,148 @@
/*
* Copyright (c) 1997, 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
* @key headful
* @summary TextField Accessibility test.
* @library ../../swing/regtesthelpers/accessibility/
* @build AccessibleTestUtils AccessibleComponentTester AccessibleStateSetTester
* @run main TextFieldTest
*/
import java.awt.AWTException;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Robot;
import java.awt.TextField;
import java.lang.reflect.InvocationTargetException;
import javax.accessibility.AccessibleState;
import javax.accessibility.AccessibleStateSet;
public class TextFieldTest {
private static TextField textField;
private static Frame frame;
private static final String ACCESSIBLE_NAME = "TextField Test";
private static final String ACCESSIBLE_DESCRIPTION =
"Regression Test: javax.accessibility, TextField";
private static final String TEXT =
"I love Cheesy Poofs you love Cheesy Poofs if we didn't " +
"eat Cheesy Poofs we'd be lame!";
public static void main(String[] args) throws InterruptedException,
InvocationTargetException, AWTException {
TextFieldTest textFieldTest = new TextFieldTest();
EventQueue.invokeAndWait(textFieldTest::createGUI);
Robot robot = new Robot();
robot.waitForIdle();
robot.delay(5000);
try {
EventQueue.invokeAndWait(textFieldTest::test);
} finally {
textFieldTest.dispose();
}
}
private void createGUI() {
frame = new Frame("TextField Test");
textField = new TextField(TEXT, 80);
textField.getAccessibleContext().setAccessibleName(ACCESSIBLE_NAME);
textField.getAccessibleContext().setAccessibleDescription(
ACCESSIBLE_DESCRIPTION);
frame.add(textField);
frame.setSize(200, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void dispose() throws InterruptedException,
InvocationTargetException {
EventQueue.invokeAndWait(() -> {
if (frame != null) {
frame.dispose();
}
});
}
private void test() {
AccessibleTestUtils.verifyTextFieldAccessibility(
textField,
ACCESSIBLE_NAME,
ACCESSIBLE_DESCRIPTION
);
new TextStateTester(
textField,
textField.getAccessibleContext().getAccessibleStateSet()
).testAll();
textField.setEditable(false);
AccessibleTestUtils.verifyTextFieldAccessibility(
textField,
ACCESSIBLE_NAME,
ACCESSIBLE_DESCRIPTION
);
new TextStateTester(
textField,
textField.getAccessibleContext().getAccessibleStateSet()
).testAll();
}
private static final class TextStateTester
extends AccessibleStateSetTester {
private final TextField textField;
private final AccessibleStateSet set;
private TextStateTester(TextField textField, AccessibleStateSet set) {
super(textField, set);
this.textField = textField;
this.set = set;
}
@Override
public void testEditable() {
if (set.contains(AccessibleState.EDITABLE)) {
if (!textField.isEditable()) {
throw new RuntimeException(
"AccessibleStateSet contains EDITABLE but " +
"this component is not editable");
}
} else {
if (textField.isEditable()) {
throw new RuntimeException(
"AccessibleStateSet does not contain EDITABLE " +
"but this component is editable");
}
}
}
}
}

View File

@ -0,0 +1,129 @@
/*
* Copyright (c) 1997, 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
* @key headful
* @summary Window Accessibility test.
* @library ../../swing/regtesthelpers/accessibility/
* @build AccessibleTestUtils AccessibleComponentTester AccessibleStateSetTester
* @run main WindowTest
*/
import java.awt.AWTException;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Robot;
import java.awt.Window;
import java.lang.reflect.InvocationTargetException;
import javax.accessibility.AccessibleState;
import javax.accessibility.AccessibleStateSet;
public class WindowTest {
private static Window window;
private static final String ACCESSIBLE_NAME = "Window Test";
private static final String ACCESSIBLE_DESCRIPTION =
"Regression Test: javax.accessibility, Window";
public static void main(String[] args) throws InterruptedException,
InvocationTargetException, AWTException {
WindowTest windowTest = new WindowTest();
EventQueue.invokeAndWait(windowTest::createGUI);
Robot robot = new Robot();
robot.waitForIdle();
robot.delay(5000);
try {
EventQueue.invokeAndWait(windowTest::test);
} finally {
windowTest.dispose();
}
}
private void createGUI() {
window = new Window(new Frame("Frame"));
window.setSize(300, 300);
window.setLocationRelativeTo(null);
window.getAccessibleContext().setAccessibleName(ACCESSIBLE_NAME);
window.getAccessibleContext().setAccessibleDescription(
ACCESSIBLE_DESCRIPTION);
window.setVisible(true);
}
private void dispose() throws InterruptedException,
InvocationTargetException {
EventQueue.invokeAndWait(() -> {
if (window != null) {
window.dispose();
}
});
}
private void test() {
AccessibleTestUtils.verifyWindowAccessibility(
window,
ACCESSIBLE_NAME,
ACCESSIBLE_DESCRIPTION
);
new WindowStateTester(
window,
window.getAccessibleContext().getAccessibleStateSet()
).testAll();
}
private static final class WindowStateTester
extends AccessibleStateSetTester {
private final Window window;
private final AccessibleStateSet set;
private WindowStateTester(Window window, AccessibleStateSet set) {
super(window, set);
this.window = window;
this.set = set;
}
@Override
public void testActive() {
if (set.contains(AccessibleState.ACTIVE)) {
if (window.getFocusOwner() == null) {
throw new RuntimeException(
"AccessibleStateSet contains ACTIVE but " +
"this component is not active");
}
} else {
if (window.getFocusOwner() != null) {
throw new RuntimeException(
"AccessibleStateSet does not contain ACTIVE " +
"but this component is active");
}
}
}
}
}

View File

@ -0,0 +1,114 @@
/*
* Copyright (c) 1997, 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.
*/
import java.awt.Font;
import java.awt.MenuComponent;
import javax.accessibility.AccessibleComponent;
public class AccessibleMenuComponentTester {
private final AccessibleComponent acomp;
private final MenuComponent comp;
public AccessibleMenuComponentTester(MenuComponent menuComponent,
AccessibleComponent ac) {
if (menuComponent == null) {
throw new RuntimeException("MenuComponent should not be null");
}
if (ac == null) {
throw new RuntimeException("AccessibleComponent should not be null");
}
this.comp = menuComponent;
this.acomp = ac;
}
// The only method supported by MenuComponents is getFont(). Everything
// else should return null.
public void test() {
testGetBackground();
testGetBounds();
testGetCursor();
testGetFont();
testGetForeground();
testGetLocation();
testGetLocationOnScreen();
testGetSize();
testIsEnabled();
testIsFocusTraversable();
testIsShowing();
testIsVisible();
}
public void testGetBackground() {
}
public void testGetBounds() {
}
public void testGetCursor() {
}
public void testGetFont() {
Font accessibleFont = acomp.getFont();
Font componentFont = comp.getFont();
if (componentFont == null) {
if (accessibleFont != null) {
throw new RuntimeException(
"MenuComponent.getFont returned null but " +
"AccessibleComponent.getFont did not");
}
} else if (!componentFont.equals(accessibleFont)) {
throw new RuntimeException(
"AccessibleComponent.getFont does not match " +
"MenuComponent.getFont");
}
}
public void testGetForeground() {
}
public void testGetLocation() {
}
public void testGetLocationOnScreen() {
}
public void testGetSize() {
}
public void testIsEnabled() {
}
public void testIsFocusTraversable() {
}
public void testIsShowing() {
}
public void testIsVisible() {
}
}

View File

@ -22,17 +22,33 @@
*/
import java.awt.Button;
import java.awt.Checkbox;
import java.awt.Choice;
import java.awt.Component;
import java.awt.Frame;
import java.awt.Label;
import java.awt.List;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.MenuComponent;
import java.awt.MenuItem;
import java.awt.Panel;
import java.awt.PopupMenu;
import java.awt.Scrollbar;
import java.awt.ScrollPane;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.Window;
import java.util.Locale;
import java.util.Objects;
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleAction;
import javax.accessibility.AccessibleComponent;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
import javax.accessibility.AccessibleSelection;
import javax.accessibility.AccessibleState;
import javax.accessibility.AccessibleStateSet;
import javax.accessibility.AccessibleText;
import javax.accessibility.AccessibleValue;
@ -51,32 +67,22 @@ public final class AccessibleTestUtils {
boolean expectSelection,
boolean expectText,
boolean expectValue) {
Objects.requireNonNull(context, "AccessibleContext must not be null");
assertExpectedString(
"getAccessibleName",
expectedName,
context.getAccessibleName()
);
assertExpectedString("getAccessibleName",
expectedName, context.getAccessibleName());
assertExpectedString("getAccessibleDescription",
expectedDescription, context.getAccessibleDescription());
assertExpectedString(
"getAccessibleDescription",
expectedDescription,
context.getAccessibleDescription()
);
AccessibleRole actualRole = context.getAccessibleRole();
if (actualRole == null) {
throw new RuntimeException("getAccessibleRole returned null");
}
if (expectedRole != null) {
AccessibleRole actualRole = context.getAccessibleRole();
if (actualRole == null) {
throw new RuntimeException("getAccessibleRole returned null");
}
if (!expectedRole.equals(actualRole)) {
throw new RuntimeException(String.format(
"getAccessibleRole returned [%s]; expected [%s]",
actualRole, expectedRole
));
}
if (!expectedRole.equals(actualRole)) {
throw new RuntimeException(
"getAccessibleRole returned [" + actualRole +
"]; expected [" + expectedRole + "]");
}
AccessibleStateSet stateSet = context.getAccessibleStateSet();
@ -84,10 +90,14 @@ public final class AccessibleTestUtils {
throw new RuntimeException("getAccessibleStateSet returned null");
}
assertPresence("getAccessibleAction", expectAction, context.getAccessibleAction());
assertPresence("getAccessibleSelection", expectSelection, context.getAccessibleSelection());
assertPresence("getAccessibleText", expectText, context.getAccessibleText());
assertPresence("getAccessibleValue", expectValue, context.getAccessibleValue());
assertPresence("getAccessibleAction",
expectAction, context.getAccessibleAction());
assertPresence("getAccessibleSelection",
expectSelection, context.getAccessibleSelection());
assertPresence("getAccessibleText",
expectText, context.getAccessibleText());
assertPresence("getAccessibleValue",
expectValue, context.getAccessibleValue());
}
public static void verifyAWTComponentAccessibility(
@ -99,10 +109,13 @@ public final class AccessibleTestUtils {
boolean expectSelection,
boolean expectText,
boolean expectValue) {
Objects.requireNonNull(component, "Component under test must not be null");
Objects.requireNonNull(component, "Component must not be null");
AccessibleContext context = component.getAccessibleContext();
if (context == null) {
throw new RuntimeException("getAccessibleContext returned null");
}
verifyAccessibleContextCommon(
context,
expectedName,
@ -111,12 +124,12 @@ public final class AccessibleTestUtils {
expectAction,
expectSelection,
expectText,
expectValue
);
expectValue);
assertLocaleMatches(component, context);
AccessibleComponent accessibleComponent = context.getAccessibleComponent();
AccessibleComponent accessibleComponent =
context.getAccessibleComponent();
if (accessibleComponent == null) {
throw new RuntimeException("getAccessibleComponent returned null");
}
@ -124,101 +137,10 @@ public final class AccessibleTestUtils {
new AccessibleComponentTester(component, accessibleComponent).test();
}
public static void verifyChoiceAccessibility(
Choice choice,
String expectedName,
String expectedDescription) {
Objects.requireNonNull(choice, "Choice must not be null");
verifyAWTComponentAccessibility(
choice,
expectedName,
expectedDescription,
AccessibleRole.COMBO_BOX,
true,
false,
false,
false
);
AccessibleContext context = choice.getAccessibleContext();
AccessibleAction action = context.getAccessibleAction();
if (action == null) {
throw new RuntimeException("getAccessibleAction should not return null for Choice");
}
AccessibleValue value = context.getAccessibleValue();
if (value != null) {
throw new RuntimeException("getAccessibleValue should return null for Choice");
}
}
public static void verifyScrollbarAccessibility(
Scrollbar scrollbar,
String expectedName,
String expectedDescription) {
Objects.requireNonNull(scrollbar, "Scrollbar must not be null");
verifyAWTComponentAccessibility(
scrollbar,
expectedName,
expectedDescription,
AccessibleRole.SCROLL_BAR,
false,
false,
false,
true
);
AccessibleValue value = scrollbar.getAccessibleContext().getAccessibleValue();
if (value == null) {
throw new RuntimeException("getAccessibleValue should not return null for Scrollbar");
}
assertIntValueEquals(
"getCurrentAccessibleValue",
scrollbar.getValue(),
value.getCurrentAccessibleValue()
);
assertIntValueEquals(
"getMinimumAccessibleValue",
scrollbar.getMinimum(),
value.getMinimumAccessibleValue()
);
assertIntValueEquals(
"getMaximumAccessibleValue",
scrollbar.getMaximum(),
value.getMaximumAccessibleValue()
);
if (!value.setCurrentAccessibleValue(Integer.valueOf(5))) {
throw new RuntimeException("setCurrentAccessibleValue(5) returned false for Scrollbar");
}
assertIntValueEquals(
"getCurrentAccessibleValue after setCurrentAccessibleValue(5)",
5,
value.getCurrentAccessibleValue()
);
if (scrollbar.getValue() != 5) {
throw new RuntimeException(
"setCurrentAccessibleValue(5) did not update Scrollbar.getValue(); actual value: "
+ scrollbar.getValue()
);
}
}
public static void verifyButtonAccessibility(
Button button,
String expectedName,
String expectedDescription) {
Objects.requireNonNull(button, "Button must not be null");
verifyAWTComponentAccessibility(
@ -229,106 +151,576 @@ public final class AccessibleTestUtils {
true,
false,
false,
true
);
true);
AccessibleContext context = button.getAccessibleContext();
verifyClickAction(context, "Button");
verifyZeroAccessibleValue(context, "Button");
}
public static void verifyCheckboxAccessibility(
Checkbox checkbox,
String expectedName,
String expectedDescription) {
Objects.requireNonNull(checkbox, "Checkbox must not be null");
verifyAWTComponentAccessibility(
checkbox,
expectedName,
expectedDescription,
AccessibleRole.CHECK_BOX,
true,
false,
false,
true);
}
public static void verifyChoiceAccessibility(
Choice choice,
String expectedName,
String expectedDescription) {
Objects.requireNonNull(choice, "Choice must not be null");
verifyAWTComponentAccessibility(
choice,
expectedName,
expectedDescription,
AccessibleRole.COMBO_BOX,
true,
false,
false,
false);
}
public static void verifyFrameAccessibility(
Frame frame,
String expectedName,
String expectedDescription) {
Objects.requireNonNull(frame, "Frame must not be null");
verifyAWTComponentAccessibility(
frame,
expectedName,
expectedDescription,
AccessibleRole.FRAME,
false,
false,
false,
false);
}
public static void verifyLabelAccessibility(
Label label,
String expectedName,
String expectedDescription) {
Objects.requireNonNull(label, "Label must not be null");
verifyAWTComponentAccessibility(
label,
expectedName,
expectedDescription,
AccessibleRole.LABEL,
false,
false,
false,
false);
}
public static void verifyListAccessibility(
List list,
String expectedName,
String expectedDescription) {
Objects.requireNonNull(list, "List must not be null");
verifyAWTComponentAccessibility(
list,
expectedName,
expectedDescription,
AccessibleRole.LIST,
false,
true,
false,
false);
verifyListChildren(list);
}
public static void verifyPanelAccessibility(
Panel panel,
String expectedName,
String expectedDescription) {
Objects.requireNonNull(panel, "Panel must not be null");
verifyAWTComponentAccessibility(
panel,
expectedName,
expectedDescription,
AccessibleRole.PANEL,
false,
false,
false,
false);
verifyContainerChildren(panel, "Panel");
}
public static void verifyScrollbarAccessibility(
Scrollbar scrollbar,
String expectedName,
String expectedDescription) {
Objects.requireNonNull(scrollbar, "Scrollbar must not be null");
verifyAWTComponentAccessibility(
scrollbar,
expectedName,
expectedDescription,
AccessibleRole.SCROLL_BAR,
false,
false,
false,
true);
AccessibleValue value =
scrollbar.getAccessibleContext().getAccessibleValue();
assertIntValueEquals(
"getCurrentAccessibleValue",
scrollbar.getValue(),
value.getCurrentAccessibleValue());
assertIntValueEquals(
"getMinimumAccessibleValue",
scrollbar.getMinimum(),
value.getMinimumAccessibleValue());
assertIntValueEquals(
"getMaximumAccessibleValue",
scrollbar.getMaximum(),
value.getMaximumAccessibleValue());
if (!value.setCurrentAccessibleValue(Integer.valueOf(5))) {
throw new RuntimeException(
"setCurrentAccessibleValue should not return false " +
"for Scrollbar");
}
assertIntValueEquals(
"getCurrentAccessibleValue after setCurrentAccessibleValue(5)",
5,
value.getCurrentAccessibleValue());
if (scrollbar.getValue() != 5) {
throw new RuntimeException(
"setCurrentAccessibleValue should change the Scrollbar " +
"value");
}
}
public static void verifyScrollPaneAccessibility(
ScrollPane scrollPane,
String expectedName,
String expectedDescription) {
Objects.requireNonNull(scrollPane, "ScrollPane must not be null");
verifyAWTComponentAccessibility(
scrollPane,
expectedName,
expectedDescription,
AccessibleRole.SCROLL_PANE,
false,
false,
false,
false);
}
public static void verifyTextAreaAccessibility(
TextArea textArea,
String expectedName,
String expectedDescription) {
Objects.requireNonNull(textArea, "TextArea must not be null");
verifyAWTComponentAccessibility(
textArea,
expectedName,
expectedDescription,
AccessibleRole.TEXT,
false,
false,
true,
false);
}
public static void verifyTextFieldAccessibility(
TextField textField,
String expectedName,
String expectedDescription) {
Objects.requireNonNull(textField, "TextField must not be null");
verifyAWTComponentAccessibility(
textField,
expectedName,
expectedDescription,
AccessibleRole.TEXT,
false,
false,
true,
false);
}
public static void verifyWindowAccessibility(
Window window,
String expectedName,
String expectedDescription) {
Objects.requireNonNull(window, "Window must not be null");
verifyAWTComponentAccessibility(
window,
expectedName,
expectedDescription,
AccessibleRole.WINDOW,
false,
false,
false,
false);
}
public static void verifyMenuAccessibility(
Menu menu,
String expectedName,
String expectedDescription) {
Objects.requireNonNull(menu, "Menu must not be null");
verifyMenuComponentAccessibility(
menu,
expectedName,
expectedDescription,
AccessibleRole.MENU,
true,
true,
false,
true,
"Menu");
AccessibleContext context = menu.getAccessibleContext();
verifyClickAction(context, "Menu");
verifyZeroAccessibleValue(context, "Menu");
}
public static void verifyMenuBarAccessibility(
MenuBar menuBar,
String expectedName,
String expectedDescription) {
Objects.requireNonNull(menuBar, "MenuBar must not be null");
verifyMenuComponentAccessibility(
menuBar,
expectedName,
expectedDescription,
AccessibleRole.MENU_BAR,
false,
true,
false,
false,
"MenuBar");
}
public static void verifyMenuItemAccessibility(
MenuItem menuItem,
String expectedName,
String expectedDescription) {
Objects.requireNonNull(menuItem, "MenuItem must not be null");
verifyMenuComponentAccessibility(
menuItem,
expectedName,
expectedDescription,
AccessibleRole.MENU_ITEM,
true,
true,
false,
true,
"MenuItem");
AccessibleContext context = menuItem.getAccessibleContext();
verifyClickAction(context, "MenuItem");
verifyZeroAccessibleValue(context, "MenuItem");
}
public static void verifyPopupMenuAccessibility(
PopupMenu popupMenu,
String expectedName,
String expectedDescription) {
Objects.requireNonNull(popupMenu, "PopupMenu must not be null");
verifyMenuComponentAccessibility(
popupMenu,
expectedName,
expectedDescription,
AccessibleRole.POPUP_MENU,
true,
true,
false,
true,
"PopupMenu");
AccessibleContext context = popupMenu.getAccessibleContext();
verifyClickAction(context, "PopupMenu");
verifyZeroAccessibleValue(context, "PopupMenu");
}
private static void verifyMenuComponentAccessibility(
MenuComponent menuComponent,
String expectedName,
String expectedDescription,
AccessibleRole expectedRole,
boolean expectAction,
boolean expectSelection,
boolean expectText,
boolean expectValue,
String componentName) {
Objects.requireNonNull(menuComponent,
componentName + " must not be null");
AccessibleContext context = menuComponent.getAccessibleContext();
if (context == null) {
throw new RuntimeException("getAccessibleContext returned null");
}
verifyAccessibleContextCommon(
context,
expectedName,
expectedDescription,
expectedRole,
expectAction,
expectSelection,
expectText,
expectValue);
AccessibleComponent accessibleComponent =
context.getAccessibleComponent();
if (accessibleComponent == null) {
throw new RuntimeException("getAccessibleComponent returned null");
}
new AccessibleMenuComponentTester(
menuComponent, accessibleComponent).test();
}
private static void verifyClickAction(AccessibleContext context,
String componentName) {
AccessibleAction action = context.getAccessibleAction();
if (action == null) {
throw new RuntimeException("getAccessibleAction should not return null for Button");
throw new RuntimeException(
"getAccessibleAction should not return null for " +
componentName);
}
int actionCount = action.getAccessibleActionCount();
if (actionCount != 1) {
throw new RuntimeException(
"getAccessibleActionCount should return 1 for Button; got " + actionCount
);
"getAccessibleActionCount returned the wrong number for " +
componentName);
}
String actionDescription = action.getAccessibleActionDescription(0);
if (!"click".equals(actionDescription)) {
throw new RuntimeException(
"getAccessibleActionDescription(0) should return \"click\" for Button; got ["
+ actionDescription + "]"
);
"getAccessibleActionDescription returned the wrong " +
"description for " + componentName);
}
}
private static void verifyZeroAccessibleValue(AccessibleContext context,
String componentName) {
AccessibleValue value = context.getAccessibleValue();
if (value == null) {
throw new RuntimeException("getAccessibleValue should not return null for Button");
throw new RuntimeException(
"getAccessibleValue should not return null for " +
componentName);
}
assertIntValueEquals("getCurrentAccessibleValue", 0, value.getCurrentAccessibleValue());
assertIntValueEquals("getMinimumAccessibleValue", 0, value.getMinimumAccessibleValue());
assertIntValueEquals("getMaximumAccessibleValue", 0, value.getMaximumAccessibleValue());
assertIntValueEquals(
"getCurrentAccessibleValue",
0,
value.getCurrentAccessibleValue());
assertIntValueEquals(
"getMinimumAccessibleValue",
0,
value.getMinimumAccessibleValue());
assertIntValueEquals(
"getMaximumAccessibleValue",
0,
value.getMaximumAccessibleValue());
if (value.setCurrentAccessibleValue(Integer.valueOf(5))) {
throw new RuntimeException(
"setCurrentAccessibleValue(5) should return false for Button"
);
"setCurrentAccessibleValue should return false for " +
componentName);
}
assertIntValueEquals(
"getCurrentAccessibleValue after setCurrentAccessibleValue(5)",
0,
value.getCurrentAccessibleValue()
);
value.getCurrentAccessibleValue());
}
private static void assertExpectedString(String methodName, String expected, String actual) {
private static void verifyListChildren(List list) {
AccessibleContext context = list.getAccessibleContext();
int childCount = context.getAccessibleChildrenCount();
if (childCount != list.getItemCount()) {
throw new RuntimeException(
"getAccessibleChildrenCount returned an incorrect value " +
"for List");
}
for (int i = 0; i < childCount; i++) {
Accessible child = context.getAccessibleChild(i);
if (child == null) {
throw new RuntimeException(
"getAccessibleChild returned null for child " + i);
}
AccessibleContext childContext = child.getAccessibleContext();
if (childContext == null) {
throw new RuntimeException(
"getAccessibleContext returned null for List child " +
i);
}
if (childContext.getAccessibleRole() != AccessibleRole.LIST_ITEM) {
throw new RuntimeException(
"The AccessibleRole of AccessibleAWTListChild is " +
"incorrect for child " + i);
}
if (childContext.getAccessibleIndexInParent() != i) {
throw new RuntimeException(
"getAccessibleIndexInParent returned an incorrect " +
"value for AccessibleAWTListChild " + i);
}
AccessibleStateSet childStateSet =
childContext.getAccessibleStateSet();
if (childStateSet == null) {
throw new RuntimeException(
"getAccessibleStateSet returned null for List child " +
i);
}
boolean accessibleSelected =
childStateSet.contains(AccessibleState.SELECTED);
boolean listSelected = list.isIndexSelected(i);
if (accessibleSelected != listSelected) {
throw new RuntimeException(
"getAccessibleStateSet reports that list item " + i +
(accessibleSelected ? " is " : " is not ") +
"selected but List reports that it " +
(listSelected ? "is" : "is not") + " selected");
}
}
}
private static void verifyContainerChildren(Component component,
String componentName) {
AccessibleContext context = component.getAccessibleContext();
int childCount = context.getAccessibleChildrenCount();
if (childCount != component.getAccessibleContext()
.getAccessibleChildrenCount()) {
throw new RuntimeException(
"getAccessibleChildrenCount returned an incorrect value " +
"for " + componentName);
}
for (int i = 0; i < childCount; i++) {
Accessible child = context.getAccessibleChild(i);
if (child == null) {
throw new RuntimeException(
"getAccessibleChild returned null for " +
componentName + " child " + i);
}
AccessibleContext childContext = child.getAccessibleContext();
if (childContext == null) {
throw new RuntimeException(
"getAccessibleContext returned null for " +
componentName + " child " + i);
}
}
}
private static void assertExpectedString(String methodName,
String expected,
String actual) {
if (expected == null) {
throw new RuntimeException("Excepted value is null. Provide " +
"excepted value");
throw new RuntimeException(
"Expected value for " + methodName + " should not be null");
}
if (actual == null) {
throw new RuntimeException(methodName + " returned null; expected" +
" [" + expected + "]");
throw new RuntimeException(
methodName + " returned null; expected [" + expected + "]");
}
if (!expected.equals(actual)) {
throw new RuntimeException(methodName + " returned [" + actual +
"]; expected [" + expected + "]");
throw new RuntimeException(
methodName + " returned [" + actual +
"]; expected [" + expected + "]");
}
}
private static void assertPresence(String methodName, boolean expectedPresent, Object value) {
private static void assertPresence(String methodName,
boolean expectedPresent,
Object value) {
if (expectedPresent && value == null) {
throw new RuntimeException(methodName + " returned null but was expected");
throw new RuntimeException(
methodName + " returned null but should not");
}
if (!expectedPresent && value != null) {
throw new RuntimeException(methodName + " returned non-null but " +
"was expected to be null");
throw new RuntimeException(
methodName + " returned non-null but should return null");
}
}
private static void assertLocaleMatches(Component component, AccessibleContext context) {
private static void assertLocaleMatches(Component component,
AccessibleContext context) {
Locale componentLocale = component.getLocale();
Locale accessibleLocale = context.getLocale();
if (componentLocale == null) {
throw new RuntimeException("Component.getLocale returned null");
}
if (accessibleLocale == null) {
throw new RuntimeException("AccessibleContext.getLocale returned null");
throw new RuntimeException(
"AccessibleContext.getLocale returned null");
}
if (!componentLocale.equals(accessibleLocale)) {
throw new RuntimeException(String.format(
"AccessibleContext.getLocale returned [%s], but Component" +
".getLocale returned [%s]",
accessibleLocale, componentLocale
));
throw new RuntimeException(
"AccessibleContext.getLocale returned [" +
accessibleLocale + "], but Component.getLocale returned [" +
componentLocale + "]");
}
}
private static void assertIntValueEquals(String methodName, int expected, Number actual) {
private static void assertIntValueEquals(String methodName,
int expected,
Number actual) {
if (actual == null) {
throw new RuntimeException(methodName + " returned null; expected [" + expected + "]");
throw new RuntimeException(
methodName + " returned null; expected [" + expected + "]");
}
if (actual.intValue() != expected) {
throw new RuntimeException(
methodName + " returned [" + actual + "]; expected [" + expected + "]"
);
methodName + " returned [" + actual +
"]; expected [" + expected + "]");
}
}
}

View File

@ -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
@ -32,13 +32,15 @@
import java.net.InetAddress;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import jdk.test.lib.security.SecurityUtils;
import jdk.test.lib.process.ProcessTools;
import jdk.test.lib.Utils;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.process.ProcessTools;
import jdk.test.lib.security.SecurityUtils;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;
@ -50,29 +52,32 @@ import javax.net.ssl.SSLHandshakeException;
public class DisabledCipherSuitesNotNegotiated {
private static final String TLS_PROTOCOL = "TLSv1.2";
private static volatile int serverPort = 0;
private static volatile Exception serverException = null;
private static final CountDownLatch waitForServer = new CountDownLatch(1);
private static final int WAIT_FOR_SERVER_SECS = 5;
private static final int WAIT_FOR_SERVER_SECS = (int)Utils.adjustTimeout(5);
private static final String DISABLED_CIPHERSUITE = "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384";
private static final String DISABLED_CIPHER_WILDCARD = "TLS_ECDH*WITH_AES_256_GCM_*";
private static volatile Exception serverException = null;
private static void runServer(boolean disabledInClient) throws Exception {
SSLContext ctx = SSLContext.getInstance(TLS_PROTOCOL);
ctx.init(null, null, null);
SSLServerSocketFactory factory = ctx.getServerSocketFactory();
InetAddress address = InetAddress.getLoopbackAddress();
System.out.println("SERVER listening on " + address);
try(SSLServerSocket serverSocket = (SSLServerSocket)factory
.createServerSocket(0, -1, InetAddress.getLoopbackAddress())) {
serverPort = serverSocket.getLocalPort();
waitForServer.countDown();
.createServerSocket(0, -1, address)) {
if (disabledInClient) {
// set cipher suite to disabled ciphersuite
serverSocket.setEnabledCipherSuites(new String[]{DISABLED_CIPHERSUITE});
}
try(SSLSocket clientSocket = (SSLSocket) serverSocket.accept()) {
serverPort = serverSocket.getLocalPort();
serverSocket.setSoTimeout(WAIT_FOR_SERVER_SECS * 3000);
waitForServer.countDown();
try(SSLSocket clientSocket = (SSLSocket)serverSocket.accept()) {
try {
clientSocket.getInputStream().readAllBytes();
throw new Exception("SERVER: The expected handshake exception was not thrown.");
@ -88,7 +93,9 @@ public class DisabledCipherSuitesNotNegotiated {
SSLContext ctx = SSLContext.getInstance(TLS_PROTOCOL);
ctx.init(null, null, null);
SSLSocketFactory factory = ctx.getSocketFactory();
try(SSLSocket socket = (SSLSocket)factory.createSocket("localhost", portNumber)) {
InetAddress address = InetAddress.getLoopbackAddress();
System.out.println("CLIENT: Connecting to " + address);
try(SSLSocket socket = (SSLSocket)factory.createSocket(address, portNumber)) {
if (!disableInClient) {
socket.setEnabledCipherSuites(new String[]{DISABLED_CIPHERSUITE});
}
@ -104,42 +111,7 @@ public class DisabledCipherSuitesNotNegotiated {
public static void main(String [] args) throws Exception {
if (args.length == 1) {
// run server-side
final boolean disabledInClient = args[0].equals("client");
if (!disabledInClient) {
SecurityUtils.addToDisabledTlsAlgs(DISABLED_CIPHER_WILDCARD);
}
try(ExecutorService executorService = Executors.newSingleThreadExecutor()) {
executorService.submit(() -> {
try {
runServer(disabledInClient);
} catch (Exception exc) {
System.out.println("Server Exception:");
exc.printStackTrace(System.out);
serverException = exc;
throw new RuntimeException(exc);
}
});
if (!waitForServer.await(WAIT_FOR_SERVER_SECS, TimeUnit.SECONDS)) {
throw new Exception("Server did not start within " +
WAIT_FOR_SERVER_SECS + " seconds.");
}
System.out.printf("Server listening on port %d.%nStarting client process...",
serverPort);
OutputAnalyzer oa = ProcessTools.executeProcess(
ProcessTools.createTestJavaProcessBuilder("DisabledCipherSuitesNotNegotiated",
"" + disabledInClient, "" + serverPort));
oa.shouldHaveExitValue(0);
System.out.println("Client output:");
System.out.println(oa.getOutput());
if (serverException != null) {
throw new Exception ("Server-side threw an unexpected exception: "
+ serverException);
}
}
runTest(args[0].equals("client"));
} else if (args.length == 2) {
// run client-side
@ -147,6 +119,7 @@ public class DisabledCipherSuitesNotNegotiated {
if (disabledInClient) {
SecurityUtils.addToDisabledTlsAlgs(DISABLED_CIPHER_WILDCARD);
}
runClient(Boolean.parseBoolean(args[0]), Integer.parseInt(args[1]));
} else {
@ -155,4 +128,48 @@ public class DisabledCipherSuitesNotNegotiated {
}
}
private static void runTest(final boolean disabledInClient) throws Exception {
try(ExecutorService executorService = Executors.newSingleThreadExecutor()) {
Future<?> serverThread = executorService.submit(() -> {
try {
if (!disabledInClient) {
SecurityUtils.addToDisabledTlsAlgs(DISABLED_CIPHER_WILDCARD);
}
runServer(disabledInClient);
} catch (Exception exc) {
serverException = exc;
}
});
if (!waitForServer.await(WAIT_FOR_SERVER_SECS, TimeUnit.SECONDS)) {
throw new Exception("Server did not start within " +
WAIT_FOR_SERVER_SECS + " seconds.");
}
System.out.printf("Server listening on port %d.%nStarting client process...",
serverPort);
OutputAnalyzer oa = ProcessTools.executeProcess(
ProcessTools.createTestJavaProcessBuilder(
"DisabledCipherSuitesNotNegotiated",
"" + disabledInClient, "" + serverPort));
oa.waitFor();
serverThread.get();
System.out.printf("Client process return %d%nCLIENT OUTPUT%n%s%n",
oa.getExitValue(), oa.getOutput());
if (serverException != null) {
System.out.printf(
"Server thread threw an unexpected exception: %s%n",
serverException);
throw serverException;
} else if (oa.getExitValue() != 0) {
throw new Exception(String.format("Client exit code is non-zero (%d). "+
"Server did not throw an exception.",
oa.getExitValue()));
}
}
}
}

View File

@ -103,9 +103,9 @@ public class TestErasure extends JavadocTester {
checkOutput("Foo.html", true, """
<li><a href="#constructor-detail" tabindex="0">Constructor Details</a>
<ol class="toc-list">
<li><a href="#%3Cinit%3E(T)" tabindex="0">Foo(T)</a></li>
<li><a href="#%3Cinit%3E(X)" tabindex="0">Foo(T)</a></li>
<li><a href="#%3Cinit%3E(Y)" tabindex="0">Foo(T)</a></li>
<li><a href="#%3Cinit%3E(T)" tabindex="0">Foo(<wbr>T)</a></li>
<li><a href="#%3Cinit%3E(X)" tabindex="0">Foo(<wbr>T)</a></li>
<li><a href="#%3Cinit%3E(Y)" tabindex="0">Foo(<wbr>T)</a></li>
</ol>
</li>""");
checkOutput("index-all.html", true, """
@ -145,9 +145,9 @@ public class TestErasure extends JavadocTester {
checkOutput("Foo.html", true, """
<li><a href="#method-detail" tabindex="0">Method Details</a>
<ol class="toc-list">
<li><a href="#m(T)" tabindex="0">m(T)</a></li>
<li><a href="#m(X)" tabindex="0">m(T)</a></li>
<li><a href="#m(Y)" tabindex="0">m(T)</a></li>
<li><a href="#m(T)" tabindex="0">m(<wbr>T)</a></li>
<li><a href="#m(X)" tabindex="0">m(<wbr>T)</a></li>
<li><a href="#m(Y)" tabindex="0">m(<wbr>T)</a></li>
</ol>
</li>""");
checkOutput("index-all.html", true, """
@ -210,8 +210,8 @@ public class TestErasure extends JavadocTester {
checkOutput("Foo.html", true, """
<li><a href="#constructor-detail" tabindex="0">Constructor Details</a>
<ol class="toc-list">
<li><a href="#%3Cinit%3E(T)" tabindex="0">Foo(T)</a></li>
<li><a href="#%3Cinit%3E(X)" tabindex="0">Foo(T)</a></li>
<li><a href="#%3Cinit%3E(T)" tabindex="0">Foo(<wbr>T)</a></li>
<li><a href="#%3Cinit%3E(X)" tabindex="0">Foo(<wbr>T)</a></li>
</ol>
</li>""");
checkOutput("index-all.html", true, """
@ -242,8 +242,8 @@ public class TestErasure extends JavadocTester {
checkOutput("Foo.html", true, """
<li><a href="#method-detail" tabindex="0">Method Details</a>
<ol class="toc-list">
<li><a href="#m(T)" tabindex="0">m(T)</a></li>
<li><a href="#m(X)" tabindex="0">m(T)</a></li>
<li><a href="#m(T)" tabindex="0">m(<wbr>T)</a></li>
<li><a href="#m(X)" tabindex="0">m(<wbr>T)</a></li>
</ol>
</li>""");
checkOutput("index-all.html", true, """

View File

@ -25,7 +25,7 @@
* @test
* @bug 7025314 8023700 7198273 8025633 8026567 8081854 8196027 8182765
* 8196200 8196202 8223378 8258659 8261976 8320458 8329537 8350638
* 8342705 8371021 8373526
* 8342705 8371021 8373526 8384065
* @summary Make sure the Next/Prev Class links iterate through all types.
* Make sure the navagation is 2 columns, not 3.
* @library /tools/lib ../../lib
@ -172,6 +172,36 @@ public class TestNavigation extends JavadocTester {
tb.writeJavaFiles(src,
"""
package pkg1; public class A {
/**
* Empty ctor
*/
public A() {}
/**
* Single param ctor
*/
public A(int i) {}
/**
* A ctor with many params
*/
public A(int i, int j, int x, int y, String s, boolean b) {}
/**
* A method without parameters
*/
public void noParams() {}
/**
* A method with a single parameter
*/
public void oneParam(String s) {}
/**
* A method with lots of parameters
*/
public void manyParams(String s, int i, int j, boolean b, double d, double e) {}
/**
* Class with members.
*/
@ -217,6 +247,29 @@ public class TestNavigation extends JavadocTester {
"pkg1");
checkExit(Exit.OK);
checkOrder("pkg1/A.html",
"""
<ol class="toc-list" tabindex="-1">
<li><a href="#" tabindex="0">Description</a></li>
<li><a href="#nested-class-summary" tabindex="0">Nested Class Summary</a></li>
<li><a href="#constructor-summary" tabindex="0">Constructor Summary</a></li>
<li><a href="#method-summary" tabindex="0">Method Summary</a></li>
<li><a href="#constructor-detail" tabindex="0">Constructor Details</a>
<ol class="toc-list">
<li><a href="#%3Cinit%3E()" tabindex="0">A()</a></li>
<li><a href="#%3Cinit%3E(int)" tabindex="0">A(<wbr>int)</a></li>
<li><a href="#%3Cinit%3E(int,int,int,int,java.lang.String,boolean)" tabindex="0">A(<wbr>int, int, int, int, String, boolean)</a></li>
</ol>
</li>
<li><a href="#method-detail" tabindex="0">Method Details</a>
<ol class="toc-list">
<li><a href="#noParams()" tabindex="0">noParams()</a></li>
<li><a href="#oneParam(java.lang.String)" tabindex="0">oneParam(<wbr>String)</a></li>
<li><a href="#manyParams(java.lang.String,int,int,boolean,double,double)" tabindex="0">manyParams(<wbr>String, int, int, boolean, double, double)</a></li>
</ol>
</li>
</ol>""");
checkOrder("pkg1/A.X.html",
"""
<ol class="sub-nav-list">

View File

@ -288,7 +288,6 @@ public class TestStylesheet extends JavadocTester {
"field-summary",
"member-details",
"method-details",
"method-summary",
// the following provide the ability to optionally override components of the
// memberSignature structure
"name",

View File

@ -643,6 +643,8 @@ public class LingeredApp {
crasher.run();
}
}
// Force a GC now to reduce the risk of one happening during the loop below.
System.gc();
while (Files.exists(path)) {
// Touch the lock to indicate our readiness
setLastModified(theLockFileName, epoch());