Merge branch 'master' into pr-jdk-8380425

This commit is contained in:
Simon Tooke 2026-06-10 08:21:55 -04:00
commit d056fcd57d
35 changed files with 1048 additions and 229 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

@ -976,12 +976,9 @@ void ShenandoahBarrierStubC2::lrb(MacroAssembler& masm) {
if (c_rarg0 == _obj) {
__ lea(c_rarg1, _addr);
} else if (c_rarg1 == _obj) {
// Set up arguments in reverse, and then flip them
__ lea(c_rarg0, _addr);
// flip them
__ mov(_tmp1, c_rarg0);
__ mov(c_rarg0, c_rarg1);
__ mov(c_rarg1, _tmp1);
__ mov(_tmp1, c_rarg1);
__ lea(c_rarg1, _addr);
__ mov(c_rarg0, _tmp1);
} else {
assert_different_registers(c_rarg1, _obj);
__ lea(c_rarg1, _addr);

View File

@ -1210,12 +1210,9 @@ void ShenandoahBarrierStubC2::lrb(MacroAssembler& masm) {
if (c_rarg0 == _obj) {
__ addi(c_rarg1, _addr.base(), _addr.disp());
} else if (c_rarg1 == _obj) {
// Set up arguments in reverse, and then flip them
__ addi(c_rarg0, _addr.base(), _addr.disp());
// flip them
__ mr(_tmp1, c_rarg0);
__ mr(c_rarg0, c_rarg1);
__ mr(c_rarg1, _tmp1);
__ mr(_tmp1, c_rarg1);
__ addi(c_rarg1, _addr.base(), _addr.disp());
__ mr(c_rarg0, _tmp1);
} else {
assert_different_registers(c_rarg1, _obj);
__ addi(c_rarg1, _addr.base(), _addr.disp());

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

@ -912,12 +912,9 @@ void ShenandoahBarrierStubC2::lrb(MacroAssembler& masm) {
if (c_rarg0 == _obj) {
__ la(c_rarg1, _addr);
} else if (c_rarg1 == _obj) {
// Set up arguments in reverse, and then flip them
__ la(c_rarg0, _addr);
// flip them
__ mv(_tmp1, c_rarg0);
__ mv(c_rarg0, c_rarg1);
__ mv(c_rarg1, _tmp1);
__ mv(_tmp1, c_rarg1);
__ la(c_rarg1, _addr);
__ mv(c_rarg0, _tmp1);
} else {
assert_different_registers(c_rarg1, _obj);
__ la(c_rarg1, _addr);

View File

@ -120,10 +120,10 @@ define_pd_global(intx, InlineSmallCode, 1000);
product(bool, UseZvbb, false, EXPERIMENTAL, "Use Zvbb instructions") \
product(bool, UseZvbc, false, EXPERIMENTAL, "Use Zvbc instructions") \
product(bool, UseZvfh, false, DIAGNOSTIC, "Use Zvfh instructions") \
product(bool, UseZvkn, false, EXPERIMENTAL, \
product(bool, UseZvkg, false, DIAGNOSTIC, "Use Zvkg instructions") \
product(bool, UseZvkn, false, DIAGNOSTIC, \
"Use Zvkn group extension, Zvkned, Zvknhb, Zvkb, Zvkt") \
product(bool, UseCtxFencei, false, EXPERIMENTAL, \
"Use PR_RISCV_CTX_SW_FENCEI_ON to avoid explicit icache flush") \
product(bool, UseZvkg, false, EXPERIMENTAL, "Use Zvkg instructions")
"Use PR_RISCV_CTX_SW_FENCEI_ON to avoid explicit icache flush")
#endif // CPU_RISCV_GLOBALS_RISCV_HPP

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

@ -1,5 +1,5 @@
/*
* Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2023, Rivos Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -249,7 +249,6 @@ void RiscvHwprobe::add_features_from_query_result() {
if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZVFH)) {
VM_Version::ext_Zvfh.enable_feature();
}
#ifndef PRODUCT
if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZVKNED) &&
is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZVKNHB) &&
is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZVKB) &&
@ -259,7 +258,6 @@ void RiscvHwprobe::add_features_from_query_result() {
if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZVKG)) {
VM_Version::ext_Zvkg.enable_feature();
}
#endif
// ====== non-extensions ======
//

View File

@ -1268,8 +1268,7 @@ void PSParallelCompact::marking_phase(ParallelOldTracer *gc_tracer) {
#endif
}
template<typename Func>
void PSParallelCompact::adjust_in_space_helper(SpaceId id, Atomic<uint>* claim_counter, Func&& on_stripe) {
void PSParallelCompact::adjust_in_space_helper(SpaceId id, Atomic<uint>* claim_counter) {
MutableSpace* sp = PSParallelCompact::space(id);
HeapWord* const bottom = sp->bottom();
HeapWord* const top = sp->top();
@ -1288,53 +1287,46 @@ void PSParallelCompact::adjust_in_space_helper(SpaceId id, Atomic<uint>* claim_c
break;
}
HeapWord* stripe_end = MIN2(cur_stripe + stripe_size, top);
on_stripe(cur_stripe, stripe_end);
adjust_in_stripe(cur_stripe, stripe_end);
}
}
size_t PSParallelCompact::adjust_in_obj_with_limit(HeapWord* obj_start, HeapWord* left, HeapWord* right) {
precond(mark_bitmap()->is_marked(obj_start));
oop obj = cast_to_oop(obj_start);
return obj->oop_iterate_size(&pc_adjust_pointer_closure, MemRegion(left, right));
}
void PSParallelCompact::adjust_in_stripe(HeapWord* stripe_start, HeapWord* stripe_end) {
precond(_summary_data.is_region_aligned(stripe_start));
RegionData* cur_region = _summary_data.addr_to_region_ptr(stripe_start);
HeapWord* obj_start;
if (cur_region->partial_obj_size() != 0) {
obj_start = cur_region->partial_obj_addr();
obj_start += adjust_in_obj_with_limit(obj_start, stripe_start, stripe_end);
} else {
obj_start = stripe_start;
}
while (obj_start < stripe_end) {
obj_start = mark_bitmap()->find_obj_beg(obj_start, stripe_end);
if (obj_start >= stripe_end) {
break;
}
obj_start += adjust_in_obj_with_limit(obj_start, stripe_start, stripe_end);
}
}
void PSParallelCompact::adjust_in_old_space(Atomic<uint>* claim_counter) {
// Regions in old-space shouldn't be split.
assert(!_space_info[old_space_id].split_info().is_valid(), "inv");
precond(!_space_info[old_space_id].split_info().is_valid());
auto scan_obj_with_limit = [&] (HeapWord* obj_start, HeapWord* left, HeapWord* right) {
assert(mark_bitmap()->is_marked(obj_start), "inv");
oop obj = cast_to_oop(obj_start);
return obj->oop_iterate_size(&pc_adjust_pointer_closure, MemRegion(left, right));
};
adjust_in_space_helper(old_space_id, claim_counter, [&] (HeapWord* stripe_start, HeapWord* stripe_end) {
assert(_summary_data.is_region_aligned(stripe_start), "inv");
RegionData* cur_region = _summary_data.addr_to_region_ptr(stripe_start);
HeapWord* obj_start;
if (cur_region->partial_obj_size() != 0) {
obj_start = cur_region->partial_obj_addr();
obj_start += scan_obj_with_limit(obj_start, stripe_start, stripe_end);
} else {
obj_start = stripe_start;
}
while (obj_start < stripe_end) {
obj_start = mark_bitmap()->find_obj_beg(obj_start, stripe_end);
if (obj_start >= stripe_end) {
break;
}
obj_start += scan_obj_with_limit(obj_start, stripe_start, stripe_end);
}
});
adjust_in_space_helper(old_space_id, claim_counter);
}
void PSParallelCompact::adjust_in_young_space(SpaceId id, Atomic<uint>* claim_counter) {
adjust_in_space_helper(id, claim_counter, [](HeapWord* stripe_start, HeapWord* stripe_end) {
HeapWord* obj_start = stripe_start;
while (obj_start < stripe_end) {
obj_start = mark_bitmap()->find_obj_beg(obj_start, stripe_end);
if (obj_start >= stripe_end) {
break;
}
oop obj = cast_to_oop(obj_start);
obj_start += obj->oop_iterate_size(&pc_adjust_pointer_closure);
}
});
adjust_in_space_helper(id, claim_counter);
}
void PSParallelCompact::adjust_pointers_in_spaces(uint worker_id, Atomic<uint>* claim_counters) {

View File

@ -760,8 +760,11 @@ public:
// should_do_max_compaction controls whether all spaces for dead objs should be reclaimed.
static bool invoke(bool clear_all_soft_refs, bool should_do_max_compaction);
template<typename Func>
static void adjust_in_space_helper(SpaceId id, Atomic<uint>* claim_counter, Func&& on_stripe);
static void adjust_in_space_helper(SpaceId id, Atomic<uint>* claim_counter);
static size_t adjust_in_obj_with_limit(HeapWord* obj_start, HeapWord* left, HeapWord* right);
static void adjust_in_stripe(HeapWord* stripe_start, HeapWord* stripe_end);
static void adjust_in_old_space(Atomic<uint>* claim_counter);

View File

@ -194,6 +194,7 @@ void CardTable::resize_covered_region(MemRegion new_region) {
// Note that these versions are precise! The scanning code has to handle the
// fact that the write barrier may be either precise or imprecise.
void CardTable::dirty_MemRegion(MemRegion mr) {
assert(!mr.is_empty(), "precondition");
assert(align_down(mr.start(), HeapWordSize) == mr.start(), "Unaligned start");
assert(align_up (mr.end(), HeapWordSize) == mr.end(), "Unaligned end" );
assert(_covered[0].contains(mr) || _covered[1].contains(mr), "precondition");
@ -203,6 +204,7 @@ void CardTable::dirty_MemRegion(MemRegion mr) {
}
void CardTable::clear_MemRegion(MemRegion mr) {
assert(!mr.is_empty(), "precondition");
// Be conservative: only clean cards entirely contained within the
// region.
CardValue* cur;

View File

@ -130,7 +130,10 @@ oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
// pointer delta is scaled to number of elements (length field in
// objArrayOop) which we assume is 32 bit.
assert(pd == (size_t)(int)pd, "length field overflow");
bs->write_ref_array((HeapWord*)dst_raw, pd);
if (pd > 0) {
// Copied at least one element; call the barrier.
bs->write_ref_array((HeapWord*)dst_raw, pd);
}
return OopCopyResult::failed_check_class_cast;
}
}

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

@ -1745,8 +1745,8 @@ HeapWord* ShenandoahFreeSet::allocate_contiguous(ShenandoahAllocRequest& req, bo
for (idx_t i = beg; i <= end; i++) {
ShenandoahHeapRegion* r = _heap->get_region(i);
assert(i == beg || _heap->get_region(i - 1)->index() + 1 == r->index(), "Should be contiguous");
assert(r->is_empty(), "Should be empty");
r->try_recycle_under_lock();
assert(r->is_empty(), "Should be empty");
r->set_affiliation(req.affiliation());
r->make_regular_allocation(req.affiliation());
if ((i == end) && (used_words_in_last_region > 0)) {

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

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

@ -1921,6 +1921,31 @@ bool BoolNode::is_counted_loop_exit_test() {
return false;
}
template<typename IntegerType>
static const IntegerType* integral_abs_value(const IntegerType* t) {
typedef typename IntegerType::NativeUType NativeUType;
// Find the absolute value of a type, resulting in a range that fits inside the unsigned range [0, signed_max+1].
// The possible values of a TypeInteger is described with the following range in the signed domain:
// smin----------lo=======uhi--------0--------ulo===========hi----------smax
// To find the absolute value of the range, we find the closer (min) value of uhi and ulo to 0, and the further (max)
// value of lo and hi from 0. In the unsigned domain, the resulting range looks like this:
// 0-----------min(|ulo|,|uhi|)================max(|lo|,|hi|)-----------umax
// When the input range's hi and lo are both positive or negative, lo == ulo and hi == uhi:
// smin------------------------------0-------lo===========hi------------smax (Positive)
// smin--------lo===========hi-------0----------------------------------smax (Negative)
// For these ranges, the result in the unsigned domain is simply [min(|lo|, |hi|), max(|lo|, |hi|)]:
// 0-----------min(|lo|,|hi|)==================max(|lo|,|hi|)-----------umax
NativeUType umin = MIN2<NativeUType>(g_uabs(t->_ulo), g_uabs(t->_uhi));
NativeUType umax = MAX2<NativeUType>(g_uabs(t->_lo), g_uabs(t->_hi));
return IntegerType::make_unsigned(umin, umax, t->_widen);
}
//=============================================================================
//------------------------------Value------------------------------------------
const Type* AbsNode::Value(PhaseGVN* phase) const {
@ -1930,17 +1955,13 @@ const Type* AbsNode::Value(PhaseGVN* phase) const {
switch (t1->base()) {
case Type::Int: {
const TypeInt* ti = t1->is_int();
if (ti->is_con()) {
return TypeInt::make(g_uabs(ti->get_con()));
}
break;
return integral_abs_value(ti);
}
case Type::Long: {
const TypeLong* tl = t1->is_long();
if (tl->is_con()) {
return TypeLong::make(g_uabs(tl->get_con()));
}
break;
return integral_abs_value(tl);
}
case Type::FloatCon:
return TypeF::make(abs(t1->getf()));

View File

@ -1801,6 +1801,12 @@ const TypeInt* TypeInt::make(jint lo, jint hi, int widen) {
return make_or_top(TypeIntPrototype<jint, juint>{{lo, hi}, {0, max_juint}, {0, 0}}, widen)->is_int();
}
const TypeInt* TypeInt::make_unsigned(juint ulo, juint uhi, int widen) {
assert(ulo <= uhi, "must be legal bounds");
// By creating the TypeInt with the full signed range and the given unsigned range, the signed bounds are inferred from the unsigned bounds.
return make_or_top(TypeIntPrototype<jint, juint>{{min_jint, max_jint}, {ulo, uhi}, {0, 0}}, widen)->is_int();
}
const Type* TypeInt::make_or_top(const TypeIntPrototype<jint, juint>& t, int widen) {
return make_or_top(t, widen, false);
}
@ -1936,6 +1942,12 @@ const TypeLong* TypeLong::make(jlong lo, jlong hi, int widen) {
return make_or_top(TypeIntPrototype<jlong, julong>{{lo, hi}, {0, max_julong}, {0, 0}}, widen)->is_long();
}
const TypeLong* TypeLong::make_unsigned(julong ulo, julong uhi, int widen) {
assert(ulo <= uhi, "must be legal bounds");
// By creating the TypeLong with the full signed range and the given unsigned range, the signed bounds are inferred from the unsigned bounds.
return make_or_top(TypeIntPrototype<jlong, julong>{{min_jlong, max_jlong}, {ulo, uhi}, {0, 0}}, widen)->is_long();
}
const Type* TypeLong::make_or_top(const TypeIntPrototype<jlong, julong>& t, int widen) {
return make_or_top(t, widen, false);
}

View File

@ -782,6 +782,7 @@ protected:
public:
typedef jint NativeType;
typedef juint NativeUType;
virtual bool eq(const Type* t) const;
virtual uint hash() const; // Type specific hashing
virtual bool singleton(void) const; // TRUE if type is a singleton
@ -795,6 +796,7 @@ public:
static const TypeInt* make(jint con);
// must always specify w
static const TypeInt* make(jint lo, jint hi, int widen);
static const TypeInt* make_unsigned(juint ulo, juint uhi, int widen);
static const Type* make_or_top(const TypeIntPrototype<jint, juint>& t, int widen);
static const TypeInt* make(const TypeIntPrototype<jint, juint>& t, int widen) { return make_or_top(t, widen)->is_int(); }
static const TypeInt* make(const TypeIntMirror<jint, juint>& t, int widen) {
@ -871,6 +873,7 @@ protected:
virtual const Type* filter_helper(const Type* kills, bool include_speculative) const;
public:
typedef jlong NativeType;
typedef julong NativeUType;
virtual bool eq( const Type *t ) const;
virtual uint hash() const; // Type specific hashing
virtual bool singleton(void) const; // TRUE if type is a singleton
@ -885,6 +888,7 @@ public:
static const TypeLong* make(jlong con);
// must always specify w
static const TypeLong* make(jlong lo, jlong hi, int widen);
static const TypeLong* make_unsigned(julong ulo, julong uhi, int widen);
static const Type* make_or_top(const TypeIntPrototype<jlong, julong>& t, int widen);
static const TypeLong* make(const TypeIntPrototype<jlong, julong>& t, int widen) { return make_or_top(t, widen)->is_long(); }
static const TypeLong* make(const TypeIntMirror<jlong, julong>& t, int widen) {

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

@ -498,15 +498,18 @@ public final class ListFormat extends Format {
midIndex += mbLength;
}
}
parsed = new MessageFormat(createMessageFormatString(count), locale).parseObject(source, parsePos);
parsed = new MessageFormat(listToMessageFormatPattern(createMessageFormatString(count)),
locale).parseObject(source, parsePos);
}
}
if (parsed == null) {
// now try exact number patterns
parsed = new MessageFormat(patterns[TWO], locale).parseObject(source, parsePos);
parsed = new MessageFormat(listToMessageFormatPattern(patterns[TWO]),
locale).parseObject(source, parsePos);
if (parsed == null) {
parsed = new MessageFormat(patterns[THREE], locale).parseObject(source, parsePos);
parsed = new MessageFormat(listToMessageFormatPattern(patterns[THREE]),
locale).parseObject(source, parsePos);
}
}
@ -584,9 +587,9 @@ public final class ListFormat extends Format {
var len = input.length;
return switch (len) {
case 0 -> throw new IllegalArgumentException("There should at least be one input string");
case 1 -> new MessageFormat("{0}", locale);
case 2, 3 -> new MessageFormat(patterns[len + 1], locale);
default -> new MessageFormat(createMessageFormatString(len), locale);
case 1 -> new MessageFormat(listToMessageFormatPattern("{0}"), locale);
case 2, 3 -> new MessageFormat(listToMessageFormatPattern(patterns[len + 1]), locale);
default -> new MessageFormat(listToMessageFormatPattern(createMessageFormatString(len)), locale);
};
}
@ -742,4 +745,18 @@ public final class ListFormat extends Format {
return prefixPos < suffixPos ?
new int[] {prefixPos, suffixPos + suffix.length()} : null;
}
/**
* {@return the MessageFormat pattern corresponding to the passed ListFormat pattern}
*
* Single quotes must be escaped so they are interpreted as literal text
* as opposed to escaping delimiters when passed to MessageFormat. Everything
* else remains the same; ListFormat already handles other validation on its own.
*
* @param pattern list pattern to use
*/
private static String listToMessageFormatPattern(String pattern) {
return pattern.indexOf('\'') < 0 ? pattern :
pattern.replace("'", "''");
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -40,7 +40,7 @@ import java.util.Queue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.locks.ReentrantLock;
import java.util.zip.Adler32;
import java.util.zip.CRC32C;
import javax.crypto.KDF;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
@ -610,9 +610,9 @@ final class SSLSessionImpl extends ExtendedSSLSession {
}
private static int getChecksum(byte[] input) {
Adler32 adler32 = new Adler32();
adler32.update(input);
return (int) adler32.getValue();
CRC32C crc32c = new CRC32C();
crc32c.update(input);
return (int) crc32c.getValue();
}
void setMasterSecret(SecretKey secret) {

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) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -32,13 +32,13 @@ package java.awt.event;
* <P>
* Mouse motion events occur when a mouse is moved or dragged.
* (Many such events will be generated in a normal program.
* To track clicks and other mouse events, use the MouseAdapter.)
* To track clicks and other mouse events, use the {@link MouseAdapter}.)
* <P>
* Extend this class to create a {@code MouseEvent} listener
* and override the methods for the events of interest. (If you implement the
* {@code MouseMotionListener} interface, you have to define all of
* the methods in it. This abstract class defines null methods for them
* all, so you can only have to define methods for events you care about.)
* all, so you have to define only methods for events you care about.)
* <P>
* Create a listener object using the extended class and then register it with
* a component using the component's {@code addMouseMotionListener}
@ -61,17 +61,14 @@ public abstract class MouseMotionAdapter implements MouseMotionListener {
protected MouseMotionAdapter() {}
/**
* Invoked when a mouse button is pressed on a component and then
* dragged. Mouse drag events will continue to be delivered to
* the component where the first originated until the mouse button is
* released (regardless of whether the mouse position is within the
* bounds of the component).
* {@inheritDoc}
*/
@Override
public void mouseDragged(MouseEvent e) {}
/**
* Invoked when the mouse button has been moved on a component
* (with no buttons no down).
* {@inheritDoc}
*/
@Override
public void mouseMoved(MouseEvent e) {}
}

View File

@ -55,8 +55,6 @@
# * com.sun.management.jmxremote.password.toHashes property is set to true in
# management.properties file
# * the password file is writable
# * the system security policy allows writing into the password file, if a
# security manager is configured
#
# In order to change the password for a role, replace the hashed password entry
# with a new clear text password or a new hashed password. If the new password
@ -110,6 +108,6 @@
# below entries with clear passwords overwritten by their respective
# SHA3-512 hash
#
# monitorRole trilby APzBTt34rV2l+OMbuvbnOQ4si8UZmfRCVbIY1+fAofV5CkQzXS/FDMGteQQk/R3q1wtt104qImzJEA7gCwl6dw== 4EeTdSJ7X6Imu0Mb+dWqIns7a7QPIBoM3NB/XlpMQSPSicE7PnlALVWn2pBY3Q3pGDHyAb32Hd8GUToQbUhAjA== SHA3-512
# monitorRole APzBTt34rV2l+OMbuvbnOQ4si8UZmfRCVbIY1+fAofV5CkQzXS/FDMGteQQk/R3q1wtt104qImzJEA7gCwl6dw== 4EeTdSJ7X6Imu0Mb+dWqIns7a7QPIBoM3NB/XlpMQSPSicE7PnlALVWn2pBY3Q3pGDHyAb32Hd8GUToQbUhAjA== SHA3-512
# controlRole roHEJSbRqSSTII4Z4+NOCV2OJaZVQ/dw153Fy2u4ILDP9XiZ426GwzCzc3RtpoqNMwqYIcfdd74xWXSMrWtGaA== w9qDsekgKn0WOVJycDyU0kLBa081zbStcCjUAVEqlfon5Sgx7XHtaodbmzpLegA1jT7Ag36T0zHaEWRHJe2fdA== SHA3-512
#
#

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2022, Arm Limited. All rights reserved.
* Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -24,18 +25,50 @@
package compiler.c2.irTests;
import jdk.test.lib.Asserts;
import compiler.lib.generators.*;
import compiler.lib.ir_framework.*;
/*
* @test
* @bug 8276673 8280089
* @bug 8276673 8280089 8349563
* @summary Test abs nodes optimization in C2.
* @requires os.arch=="amd64" | os.arch=="x86_64" | os.arch=="aarch64" | os.arch=="riscv64"
* @key randomness
* @library /test/lib /
* @run driver compiler.c2.irTests.TestIRAbs
*/
public class TestIRAbs {
private static final RestrictableGenerator<Integer> INTS = Generators.G.ints();
private static final RestrictableGenerator<Long> LONGS = Generators.G.longs();
private static final IntRange INT_RANGE = IntRange.generate(INTS);
private static final IntRange INT_FULL_RANGE = new IntRange(Integer.MIN_VALUE, Integer.MAX_VALUE);
private static final IntRange INT_UNSIGNED_MAX = new IntRange(-1, Integer.MAX_VALUE);
private static final IntRange INT_POSITIVE = new IntRange(0, Integer.MAX_VALUE);
private static final IntRange INT_NEGATIVE = new IntRange(Integer.MIN_VALUE, 0);
private static final LongRange LONG_RANGE = LongRange.generate(LONGS);
private static final LongRange LONG_FULL_RANGE = new LongRange(Long.MIN_VALUE, Long.MAX_VALUE);
private static final LongRange LONG_UNSIGNED_MAX = new LongRange(-1, Long.MAX_VALUE);
private static final LongRange LONG_POSITIVE = new LongRange(0, Long.MAX_VALUE);
private static final LongRange LONG_NEGATIVE = new LongRange(Long.MIN_VALUE, 0);
private static final int INT_1 = INTS.next();
private static final int INT_2 = INTS.next();
private static final int INT_3 = INTS.next();
private static final int INT_4 = INTS.next();
private static final int INT_5 = INTS.next();
private static final int INT_6 = INTS.next();
private static final int INT_7 = INTS.next();
private static final int INT_8 = INTS.next();
private static final long LONG_1 = LONGS.next();
private static final long LONG_2 = LONGS.next();
private static final long LONG_3 = LONGS.next();
private static final long LONG_4 = LONGS.next();
private static final long LONG_5 = LONGS.next();
private static final long LONG_6 = LONGS.next();
private static final long LONG_7 = LONGS.next();
private static final long LONG_8 = LONGS.next();
public static char [] cspecial = {
0, 42, 128, 256, 1024, 4096, 65535
@ -103,7 +136,7 @@ public class TestIRAbs {
}
@Test
@IR(failOn = {IRNode.ABS_I, IRNode.ABS_L, IRNode.ABS_F, IRNode.ABS_D})
@IR(failOn = {IRNode.ABS_I, IRNode.ABS_L, IRNode.ABS_F, IRNode.ABS_D}, applyIfPlatform = { "64-bit", "true" })
public void testAbsConstant() {
// Test abs(constant) optimization for int
Asserts.assertEquals(Integer.MAX_VALUE, Math.abs(Integer.MAX_VALUE));
@ -160,14 +193,14 @@ public class TestIRAbs {
}
@Test
@IR(counts = {IRNode.ABS_L, "1"})
@IR(counts = {IRNode.ABS_L, "1"}, applyIfPlatform = { "64-bit", "true" })
public long testLong0(long x) {
return Math.abs(Math.abs(x)); // transformed to Math.abs(x)
}
@Test
@IR(failOn = {IRNode.SUB_L})
@IR(counts = {IRNode.ABS_L, "1"})
@IR(failOn = {IRNode.SUB_L}, applyIfPlatform = { "64-bit", "true" })
@IR(counts = {IRNode.ABS_L, "1"}, applyIfPlatform = { "64-bit", "true" })
public long testLong1(long x) {
return Math.abs(0 - x); // transformed to Math.abs(x)
}
@ -229,4 +262,524 @@ public class TestIRAbs {
Asserts.assertEquals(cspecial[i], (char) Math.abs(cspecial[i]));
}
}
}
@Run(test = {"testIntRange1", "testIntRange2", "testIntRange3", "testIntRange4",
"testIntRangeFolding", "testIntFullRangeFolding", "testIntUnsignedMaxFolding",
"testIntPositiveRangeFolding", "testIntNegativeRangeFolding"})
public void checkIntRanges(RunInfo info) {
for (int i : ispecial) {
checkIntRange(i);
}
for (int j = 0; j < 20; j++) {
int i = INTS.next();
checkIntRange(i);
}
}
@DontCompile
public void checkIntRange(int i) {
Asserts.assertEquals(Math.abs((i & 7) - 4) > 4, testIntRange1(i));
Asserts.assertEquals(Math.abs((i & 7) - 4) < 0, testIntRange2(i));
Asserts.assertEquals(Math.abs(-((i & 7) + 2)) < 2, testIntRange3(i));
Asserts.assertEquals(Math.abs(-((i & 7) + 2)) > 9, testIntRange4(i));
Asserts.assertEquals(testIntRangeFoldingInterpreter(i), testIntRangeFolding(i));
Asserts.assertEquals(testIntFullRangeFoldingInterpreter(i), testIntFullRangeFolding(i));
Asserts.assertEquals(testIntUnsignedMaxFoldingInterpreter(i), testIntUnsignedMaxFolding(i));
Asserts.assertEquals(testIntPositiveRangeFoldingInterpreter(i), testIntPositiveRangeFolding(i));
Asserts.assertEquals(testIntNegativeRangeFoldingInterpreter(i), testIntNegativeRangeFolding(i));
}
@Run(test = {"testLongRange1", "testLongRange2", "testLongRange3", "testLongRange4",
"testLongRangeFolding", "testLongFullRangeFolding", "testLongUnsignedMaxFolding",
"testLongPositiveRangeFolding", "testLongNegativeRangeFolding"})
public void checkLongRanges(RunInfo info) {
for (long l : lspecial) {
checkLongRange(l);
}
for (int j = 0; j < 20; j++) {
long l = LONGS.next();
checkLongRange(l);
}
}
@DontCompile
public void checkLongRange(long l) {
Asserts.assertEquals(Math.abs((l & 7) - 4) > 4, testLongRange1(l));
Asserts.assertEquals(Math.abs((l & 7) - 4) < 0, testLongRange2(l));
Asserts.assertEquals(Math.abs(-((l & 7) + 2)) < 2, testLongRange3(l));
Asserts.assertEquals(Math.abs(-((l & 7) + 2)) > 9, testLongRange4(l));
Asserts.assertEquals(testLongRangeFoldingInterpreter(l), testLongRangeFolding(l));
Asserts.assertEquals(testLongFullRangeFoldingInterpreter(l), testLongFullRangeFolding(l));
Asserts.assertEquals(testLongUnsignedMaxFoldingInterpreter(l), testLongUnsignedMaxFolding(l));
Asserts.assertEquals(testLongPositiveRangeFoldingInterpreter(l), testLongPositiveRangeFolding(l));
Asserts.assertEquals(testLongNegativeRangeFoldingInterpreter(l), testLongNegativeRangeFolding(l));
}
// Int ranges
@Test
@IR(failOn = { IRNode.ABS_I })
public boolean testIntRange1(int in) {
// [-4, 3] => [0, 4]
return Math.abs((in & 7) - 4) > 4;
}
@Test
@IR(failOn = { IRNode.ABS_I })
public boolean testIntRange2(int in) {
// [-4, 3] => [0, 4]
return Math.abs((in & 7) - 4) < 0;
}
@Test
@IR(failOn = { IRNode.ABS_I })
public boolean testIntRange3(int in) {
// [-9, -2] => [2, 9]
return Math.abs(-((in & 7) + 2)) < 2;
}
@Test
@IR(failOn = { IRNode.ABS_I })
public boolean testIntRange4(int in) {
// [-9, -2] => [2, 9]
return Math.abs(-((in & 7) + 2)) > 9;
}
@Test
public int testIntRangeFolding(int in) {
int c = INT_RANGE.clamp(in);
int v = Math.abs(c);
int sum = 0;
if (v > INT_1) { sum += 1; }
if (v > INT_2) { sum += 2; }
if (v > INT_3) { sum += 4; }
if (v > INT_4) { sum += 8; }
if (v > INT_5) { sum += 16; }
if (v > INT_6) { sum += 32; }
if (v > INT_7) { sum += 64; }
if (v > INT_8) { sum += 128; }
return sum;
}
@DontCompile
public int testIntRangeFoldingInterpreter(int in) {
int c = INT_RANGE.clamp(in);
int v = Math.abs(c);
int sum = 0;
if (v > INT_1) { sum += 1; }
if (v > INT_2) { sum += 2; }
if (v > INT_3) { sum += 4; }
if (v > INT_4) { sum += 8; }
if (v > INT_5) { sum += 16; }
if (v > INT_6) { sum += 32; }
if (v > INT_7) { sum += 64; }
if (v > INT_8) { sum += 128; }
return sum;
}
@Test
public int testIntFullRangeFolding(int in) {
int c = INT_FULL_RANGE.clamp(in);
int v = Math.abs(c);
int sum = 0;
if (v > INT_1) { sum += 1; }
if (v > INT_2) { sum += 2; }
if (v > INT_3) { sum += 4; }
if (v > INT_4) { sum += 8; }
if (v > INT_5) { sum += 16; }
if (v > INT_6) { sum += 32; }
if (v > INT_7) { sum += 64; }
if (v > INT_8) { sum += 128; }
return sum;
}
@DontCompile
public int testIntFullRangeFoldingInterpreter(int in) {
int c = INT_FULL_RANGE.clamp(in);
int v = Math.abs(c);
int sum = 0;
if (v > INT_1) { sum += 1; }
if (v > INT_2) { sum += 2; }
if (v > INT_3) { sum += 4; }
if (v > INT_4) { sum += 8; }
if (v > INT_5) { sum += 16; }
if (v > INT_6) { sum += 32; }
if (v > INT_7) { sum += 64; }
if (v > INT_8) { sum += 128; }
return sum;
}
@Test
public int testIntUnsignedMaxFolding(int in) {
int c = INT_UNSIGNED_MAX.clamp(in);
int v = Math.abs(c);
int sum = 0;
if (v > INT_1) { sum += 1; }
if (v > INT_2) { sum += 2; }
if (v > INT_3) { sum += 4; }
if (v > INT_4) { sum += 8; }
if (v > INT_5) { sum += 16; }
if (v > INT_6) { sum += 32; }
if (v > INT_7) { sum += 64; }
if (v > INT_8) { sum += 128; }
return sum;
}
@DontCompile
public int testIntUnsignedMaxFoldingInterpreter(int in) {
int c = INT_UNSIGNED_MAX.clamp(in);
int v = Math.abs(c);
int sum = 0;
if (v > INT_1) { sum += 1; }
if (v > INT_2) { sum += 2; }
if (v > INT_3) { sum += 4; }
if (v > INT_4) { sum += 8; }
if (v > INT_5) { sum += 16; }
if (v > INT_6) { sum += 32; }
if (v > INT_7) { sum += 64; }
if (v > INT_8) { sum += 128; }
return sum;
}
@Test
public int testIntPositiveRangeFolding(int in) {
int c = INT_POSITIVE.clamp(in);
int v = Math.abs(c);
int sum = 0;
if (v > INT_1) { sum += 1; }
if (v > INT_2) { sum += 2; }
if (v > INT_3) { sum += 4; }
if (v > INT_4) { sum += 8; }
if (v > INT_5) { sum += 16; }
if (v > INT_6) { sum += 32; }
if (v > INT_7) { sum += 64; }
if (v > INT_8) { sum += 128; }
return sum;
}
@DontCompile
public int testIntPositiveRangeFoldingInterpreter(int in) {
int c = INT_POSITIVE.clamp(in);
int v = Math.abs(c);
int sum = 0;
if (v > INT_1) { sum += 1; }
if (v > INT_2) { sum += 2; }
if (v > INT_3) { sum += 4; }
if (v > INT_4) { sum += 8; }
if (v > INT_5) { sum += 16; }
if (v > INT_6) { sum += 32; }
if (v > INT_7) { sum += 64; }
if (v > INT_8) { sum += 128; }
return sum;
}
@Test
public int testIntNegativeRangeFolding(int in) {
int c = INT_NEGATIVE.clamp(in);
int v = Math.abs(c);
int sum = 0;
if (v > INT_1) { sum += 1; }
if (v > INT_2) { sum += 2; }
if (v > INT_3) { sum += 4; }
if (v > INT_4) { sum += 8; }
if (v > INT_5) { sum += 16; }
if (v > INT_6) { sum += 32; }
if (v > INT_7) { sum += 64; }
if (v > INT_8) { sum += 128; }
return sum;
}
@DontCompile
public int testIntNegativeRangeFoldingInterpreter(int in) {
int c = INT_NEGATIVE.clamp(in);
int v = Math.abs(c);
int sum = 0;
if (v > INT_1) { sum += 1; }
if (v > INT_2) { sum += 2; }
if (v > INT_3) { sum += 4; }
if (v > INT_4) { sum += 8; }
if (v > INT_5) { sum += 16; }
if (v > INT_6) { sum += 32; }
if (v > INT_7) { sum += 64; }
if (v > INT_8) { sum += 128; }
return sum;
}
// Long ranges
@Test
@IR(failOn = { IRNode.ABS_L }, applyIfPlatform = { "64-bit", "true" })
public boolean testLongRange1(long in) {
// [-4, 3] => [0, 4]
return Math.abs((in & 7) - 4) > 4;
}
@Test
@IR(failOn = { IRNode.ABS_L }, applyIfPlatform = { "64-bit", "true" })
public boolean testLongRange2(long in) {
// [-4, 3] => [0, 4]
return Math.abs((in & 7) - 4) < 0;
}
@Test
@IR(failOn = { IRNode.ABS_L }, applyIfPlatform = { "64-bit", "true" })
public boolean testLongRange3(long in) {
// [-9, -2] => [2, 9]
return Math.abs(-((in & 7) + 2)) < 2;
}
@Test
@IR(failOn = { IRNode.ABS_L }, applyIfPlatform = { "64-bit", "true" })
public boolean testLongRange4(long in) {
// [-9, -2] => [2, 9]
return Math.abs(-((in & 7) + 2)) > 9;
}
@Test
public int testLongRangeFolding(long in) {
long c = LONG_RANGE.clamp(in);
long v = Math.abs(c);
int sum = 0;
if (v > LONG_1) { sum += 1; }
if (v > LONG_2) { sum += 2; }
if (v > LONG_3) { sum += 4; }
if (v > LONG_4) { sum += 8; }
if (v > LONG_5) { sum += 16; }
if (v > LONG_6) { sum += 32; }
if (v > LONG_7) { sum += 64; }
if (v > LONG_8) { sum += 128; }
return sum;
}
@DontCompile
public int testLongRangeFoldingInterpreter(long in) {
long c = LONG_RANGE.clamp(in);
long v = Math.abs(c);
int sum = 0;
if (v > LONG_1) { sum += 1; }
if (v > LONG_2) { sum += 2; }
if (v > LONG_3) { sum += 4; }
if (v > LONG_4) { sum += 8; }
if (v > LONG_5) { sum += 16; }
if (v > LONG_6) { sum += 32; }
if (v > LONG_7) { sum += 64; }
if (v > LONG_8) { sum += 128; }
return sum;
}
@Test
public int testLongFullRangeFolding(long in) {
long c = LONG_FULL_RANGE.clamp(in);
long v = Math.abs(c);
int sum = 0;
if (v > LONG_1) { sum += 1; }
if (v > LONG_2) { sum += 2; }
if (v > LONG_3) { sum += 4; }
if (v > LONG_4) { sum += 8; }
if (v > LONG_5) { sum += 16; }
if (v > LONG_6) { sum += 32; }
if (v > LONG_7) { sum += 64; }
if (v > LONG_8) { sum += 128; }
return sum;
}
@DontCompile
public int testLongFullRangeFoldingInterpreter(long in) {
long c = LONG_FULL_RANGE.clamp(in);
long v = Math.abs(c);
int sum = 0;
if (v > LONG_1) { sum += 1; }
if (v > LONG_2) { sum += 2; }
if (v > LONG_3) { sum += 4; }
if (v > LONG_4) { sum += 8; }
if (v > LONG_5) { sum += 16; }
if (v > LONG_6) { sum += 32; }
if (v > LONG_7) { sum += 64; }
if (v > LONG_8) { sum += 128; }
return sum;
}
@Test
public int testLongUnsignedMaxFolding(long in) {
long c = LONG_UNSIGNED_MAX.clamp(in);
long v = Math.abs(c);
int sum = 0;
if (v > LONG_1) { sum += 1; }
if (v > LONG_2) { sum += 2; }
if (v > LONG_3) { sum += 4; }
if (v > LONG_4) { sum += 8; }
if (v > LONG_5) { sum += 16; }
if (v > LONG_6) { sum += 32; }
if (v > LONG_7) { sum += 64; }
if (v > LONG_8) { sum += 128; }
return sum;
}
@DontCompile
public int testLongUnsignedMaxFoldingInterpreter(long in) {
long c = LONG_UNSIGNED_MAX.clamp(in);
long v = Math.abs(c);
int sum = 0;
if (v > LONG_1) { sum += 1; }
if (v > LONG_2) { sum += 2; }
if (v > LONG_3) { sum += 4; }
if (v > LONG_4) { sum += 8; }
if (v > LONG_5) { sum += 16; }
if (v > LONG_6) { sum += 32; }
if (v > LONG_7) { sum += 64; }
if (v > LONG_8) { sum += 128; }
return sum;
}
@Test
public int testLongPositiveRangeFolding(long in) {
long c = LONG_POSITIVE.clamp(in);
long v = Math.abs(c);
int sum = 0;
if (v > LONG_1) { sum += 1; }
if (v > LONG_2) { sum += 2; }
if (v > LONG_3) { sum += 4; }
if (v > LONG_4) { sum += 8; }
if (v > LONG_5) { sum += 16; }
if (v > LONG_6) { sum += 32; }
if (v > LONG_7) { sum += 64; }
if (v > LONG_8) { sum += 128; }
return sum;
}
@DontCompile
public int testLongPositiveRangeFoldingInterpreter(long in) {
long c = LONG_POSITIVE.clamp(in);
long v = Math.abs(c);
int sum = 0;
if (v > LONG_1) { sum += 1; }
if (v > LONG_2) { sum += 2; }
if (v > LONG_3) { sum += 4; }
if (v > LONG_4) { sum += 8; }
if (v > LONG_5) { sum += 16; }
if (v > LONG_6) { sum += 32; }
if (v > LONG_7) { sum += 64; }
if (v > LONG_8) { sum += 128; }
return sum;
}
@Test
public int testLongNegativeRangeFolding(long in) {
long c = LONG_NEGATIVE.clamp(in);
long v = Math.abs(c);
int sum = 0;
if (v > LONG_1) { sum += 1; }
if (v > LONG_2) { sum += 2; }
if (v > LONG_3) { sum += 4; }
if (v > LONG_4) { sum += 8; }
if (v > LONG_5) { sum += 16; }
if (v > LONG_6) { sum += 32; }
if (v > LONG_7) { sum += 64; }
if (v > LONG_8) { sum += 128; }
return sum;
}
@DontCompile
public int testLongNegativeRangeFoldingInterpreter(long in) {
long c = LONG_NEGATIVE.clamp(in);
long v = Math.abs(c);
int sum = 0;
if (v > LONG_1) { sum += 1; }
if (v > LONG_2) { sum += 2; }
if (v > LONG_3) { sum += 4; }
if (v > LONG_4) { sum += 8; }
if (v > LONG_5) { sum += 16; }
if (v > LONG_6) { sum += 32; }
if (v > LONG_7) { sum += 64; }
if (v > LONG_8) { sum += 128; }
return sum;
}
record IntRange(int lo, int hi) {
IntRange {
if (lo > hi) {
throw new IllegalArgumentException("lo > hi");
}
}
int clamp(int v) {
return Math.min(hi, Math.max(v, lo));
}
static IntRange generate(Generator<Integer> g) {
var a = g.next();
var b = g.next();
if (a > b) {
var tmp = a;
a = b;
b = tmp;
}
return new IntRange(a, b);
}
}
record LongRange(long lo, long hi) {
LongRange {
if (lo > hi) {
throw new IllegalArgumentException("lo > hi");
}
}
long clamp(long v) {
return Math.min(hi, Math.max(v, lo));
}
static LongRange generate(Generator<Long> g) {
var a = g.next();
var b = g.next();
if (a > b) {
var tmp = a;
a = b;
b = tmp;
}
return new LongRange(a, b);
}
}
}

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

@ -23,7 +23,7 @@
/*
* @test
* @bug 8041488 8316974 8318569 8306116 8385736 8385834
* @bug 8041488 8316974 8318569 8306116 8385736 8385834 8386200
* @summary Tests for ListFormat class
* @run junit TestListFormat
*/
@ -74,6 +74,14 @@ public class TestListFormat {
"",
"",
};
// Ensures MessageFormat single quotes in custom patterns are treated as literals.
private static final String[] CUSTOM_PATTERNS_SINGLE_QUOTE = {
"' {0} ' {1}",
"{0} '' {1}",
"{0} ''' {1} '''",
"",
"",
};
private static final String[] CUSTOM_PATTERNS_IAE_START = {
"{0}",
"{0} mid {1}",
@ -142,6 +150,10 @@ public class TestListFormat {
arguments(CUSTOM_PATTERNS_METACHAR, SAMPLE2, ". foo | bar ["),
arguments(CUSTOM_PATTERNS_METACHAR, SAMPLE3, ". foo * bar | baz ["),
arguments(CUSTOM_PATTERNS_METACHAR, SAMPLE4, ". foo * bar + baz | qux ["),
arguments(CUSTOM_PATTERNS_SINGLE_QUOTE, SAMPLE1, "foo"),
arguments(CUSTOM_PATTERNS_SINGLE_QUOTE, SAMPLE2, "' foo ''' bar '''"),
arguments(CUSTOM_PATTERNS_SINGLE_QUOTE, SAMPLE3, "' foo ' bar ''' baz '''"),
arguments(CUSTOM_PATTERNS_SINGLE_QUOTE, SAMPLE4, "' foo ' bar '' baz ''' qux '''")
};
}