diff --git a/doc/building.html b/doc/building.html index 3aad6eae0742b..69fb371a4770f 100644 --- a/doc/building.html +++ b/doc/building.html @@ -1499,9 +1499,7 @@
If the target architecture is riscv64
, the path should
-be debian-ports
instead of debian
.
To create an Ubuntu-based chroot:
sudo debootstrap \
--arch=arm64 \
diff --git a/doc/building.md b/doc/building.md
index 611cfe15915c8..abbd935f652ab 100644
--- a/doc/building.md
+++ b/doc/building.md
@@ -1316,9 +1316,6 @@ For example, cross-compiling to AArch64 from x86_64 could be done like this:
https://httpredir.debian.org/debian/
```
- If the target architecture is `riscv64`, the path should be `debian-ports`
- instead of `debian`.
-
* To create an Ubuntu-based chroot:
```
diff --git a/make/jdk/src/classes/build/tools/cldrconverter/CLDRConverter.java b/make/jdk/src/classes/build/tools/cldrconverter/CLDRConverter.java
index b6298c00c9a19..442a245f92fea 100644
--- a/make/jdk/src/classes/build/tools/cldrconverter/CLDRConverter.java
+++ b/make/jdk/src/classes/build/tools/cldrconverter/CLDRConverter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1289,25 +1289,58 @@ private static Map coverageLevelsMap() throws Exception {
*/
private static void generateTZDBShortNamesMap() throws IOException {
Files.walk(Path.of(tzDataDir), 1, FileVisitOption.FOLLOW_LINKS)
- .filter(p -> p.toFile().isFile())
+ .filter(p -> p.toFile().isFile() && !p.endsWith("jdk11_backward"))
.forEach(p -> {
try {
String zone = null;
String rule = null;
String format = null;
+ boolean inVanguard = false;
+ boolean inRearguard = false;
for (var line : Files.readAllLines(p)) {
- if (line.contains("#STDOFF")) continue;
+ // Interpret the line in rearguard mode so that STD/DST
+ // correctly handles negative DST cases, such as "GMT/IST"
+ // vs. "IST/GMT" case for Europe/Dublin
+ if (inVanguard) {
+ if (line.startsWith("# Rearguard")) {
+ inVanguard = false;
+ inRearguard = true;
+ }
+ continue;
+ } else if (line.startsWith("# Vanguard")) {
+ inVanguard = true;
+ continue;
+ }
+ if (inRearguard) {
+ if (line.startsWith("# End of rearguard")) {
+ inRearguard = false;
+ continue;
+ } else {
+ if (line.startsWith("#\t")) {
+ line = line.substring(1); // omit #
+ }
+ }
+ }
+ if (line.isBlank() || line.matches("^[ \t]*#.*")) {
+ // ignore blank/comment lines
+ continue;
+ }
+ // remove comments in-line
line = line.replaceAll("[ \t]*#.*", "");
// Zone line
if (line.startsWith("Zone")) {
+ if (zone != null) {
+ tzdbShortNamesMap.put(zone, format + NBSP + rule);
+ }
var zl = line.split("[ \t]+", -1);
zone = zl[1];
rule = zl[3];
format = zl[4];
} else {
if (zone != null) {
- if (line.isBlank()) {
+ if (line.startsWith("Rule") ||
+ line.startsWith("Link")) {
tzdbShortNamesMap.put(zone, format + NBSP + rule);
zone = null;
rule = null;
diff --git a/make/modules/java.instrument/Lib.gmk b/make/modules/java.instrument/Lib.gmk
index ae985b3158fcf..942462266446d 100644
--- a/make/modules/java.instrument/Lib.gmk
+++ b/make/modules/java.instrument/Lib.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -47,7 +47,7 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBINSTRUMENT, \
LDFLAGS_macosx := -L$(call FindLibDirForModule, java.base), \
LDFLAGS_aix := -L$(SUPPORT_OUTPUTDIR)/native/java.base, \
LIBS := $(JDKLIB_LIBS), \
- LIBS_unix := -ljava -ljvm $(LIBZ_LIBS), \
+ LIBS_unix := $(LIBZ_LIBS), \
LIBS_linux := -ljli $(LIBDL), \
LIBS_aix := -liconv -ljli_static $(LIBDL), \
LIBS_macosx := -ljli -liconv -framework Cocoa -framework Security \
diff --git a/src/demo/share/jfc/J2Ddemo/java2d/Intro.java b/src/demo/share/jfc/J2Ddemo/java2d/Intro.java
index 046768e3a6a4b..a4fd2e5b75374 100644
--- a/src/demo/share/jfc/J2Ddemo/java2d/Intro.java
+++ b/src/demo/share/jfc/J2Ddemo/java2d/Intro.java
@@ -1,6 +1,6 @@
/*
*
- * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -1716,7 +1716,7 @@ public Contributors(int beg, int end, Surface surf) {
this.beginning = beg;
this.ending = end;
fm = surf.getMetrics(font);
- java.util.Arrays.sort(members);
+ Arrays.sort(members);
cast.add("CONTRIBUTORS");
cast.add(" ");
cast.addAll(Arrays.asList(members));
diff --git a/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp b/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp
index 2293d70c8dacd..63f6c9491c8de 100644
--- a/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp
+++ b/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp
@@ -42,8 +42,12 @@ const bool CCallingConventionRequiresIntsAsLongs = false;
// and Operational Models for ARMv8"
#define CPU_MULTI_COPY_ATOMIC
+// The expected size in bytes of a cache line.
#define DEFAULT_CACHE_LINE_SIZE 64
+// The default padding size for data structures to avoid false sharing.
+#define DEFAULT_PADDING_SIZE DEFAULT_CACHE_LINE_SIZE
+
// According to the ARMv8 ARM, "Concurrent modification and execution
// of instructions can lead to the resulting instruction performing
// any behavior that can be achieved by executing any sequence of
diff --git a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp
index c7b45ff0dde17..8694734c751c6 100644
--- a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp
+++ b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp
@@ -310,7 +310,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
uint int_args = 0;
uint fp_args = 0;
- uint stk_args = 0; // inc by 2 each time
+ uint stk_args = 0;
for (int i = 0; i < total_args_passed; i++) {
switch (sig_bt[i]) {
@@ -322,8 +322,9 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
if (int_args < Argument::n_int_register_parameters_j) {
regs[i].set1(INT_ArgReg[int_args++]->as_VMReg());
} else {
+ stk_args = align_up(stk_args, 2);
regs[i].set1(VMRegImpl::stack2reg(stk_args));
- stk_args += 2;
+ stk_args += 1;
}
break;
case T_VOID:
@@ -340,6 +341,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
if (int_args < Argument::n_int_register_parameters_j) {
regs[i].set2(INT_ArgReg[int_args++]->as_VMReg());
} else {
+ stk_args = align_up(stk_args, 2);
regs[i].set2(VMRegImpl::stack2reg(stk_args));
stk_args += 2;
}
@@ -348,8 +350,9 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
if (fp_args < Argument::n_float_register_parameters_j) {
regs[i].set1(FP_ArgReg[fp_args++]->as_VMReg());
} else {
+ stk_args = align_up(stk_args, 2);
regs[i].set1(VMRegImpl::stack2reg(stk_args));
- stk_args += 2;
+ stk_args += 1;
}
break;
case T_DOUBLE:
@@ -357,6 +360,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
if (fp_args < Argument::n_float_register_parameters_j) {
regs[i].set2(FP_ArgReg[fp_args++]->as_VMReg());
} else {
+ stk_args = align_up(stk_args, 2);
regs[i].set2(VMRegImpl::stack2reg(stk_args));
stk_args += 2;
}
@@ -367,7 +371,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
}
}
- return align_up(stk_args, 2);
+ return stk_args;
}
// Patch the callers callsite with entry to compiled code if it exists.
diff --git a/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp b/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp
index 6fc6be7a5b34c..1a567049a4654 100644
--- a/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp
+++ b/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp
@@ -3603,11 +3603,9 @@ void TemplateTable::_new() {
// get InstanceKlass
__ load_resolved_klass_at_offset(r4, r3, r4, rscratch1);
- // make sure klass is initialized & doesn't have finalizer
- // make sure klass is fully initialized
- __ ldrb(rscratch1, Address(r4, InstanceKlass::init_state_offset()));
- __ cmp(rscratch1, (u1)InstanceKlass::fully_initialized);
- __ br(Assembler::NE, slow_case);
+ // make sure klass is initialized
+ assert(VM_Version::supports_fast_class_init_checks(), "Optimization requires support for fast class initialization checks");
+ __ clinit_barrier(r4, rscratch1, nullptr /*L_fast_path*/, &slow_case);
// get instance_size in InstanceKlass (scaled to a count of bytes)
__ ldrw(r3,
diff --git a/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp b/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp
index 8b67a207cf93c..4b2e5cc5a4ddd 100644
--- a/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp
+++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp
@@ -165,6 +165,7 @@ enum Ampere_CPU_Model {
static int dcache_line_size() { return _dcache_line_size; }
static int get_initial_sve_vector_length() { return _initial_sve_vector_length; };
+ // Aarch64 supports fast class initialization checks
static bool supports_fast_class_init_checks() { return true; }
constexpr static bool supports_stack_watermark_barrier() { return true; }
diff --git a/src/hotspot/cpu/arm/globalDefinitions_arm.hpp b/src/hotspot/cpu/arm/globalDefinitions_arm.hpp
index 2041cf9e17ead..5b68dbc9dbd8b 100644
--- a/src/hotspot/cpu/arm/globalDefinitions_arm.hpp
+++ b/src/hotspot/cpu/arm/globalDefinitions_arm.hpp
@@ -49,8 +49,12 @@ const bool HaveVFP = true;
// arm32 is not specified as multi-copy-atomic
// So we must not #define CPU_MULTI_COPY_ATOMIC
+// The expected size in bytes of a cache line.
#define DEFAULT_CACHE_LINE_SIZE 64
+// The default padding size for data structures to avoid false sharing.
+#define DEFAULT_PADDING_SIZE DEFAULT_CACHE_LINE_SIZE
+
#define STUBROUTINES_MD_HPP "stubRoutines_arm.hpp"
#define INTERP_MASM_MD_HPP "interp_masm_arm.hpp"
#define TEMPLATETABLE_MD_HPP "templateTable_arm.hpp"
diff --git a/src/hotspot/cpu/arm/sharedRuntime_arm.cpp b/src/hotspot/cpu/arm/sharedRuntime_arm.cpp
index 9a65f9f09fe17..716c7b7575e9c 100644
--- a/src/hotspot/cpu/arm/sharedRuntime_arm.cpp
+++ b/src/hotspot/cpu/arm/sharedRuntime_arm.cpp
@@ -441,7 +441,6 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
}
}
- if (slot & 1) slot++;
return slot;
}
diff --git a/src/hotspot/cpu/ppc/globalDefinitions_ppc.hpp b/src/hotspot/cpu/ppc/globalDefinitions_ppc.hpp
index bced453d784cf..30670d053fa6e 100644
--- a/src/hotspot/cpu/ppc/globalDefinitions_ppc.hpp
+++ b/src/hotspot/cpu/ppc/globalDefinitions_ppc.hpp
@@ -48,9 +48,12 @@ const bool CCallingConventionRequiresIntsAsLongs = true;
// PPC64 is not specified as multi-copy-atomic
// So we must not #define CPU_MULTI_COPY_ATOMIC
-// The expected size in bytes of a cache line, used to pad data structures.
+// The expected size in bytes of a cache line.
#define DEFAULT_CACHE_LINE_SIZE 128
+// The default padding size for data structures to avoid false sharing.
+#define DEFAULT_PADDING_SIZE DEFAULT_CACHE_LINE_SIZE
+
#define SUPPORT_RESERVED_STACK_AREA
// If UseSIGTRAP is active, we only use the poll bit and no polling page.
diff --git a/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp b/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp
index 824996168a95b..3382df355da79 100644
--- a/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp
+++ b/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp
@@ -734,7 +734,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
ShouldNotReachHere();
}
}
- return align_up(stk, 2);
+ return stk;
}
#if defined(COMPILER1) || defined(COMPILER2)
diff --git a/src/hotspot/cpu/ppc/vm_version_ppc.hpp b/src/hotspot/cpu/ppc/vm_version_ppc.hpp
index b1168ded45678..a5831ef1590ad 100644
--- a/src/hotspot/cpu/ppc/vm_version_ppc.hpp
+++ b/src/hotspot/cpu/ppc/vm_version_ppc.hpp
@@ -91,7 +91,7 @@ class VM_Version: public Abstract_VM_Version {
// Override Abstract_VM_Version implementation
static void print_platform_virtualization_info(outputStream*);
- // PPC64 supports fast class initialization checks for static methods.
+ // PPC64 supports fast class initialization checks
static bool supports_fast_class_init_checks() { return true; }
constexpr static bool supports_stack_watermark_barrier() { return true; }
diff --git a/src/hotspot/cpu/riscv/assembler_riscv.hpp b/src/hotspot/cpu/riscv/assembler_riscv.hpp
index 3ea70429f21f0..e92b3b521d00a 100644
--- a/src/hotspot/cpu/riscv/assembler_riscv.hpp
+++ b/src/hotspot/cpu/riscv/assembler_riscv.hpp
@@ -3184,6 +3184,17 @@ enum Nf {
return uabs(target - branch) < branch_range;
}
+ // Decode the given instruction, checking if it's a 16-bit compressed
+ // instruction and return the address of the next instruction.
+ static address locate_next_instruction(address inst) {
+ // Instruction wider than 16 bits has the two least-significant bits set.
+ if ((0x3 & *inst) == 0x3) {
+ return inst + instruction_size;
+ } else {
+ return inst + compressed_instruction_size;
+ }
+ }
+
Assembler(CodeBuffer* code) : AbstractAssembler(code), _in_compressible_region(true) {}
};
diff --git a/src/hotspot/cpu/riscv/globalDefinitions_riscv.hpp b/src/hotspot/cpu/riscv/globalDefinitions_riscv.hpp
index f40ffbeefa748..e368bbdc9141f 100644
--- a/src/hotspot/cpu/riscv/globalDefinitions_riscv.hpp
+++ b/src/hotspot/cpu/riscv/globalDefinitions_riscv.hpp
@@ -50,6 +50,10 @@ const bool CCallingConventionRequiresIntsAsLongs = false;
#define USE_POINTERS_TO_REGISTER_IMPL_ARRAY
+// The expected size in bytes of a cache line.
#define DEFAULT_CACHE_LINE_SIZE 64
+// The default padding size for data structures to avoid false sharing.
+#define DEFAULT_PADDING_SIZE DEFAULT_CACHE_LINE_SIZE
+
#endif // CPU_RISCV_GLOBALDEFINITIONS_RISCV_HPP
diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp
index 5f5a04cc01f06..5008a0c08c219 100644
--- a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp
+++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp
@@ -4481,6 +4481,57 @@ void MacroAssembler::zero_dcache_blocks(Register base, Register cnt, Register tm
bge(cnt, tmp1, loop);
}
+// java.lang.Math.round(float a)
+// Returns the closest int to the argument, with ties rounding to positive infinity.
+void MacroAssembler::java_round_float(Register dst, FloatRegister src, FloatRegister ftmp) {
+ // this instructions calling sequence provides performance improvement on all tested devices;
+ // don't change it without re-verification
+ Label done;
+ mv(t0, jint_cast(0.5f));
+ fmv_w_x(ftmp, t0);
+
+ // dst = 0 if NaN
+ feq_s(t0, src, src); // replacing fclass with feq as performance optimization
+ mv(dst, zr);
+ beqz(t0, done);
+
+ // dst = (src + 0.5f) rounded down towards negative infinity
+ // Adding 0.5f to some floats exceeds the precision limits for a float and rounding takes place.
+ // RDN is required for fadd_s, RNE gives incorrect results:
+ // --------------------------------------------------------------------
+ // fadd.s rne (src + 0.5f): src = 8388609.000000 ftmp = 8388610.000000
+ // fcvt.w.s rdn: ftmp = 8388610.000000 dst = 8388610
+ // --------------------------------------------------------------------
+ // fadd.s rdn (src + 0.5f): src = 8388609.000000 ftmp = 8388609.000000
+ // fcvt.w.s rdn: ftmp = 8388609.000000 dst = 8388609
+ // --------------------------------------------------------------------
+ fadd_s(ftmp, src, ftmp, RoundingMode::rdn);
+ fcvt_w_s(dst, ftmp, RoundingMode::rdn);
+
+ bind(done);
+}
+
+// java.lang.Math.round(double a)
+// Returns the closest long to the argument, with ties rounding to positive infinity.
+void MacroAssembler::java_round_double(Register dst, FloatRegister src, FloatRegister ftmp) {
+ // this instructions calling sequence provides performance improvement on all tested devices;
+ // don't change it without re-verification
+ Label done;
+ mv(t0, julong_cast(0.5));
+ fmv_d_x(ftmp, t0);
+
+ // dst = 0 if NaN
+ feq_d(t0, src, src); // replacing fclass with feq as performance optimization
+ mv(dst, zr);
+ beqz(t0, done);
+
+ // dst = (src + 0.5) rounded down towards negative infinity
+ fadd_d(ftmp, src, ftmp, RoundingMode::rdn); // RDN is required here otherwise some inputs produce incorrect results
+ fcvt_l_d(dst, ftmp, RoundingMode::rdn);
+
+ bind(done);
+}
+
#define FCVT_SAFE(FLOATCVT, FLOATSIG) \
void MacroAssembler::FLOATCVT##_safe(Register dst, FloatRegister src, Register tmp) { \
Label done; \
diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp
index 62efb92b7117e..3e5be3886a428 100644
--- a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp
+++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp
@@ -1279,6 +1279,9 @@ class MacroAssembler: public Assembler {
void fcvt_w_d_safe(Register dst, FloatRegister src, Register tmp = t0);
void fcvt_l_d_safe(Register dst, FloatRegister src, Register tmp = t0);
+ void java_round_float(Register dst, FloatRegister src, FloatRegister ftmp);
+ void java_round_double(Register dst, FloatRegister src, FloatRegister ftmp);
+
// vector load/store unit-stride instructions
void vlex_v(VectorRegister vd, Register base, Assembler::SEW sew, VectorMask vm = unmasked) {
switch (sew) {
diff --git a/src/hotspot/cpu/riscv/riscv.ad b/src/hotspot/cpu/riscv/riscv.ad
index 5af25b26a16ad..d5a95b2e3ba5b 100644
--- a/src/hotspot/cpu/riscv/riscv.ad
+++ b/src/hotspot/cpu/riscv/riscv.ad
@@ -8417,6 +8417,34 @@ instruct convN2I(iRegINoSp dst, iRegN src)
ins_pipe(ialu_reg);
%}
+instruct round_double_reg(iRegLNoSp dst, fRegD src, fRegD ftmp) %{
+ match(Set dst (RoundD src));
+
+ ins_cost(XFER_COST + BRANCH_COST);
+ effect(TEMP ftmp);
+ format %{ "java_round_double $dst, $src\t#@round_double_reg" %}
+
+ ins_encode %{
+ __ java_round_double($dst$$Register, as_FloatRegister($src$$reg), as_FloatRegister($ftmp$$reg));
+ %}
+
+ ins_pipe(pipe_slow);
+%}
+
+instruct round_float_reg(iRegINoSp dst, fRegF src, fRegF ftmp) %{
+ match(Set dst (RoundF src));
+
+ ins_cost(XFER_COST + BRANCH_COST);
+ effect(TEMP ftmp);
+ format %{ "java_round_float $dst, $src\t#@round_float_reg" %}
+
+ ins_encode %{
+ __ java_round_float($dst$$Register, as_FloatRegister($src$$reg), as_FloatRegister($ftmp$$reg));
+ %}
+
+ ins_pipe(pipe_slow);
+%}
+
// Convert oop pointer into compressed form
instruct encodeHeapOop(iRegNNoSp dst, iRegP src) %{
match(Set dst (EncodeP src));
diff --git a/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp b/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp
index f960c78edb9f4..01fe307bc27c3 100644
--- a/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp
+++ b/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp
@@ -266,7 +266,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
uint int_args = 0;
uint fp_args = 0;
- uint stk_args = 0; // inc by 2 each time
+ uint stk_args = 0;
for (int i = 0; i < total_args_passed; i++) {
switch (sig_bt[i]) {
@@ -278,8 +278,9 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
if (int_args < Argument::n_int_register_parameters_j) {
regs[i].set1(INT_ArgReg[int_args++]->as_VMReg());
} else {
+ stk_args = align_up(stk_args, 2);
regs[i].set1(VMRegImpl::stack2reg(stk_args));
- stk_args += 2;
+ stk_args += 1;
}
break;
case T_VOID:
@@ -295,6 +296,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
if (int_args < Argument::n_int_register_parameters_j) {
regs[i].set2(INT_ArgReg[int_args++]->as_VMReg());
} else {
+ stk_args = align_up(stk_args, 2);
regs[i].set2(VMRegImpl::stack2reg(stk_args));
stk_args += 2;
}
@@ -303,8 +305,9 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
if (fp_args < Argument::n_float_register_parameters_j) {
regs[i].set1(FP_ArgReg[fp_args++]->as_VMReg());
} else {
+ stk_args = align_up(stk_args, 2);
regs[i].set1(VMRegImpl::stack2reg(stk_args));
- stk_args += 2;
+ stk_args += 1;
}
break;
case T_DOUBLE:
@@ -312,6 +315,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
if (fp_args < Argument::n_float_register_parameters_j) {
regs[i].set2(FP_ArgReg[fp_args++]->as_VMReg());
} else {
+ stk_args = align_up(stk_args, 2);
regs[i].set2(VMRegImpl::stack2reg(stk_args));
stk_args += 2;
}
@@ -321,7 +325,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
}
}
- return align_up(stk_args, 2);
+ return stk_args;
}
// Patch the callers callsite with entry to compiled code if it exists.
diff --git a/src/hotspot/cpu/riscv/vm_version_riscv.hpp b/src/hotspot/cpu/riscv/vm_version_riscv.hpp
index 921847337306c..1ea853284ff15 100644
--- a/src/hotspot/cpu/riscv/vm_version_riscv.hpp
+++ b/src/hotspot/cpu/riscv/vm_version_riscv.hpp
@@ -215,6 +215,9 @@ class VM_Version : public Abstract_VM_Version {
constexpr static bool supports_stack_watermark_barrier() { return true; }
static bool supports_on_spin_wait() { return UseZihintpause; }
+
+ // RISCV64 supports fast class initialization checks
+ static bool supports_fast_class_init_checks() { return true; }
};
#endif // CPU_RISCV_VM_VERSION_RISCV_HPP
diff --git a/src/hotspot/cpu/s390/globalDefinitions_s390.hpp b/src/hotspot/cpu/s390/globalDefinitions_s390.hpp
index 39baf5bf0478e..236d4c5bf69f1 100644
--- a/src/hotspot/cpu/s390/globalDefinitions_s390.hpp
+++ b/src/hotspot/cpu/s390/globalDefinitions_s390.hpp
@@ -48,6 +48,9 @@ const bool CCallingConventionRequiresIntsAsLongs = true;
// The expected size in bytes of a cache line, used to pad data structures.
#define DEFAULT_CACHE_LINE_SIZE 256
+// The default padding size for data structures to avoid false sharing.
+#define DEFAULT_PADDING_SIZE DEFAULT_CACHE_LINE_SIZE
+
#define SUPPORT_RESERVED_STACK_AREA
#endif // CPU_S390_GLOBALDEFINITIONS_S390_HPP
diff --git a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp
index 4798f35f19d05..ed1795cfa339f 100644
--- a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp
+++ b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp
@@ -755,7 +755,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
ShouldNotReachHere();
}
}
- return align_up(stk, 2);
+ return stk;
}
int SharedRuntime::c_calling_convention(const BasicType *sig_bt,
diff --git a/src/hotspot/cpu/s390/vm_version_s390.hpp b/src/hotspot/cpu/s390/vm_version_s390.hpp
index d72e2712a40dc..93d5b11c473d1 100644
--- a/src/hotspot/cpu/s390/vm_version_s390.hpp
+++ b/src/hotspot/cpu/s390/vm_version_s390.hpp
@@ -410,7 +410,7 @@ class VM_Version: public Abstract_VM_Version {
// Override Abstract_VM_Version implementation
static void print_platform_virtualization_info(outputStream*);
- // s390 supports fast class initialization checks for static methods.
+ // s390 supports fast class initialization checks
static bool supports_fast_class_init_checks() { return true; }
// CPU feature query functions
diff --git a/src/hotspot/cpu/x86/assembler_x86.cpp b/src/hotspot/cpu/x86/assembler_x86.cpp
index c262df21e4547..63d6ec9b00f1b 100644
--- a/src/hotspot/cpu/x86/assembler_x86.cpp
+++ b/src/hotspot/cpu/x86/assembler_x86.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -889,8 +889,8 @@ address Assembler::locate_operand(address inst, WhichOperand which) {
assert(which == imm_operand || which == disp32_operand,
"which %d is_64_bit %d ip " INTPTR_FORMAT, which, is_64bit, p2i(ip));
#else
- assert((which == call32_operand || which == imm_operand) && is_64bit ||
- which == narrow_oop_operand && !is_64bit,
+ assert(((which == call32_operand || which == imm_operand) && is_64bit) ||
+ (which == narrow_oop_operand && !is_64bit),
"which %d is_64_bit %d ip " INTPTR_FORMAT, which, is_64bit, p2i(ip));
#endif // _LP64
return ip;
@@ -7235,7 +7235,7 @@ void Assembler::vxorps(XMMRegister dst, XMMRegister nds, Address src, int vector
// Integer vector arithmetic
void Assembler::vphaddw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
- assert(VM_Version::supports_avx() && (vector_len == 0) ||
+ assert((VM_Version::supports_avx() && (vector_len == 0)) ||
VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ true);
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
@@ -7243,7 +7243,7 @@ void Assembler::vphaddw(XMMRegister dst, XMMRegister nds, XMMRegister src, int v
}
void Assembler::vphaddd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
- assert(VM_Version::supports_avx() && (vector_len == 0) ||
+ assert((VM_Version::supports_avx() && (vector_len == 0)) ||
VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ true);
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
diff --git a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp
index 54e5f55fa2b00..42f675f83c355 100644
--- a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp
+++ b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -5223,8 +5223,8 @@ void C2_MacroAssembler::vector_mask_operation(int opc, Register dst, KRegister m
void C2_MacroAssembler::vector_mask_operation(int opc, Register dst, XMMRegister mask, XMMRegister xtmp,
Register tmp, int masklen, BasicType bt, int vec_enc) {
- assert(vec_enc == AVX_128bit && VM_Version::supports_avx() ||
- vec_enc == AVX_256bit && (VM_Version::supports_avx2() || type2aelembytes(bt) >= 4), "");
+ assert((vec_enc == AVX_128bit && VM_Version::supports_avx()) ||
+ (vec_enc == AVX_256bit && (VM_Version::supports_avx2() || type2aelembytes(bt) >= 4)), "");
assert(VM_Version::supports_popcnt(), "");
bool need_clip = false;
diff --git a/src/hotspot/cpu/x86/frame_x86.inline.hpp b/src/hotspot/cpu/x86/frame_x86.inline.hpp
index 67e5a1e0c43fe..70008e1011779 100644
--- a/src/hotspot/cpu/x86/frame_x86.inline.hpp
+++ b/src/hotspot/cpu/x86/frame_x86.inline.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -181,7 +181,7 @@ inline bool frame::equal(frame other) const {
&& unextended_sp() == other.unextended_sp()
&& fp() == other.fp()
&& pc() == other.pc();
- assert(!ret || ret && cb() == other.cb() && _deopt_state == other._deopt_state, "inconsistent construction");
+ assert(!ret || (ret && cb() == other.cb() && _deopt_state == other._deopt_state), "inconsistent construction");
return ret;
}
diff --git a/src/hotspot/cpu/x86/globalDefinitions_x86.hpp b/src/hotspot/cpu/x86/globalDefinitions_x86.hpp
index 7eff43471b5dd..2e82453b38002 100644
--- a/src/hotspot/cpu/x86/globalDefinitions_x86.hpp
+++ b/src/hotspot/cpu/x86/globalDefinitions_x86.hpp
@@ -38,29 +38,18 @@ const bool CCallingConventionRequiresIntsAsLongs = false;
#define CPU_MULTI_COPY_ATOMIC
-// The expected size in bytes of a cache line, used to pad data structures.
-#if COMPILER1_AND_COMPILER2
- #ifdef _LP64
- // tiered, 64-bit, large machine
- #define DEFAULT_CACHE_LINE_SIZE 128
- #define OM_CACHE_LINE_SIZE 64
- #else
- // tiered, 32-bit, medium machine
- #define DEFAULT_CACHE_LINE_SIZE 64
- #endif
-#elif defined(COMPILER1)
- // pure C1, 32-bit, small machine
- // i486 was the last Intel chip with 16-byte cache line size
- #define DEFAULT_CACHE_LINE_SIZE 32
-#elif defined(COMPILER2)
- #ifdef _LP64
- // pure C2, 64-bit, large machine
- #define DEFAULT_CACHE_LINE_SIZE 128
- #define OM_CACHE_LINE_SIZE 64
- #else
- // pure C2, 32-bit, medium machine
- #define DEFAULT_CACHE_LINE_SIZE 64
- #endif
+// The expected size in bytes of a cache line.
+#define DEFAULT_CACHE_LINE_SIZE 64
+
+// The default padding size for data structures to avoid false sharing.
+#ifdef _LP64
+// The common wisdom is that adjacent cache line prefetchers on some hardware
+// may pull two cache lines on access, so we have to pessimistically assume twice
+// the cache line size for padding. TODO: Check if this is still true for modern
+// hardware. If not, DEFAULT_CACHE_LINE_SIZE might as well suffice.
+#define DEFAULT_PADDING_SIZE (DEFAULT_CACHE_LINE_SIZE*2)
+#else
+#define DEFAULT_PADDING_SIZE DEFAULT_CACHE_LINE_SIZE
#endif
#if defined(COMPILER2)
diff --git a/src/hotspot/cpu/x86/macroAssembler_x86.hpp b/src/hotspot/cpu/x86/macroAssembler_x86.hpp
index ea6a37d16edba..b474944c4bead 100644
--- a/src/hotspot/cpu/x86/macroAssembler_x86.hpp
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.hpp
@@ -111,8 +111,8 @@ class MacroAssembler: public Assembler {
op == 0xE9 /* jmp */ ||
op == 0xEB /* short jmp */ ||
(op & 0xF0) == 0x70 /* short jcc */ ||
- op == 0x0F && (branch[1] & 0xF0) == 0x80 /* jcc */ ||
- op == 0xC7 && branch[1] == 0xF8 /* xbegin */,
+ (op == 0x0F && (branch[1] & 0xF0) == 0x80) /* jcc */ ||
+ (op == 0xC7 && branch[1] == 0xF8) /* xbegin */,
"Invalid opcode at patch point");
if (op == 0xEB || (op & 0xF0) == 0x70) {
diff --git a/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp b/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp
index 3ae539bac8d05..571160523cbe4 100644
--- a/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp
+++ b/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp
@@ -528,8 +528,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
}
}
- // return value can be odd number of VMRegImpl stack slots make multiple of 2
- return align_up(stack, 2);
+ return stack;
}
// Patch the callers callsite with entry to compiled code if it exists.
diff --git a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp
index bf15dab070369..faa423bcf8e76 100644
--- a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp
+++ b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp
@@ -498,7 +498,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
uint int_args = 0;
uint fp_args = 0;
- uint stk_args = 0; // inc by 2 each time
+ uint stk_args = 0;
for (int i = 0; i < total_args_passed; i++) {
switch (sig_bt[i]) {
@@ -510,8 +510,9 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
if (int_args < Argument::n_int_register_parameters_j) {
regs[i].set1(INT_ArgReg[int_args++]->as_VMReg());
} else {
+ stk_args = align_up(stk_args, 2);
regs[i].set1(VMRegImpl::stack2reg(stk_args));
- stk_args += 2;
+ stk_args += 1;
}
break;
case T_VOID:
@@ -528,6 +529,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
if (int_args < Argument::n_int_register_parameters_j) {
regs[i].set2(INT_ArgReg[int_args++]->as_VMReg());
} else {
+ stk_args = align_up(stk_args, 2);
regs[i].set2(VMRegImpl::stack2reg(stk_args));
stk_args += 2;
}
@@ -536,8 +538,9 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
if (fp_args < Argument::n_float_register_parameters_j) {
regs[i].set1(FP_ArgReg[fp_args++]->as_VMReg());
} else {
+ stk_args = align_up(stk_args, 2);
regs[i].set1(VMRegImpl::stack2reg(stk_args));
- stk_args += 2;
+ stk_args += 1;
}
break;
case T_DOUBLE:
@@ -545,6 +548,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
if (fp_args < Argument::n_float_register_parameters_j) {
regs[i].set2(FP_ArgReg[fp_args++]->as_VMReg());
} else {
+ stk_args = align_up(stk_args, 2);
regs[i].set2(VMRegImpl::stack2reg(stk_args));
stk_args += 2;
}
@@ -555,7 +559,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
}
}
- return align_up(stk_args, 2);
+ return stk_args;
}
// Patch the callers callsite with entry to compiled code if it exists.
diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp
index 85f3bbf61094c..cad9e6475c610 100644
--- a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp
+++ b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -2318,7 +2318,7 @@ address StubGenerator::generate_base64_decodeBlock() {
const Register isURL = c_rarg5;// Base64 or URL character set
__ movl(isMIME, Address(rbp, 2 * wordSize));
#else
- const Address dp_mem(rbp, 6 * wordSize); // length is on stack on Win64
+ const Address dp_mem(rbp, 6 * wordSize); // length is on stack on Win64
const Address isURL_mem(rbp, 7 * wordSize);
const Register isURL = r10; // pick the volatile windows register
const Register dp = r12;
@@ -2540,10 +2540,12 @@ address StubGenerator::generate_base64_decodeBlock() {
// output_size in r13
// Strip pad characters, if any, and adjust length and mask
+ __ addq(length, start_offset);
__ cmpb(Address(source, length, Address::times_1, -1), '=');
__ jcc(Assembler::equal, L_padding);
__ BIND(L_donePadding);
+ __ subq(length, start_offset);
// Output size is (64 - output_size), output mask is (all 1s >> output_size).
__ kmovql(input_mask, rax);
diff --git a/src/hotspot/cpu/x86/templateTable_x86.cpp b/src/hotspot/cpu/x86/templateTable_x86.cpp
index b17fc43032c3d..f53a7872451a4 100644
--- a/src/hotspot/cpu/x86/templateTable_x86.cpp
+++ b/src/hotspot/cpu/x86/templateTable_x86.cpp
@@ -4048,11 +4048,16 @@ void TemplateTable::_new() {
__ load_resolved_klass_at_index(rcx, rcx, rdx);
__ push(rcx); // save the contexts of klass for initializing the header
- // make sure klass is initialized & doesn't have finalizer
- // make sure klass is fully initialized
+ // make sure klass is initialized
+#ifdef _LP64
+ assert(VM_Version::supports_fast_class_init_checks(), "must support fast class initialization checks");
+ __ clinit_barrier(rcx, r15_thread, nullptr /*L_fast_path*/, &slow_case);
+#else
__ cmpb(Address(rcx, InstanceKlass::init_state_offset()), InstanceKlass::fully_initialized);
__ jcc(Assembler::notEqual, slow_case);
+#endif
+ // make sure klass doesn't have finalizer
// get instance_size in InstanceKlass (scaled to a count of bytes)
__ movl(rdx, Address(rcx, Klass::layout_helper_offset()));
// test to see if it has a finalizer or is malformed in some way
diff --git a/src/hotspot/cpu/x86/vm_version_x86.cpp b/src/hotspot/cpu/x86/vm_version_x86.cpp
index ac937bef04e7c..df1ea6edd300f 100644
--- a/src/hotspot/cpu/x86/vm_version_x86.cpp
+++ b/src/hotspot/cpu/x86/vm_version_x86.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1178,7 +1178,7 @@ void VM_Version::get_processor_features() {
UseMD5Intrinsics = true;
}
- if (supports_sha() LP64_ONLY(|| supports_avx2() && supports_bmi2())) {
+ if (supports_sha() LP64_ONLY(|| (supports_avx2() && supports_bmi2()))) {
if (FLAG_IS_DEFAULT(UseSHA)) {
UseSHA = true;
}
diff --git a/src/hotspot/cpu/x86/vm_version_x86.hpp b/src/hotspot/cpu/x86/vm_version_x86.hpp
index 454a8f312553a..e521a6ee3bc0e 100644
--- a/src/hotspot/cpu/x86/vm_version_x86.hpp
+++ b/src/hotspot/cpu/x86/vm_version_x86.hpp
@@ -756,7 +756,7 @@ class VM_Version : public Abstract_VM_Version {
// the intrinsic for java.lang.Thread.onSpinWait()
static bool supports_on_spin_wait() { return supports_sse2(); }
- // x86_64 supports fast class initialization checks for static methods.
+ // x86_64 supports fast class initialization checks
static bool supports_fast_class_init_checks() {
return LP64_ONLY(true) NOT_LP64(false); // not implemented on x86_32
}
diff --git a/src/hotspot/cpu/x86/x86.ad b/src/hotspot/cpu/x86/x86.ad
index 9db209fe48bc3..8d656c136aa89 100644
--- a/src/hotspot/cpu/x86/x86.ad
+++ b/src/hotspot/cpu/x86/x86.ad
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
//
// This code is free software; you can redistribute it and/or modify it
@@ -2532,8 +2532,8 @@ static inline Assembler::ComparisonPredicateFP booltest_pred_to_comparison_pred_
static void vec_mov_helper(CodeBuffer *cbuf, int src_lo, int dst_lo,
int src_hi, int dst_hi, uint ireg, outputStream* st) {
assert(ireg == Op_VecS || // 32bit vector
- (src_lo & 1) == 0 && (src_lo + 1) == src_hi &&
- (dst_lo & 1) == 0 && (dst_lo + 1) == dst_hi,
+ ((src_lo & 1) == 0 && (src_lo + 1) == src_hi &&
+ (dst_lo & 1) == 0 && (dst_lo + 1) == dst_hi),
"no non-adjacent vector moves" );
if (cbuf) {
C2_MacroAssembler _masm(cbuf);
diff --git a/src/hotspot/cpu/x86/x86_32.ad b/src/hotspot/cpu/x86/x86_32.ad
index 07b3cb35a388d..45cc785a5394d 100644
--- a/src/hotspot/cpu/x86/x86_32.ad
+++ b/src/hotspot/cpu/x86/x86_32.ad
@@ -11142,7 +11142,7 @@ instruct convI2FPR_mem(regFPR dst, memory mem) %{
// Convert an int to a float in xmm; no rounding step needed.
instruct convI2F_reg(regF dst, rRegI src) %{
- predicate( UseSSE==1 || UseSSE>=2 && !UseXmmI2F );
+ predicate( UseSSE==1 || ( UseSSE>=2 && !UseXmmI2F ));
match(Set dst (ConvI2F src));
format %{ "CVTSI2SS $dst, $src" %}
ins_encode %{
diff --git a/src/hotspot/cpu/zero/globalDefinitions_zero.hpp b/src/hotspot/cpu/zero/globalDefinitions_zero.hpp
index 810f7de3cb3f6..0f78b3eeefba2 100644
--- a/src/hotspot/cpu/zero/globalDefinitions_zero.hpp
+++ b/src/hotspot/cpu/zero/globalDefinitions_zero.hpp
@@ -30,8 +30,12 @@
#define SUPPORTS_NATIVE_CX8
#endif
+// The expected size in bytes of a cache line.
#define DEFAULT_CACHE_LINE_SIZE 64
+// The default padding size for data structures to avoid false sharing.
+#define DEFAULT_PADDING_SIZE DEFAULT_CACHE_LINE_SIZE
+
#define SUPPORT_MONITOR_COUNT
#include
diff --git a/src/hotspot/os/aix/os_aix.cpp b/src/hotspot/os/aix/os_aix.cpp
index 54c538cf367ed..c75828c0c22f9 100644
--- a/src/hotspot/os/aix/os_aix.cpp
+++ b/src/hotspot/os/aix/os_aix.cpp
@@ -2112,11 +2112,6 @@ bool os::can_commit_large_page_memory() {
return false;
}
-bool os::can_execute_large_page_memory() {
- // Does not matter, we do not support huge pages.
- return false;
-}
-
char* os::pd_attempt_map_memory_to_file_at(char* requested_addr, size_t bytes, int file_desc) {
assert(file_desc >= 0, "file_desc is not valid");
char* result = nullptr;
diff --git a/src/hotspot/os/bsd/os_bsd.cpp b/src/hotspot/os/bsd/os_bsd.cpp
index 18f3cd2b38d49..2f7f31157e89e 100644
--- a/src/hotspot/os/bsd/os_bsd.cpp
+++ b/src/hotspot/os/bsd/os_bsd.cpp
@@ -979,7 +979,7 @@ bool os::dll_address_to_library_name(address addr, char* buf,
// in case of error it checks if .dll/.so was built for the
// same architecture as Hotspot is running on
-void *os::Bsd::dlopen_helper(const char *filename, int mode) {
+void *os::Bsd::dlopen_helper(const char *filename, int mode, char *ebuf, int ebuflen) {
#ifndef IA32
bool ieee_handling = IEEE_subnormal_handling_OK();
if (!ieee_handling) {
@@ -1005,27 +1005,44 @@ void *os::Bsd::dlopen_helper(const char *filename, int mode) {
assert(rtn == 0, "fegetenv must succeed");
#endif // IA32
- void * result= ::dlopen(filename, RTLD_LAZY);
-
+ void* result;
+ JFR_ONLY(NativeLibraryLoadEvent load_event(filename, &result);)
+ result = ::dlopen(filename, RTLD_LAZY);
+ if (result == nullptr) {
+ const char* error_report = ::dlerror();
+ if (error_report == nullptr) {
+ error_report = "dlerror returned no error description";
+ }
+ if (ebuf != nullptr && ebuflen > 0) {
+ ::strncpy(ebuf, error_report, ebuflen-1);
+ ebuf[ebuflen-1]='\0';
+ }
+ Events::log_dll_message(nullptr, "Loading shared library %s failed, %s", filename, error_report);
+ log_info(os)("shared library load of %s failed, %s", filename, error_report);
+ JFR_ONLY(load_event.set_error_msg(error_report);)
+ } else {
+ Events::log_dll_message(nullptr, "Loaded shared library %s", filename);
+ log_info(os)("shared library load of %s was successful", filename);
#ifndef IA32
- if (result != nullptr && ! IEEE_subnormal_handling_OK()) {
- // We just dlopen()ed a library that mangled the floating-point
- // flags. Silently fix things now.
- int rtn = fesetenv(&default_fenv);
- assert(rtn == 0, "fesetenv must succeed");
- bool ieee_handling_after_issue = IEEE_subnormal_handling_OK();
-
- if (ieee_handling_after_issue) {
- Events::log_dll_message(nullptr, "IEEE subnormal handling had to be corrected after loading %s", filename);
- log_info(os)("IEEE subnormal handling had to be corrected after loading %s", filename);
- } else {
- Events::log_dll_message(nullptr, "IEEE subnormal handling could not be corrected after loading %s", filename);
- log_info(os)("IEEE subnormal handling could not be corrected after loading %s", filename);
+ if (! IEEE_subnormal_handling_OK()) {
+ // We just dlopen()ed a library that mangled the floating-point
+ // flags. Silently fix things now.
+ JFR_ONLY(load_event.set_fp_env_correction_attempt(true);)
+ int rtn = fesetenv(&default_fenv);
+ assert(rtn == 0, "fesetenv must succeed");
+
+ if (IEEE_subnormal_handling_OK()) {
+ Events::log_dll_message(nullptr, "IEEE subnormal handling had to be corrected after loading %s", filename);
+ log_info(os)("IEEE subnormal handling had to be corrected after loading %s", filename);
+ JFR_ONLY(load_event.set_fp_env_correction_success(true);)
+ } else {
+ Events::log_dll_message(nullptr, "IEEE subnormal handling could not be corrected after loading %s", filename);
+ log_info(os)("IEEE subnormal handling could not be corrected after loading %s", filename);
+ assert(false, "fesetenv didn't work");
+ }
}
-
- assert(ieee_handling_after_issue, "fesetenv didn't work");
- }
#endif // IA32
+ }
return result;
}
@@ -1037,30 +1054,7 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) {
#else
log_info(os)("attempting shared library load of %s", filename);
- void* result;
- JFR_ONLY(NativeLibraryLoadEvent load_event(filename, &result);)
- result = os::Bsd::dlopen_helper(filename, RTLD_LAZY);
- if (result != nullptr) {
- Events::log_dll_message(nullptr, "Loaded shared library %s", filename);
- // Successful loading
- log_info(os)("shared library load of %s was successful", filename);
- return result;
- }
-
- const char* error_report = ::dlerror();
- if (error_report == nullptr) {
- error_report = "dlerror returned no error description";
- }
- if (ebuf != nullptr && ebuflen > 0) {
- // Read system error message into ebuf
- ::strncpy(ebuf, error_report, ebuflen-1);
- ebuf[ebuflen-1]='\0';
- }
- Events::log_dll_message(nullptr, "Loading shared library %s failed, %s", filename, error_report);
- log_info(os)("shared library load of %s failed, %s", filename, error_report);
- JFR_ONLY(load_event.set_error_msg(error_report);)
-
- return nullptr;
+ return os::Bsd::dlopen_helper(filename, RTLD_LAZY, ebuf, ebuflen);
#endif // STATIC_BUILD
}
#else
@@ -1071,29 +1065,13 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) {
log_info(os)("attempting shared library load of %s", filename);
void* result;
- JFR_ONLY(NativeLibraryLoadEvent load_event(filename, &result);)
- result = os::Bsd::dlopen_helper(filename, RTLD_LAZY);
+ result = os::Bsd::dlopen_helper(filename, RTLD_LAZY, ebuf, ebuflen);
if (result != nullptr) {
- Events::log_dll_message(nullptr, "Loaded shared library %s", filename);
- // Successful loading
- log_info(os)("shared library load of %s was successful", filename);
return result;
}
- Elf32_Ehdr elf_head;
-
- const char* const error_report = ::dlerror();
- if (error_report == nullptr) {
- error_report = "dlerror returned no error description";
- }
- if (ebuf != nullptr && ebuflen > 0) {
- // Read system error message into ebuf
- ::strncpy(ebuf, error_report, ebuflen-1);
- ebuf[ebuflen-1]='\0';
- }
Events::log_dll_message(nullptr, "Loading shared library %s failed, %s", filename, error_report);
log_info(os)("shared library load of %s failed, %s", filename, error_report);
- JFR_ONLY(load_event.set_error_msg(error_report);)
int diag_msg_max_length=ebuflen-strlen(ebuf);
char* diag_msg_buf=ebuf+strlen(ebuf);
@@ -1102,7 +1080,6 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) {
return nullptr;
}
-
int file_descriptor= ::open(filename, O_RDONLY | O_NONBLOCK);
if (file_descriptor < 0) {
@@ -1110,6 +1087,7 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) {
return nullptr;
}
+ Elf32_Ehdr elf_head;
bool failed_to_read_elf_head=
(sizeof(elf_head)!=
(::read(file_descriptor, &elf_head,sizeof(elf_head))));
@@ -1809,11 +1787,6 @@ bool os::can_commit_large_page_memory() {
return false;
}
-bool os::can_execute_large_page_memory() {
- // Does not matter, we do not support huge pages.
- return false;
-}
-
char* os::pd_attempt_map_memory_to_file_at(char* requested_addr, size_t bytes, int file_desc) {
assert(file_desc >= 0, "file_desc is not valid");
char* result = pd_attempt_reserve_memory_at(requested_addr, bytes, !ExecMem);
diff --git a/src/hotspot/os/bsd/os_bsd.hpp b/src/hotspot/os/bsd/os_bsd.hpp
index f79212bc43c0f..72de9ca597195 100644
--- a/src/hotspot/os/bsd/os_bsd.hpp
+++ b/src/hotspot/os/bsd/os_bsd.hpp
@@ -70,7 +70,7 @@ class os::Bsd {
// Real-time clock functions
static void clock_init(void);
- static void *dlopen_helper(const char *path, int mode);
+ static void *dlopen_helper(const char *path, int mode, char *ebuf, int ebuflen);
// Stack repair handling
diff --git a/src/hotspot/os/linux/os_linux.cpp b/src/hotspot/os/linux/os_linux.cpp
index e94e366acc741..5117ccac84bb1 100644
--- a/src/hotspot/os/linux/os_linux.cpp
+++ b/src/hotspot/os/linux/os_linux.cpp
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2015, 2022 SAP SE. All rights reserved.
+ * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2024 SAP SE. 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
@@ -1856,18 +1856,19 @@ void * os::Linux::dlopen_helper(const char *filename, char *ebuf, int ebuflen) {
if (! IEEE_subnormal_handling_OK()) {
// We just dlopen()ed a library that mangled the floating-point flags.
// Attempt to fix things now.
+ JFR_ONLY(load_event.set_fp_env_correction_attempt(true);)
int rtn = fesetenv(&default_fenv);
assert(rtn == 0, "fesetenv must succeed");
- bool ieee_handling_after_issue = IEEE_subnormal_handling_OK();
- if (ieee_handling_after_issue) {
+ if (IEEE_subnormal_handling_OK()) {
Events::log_dll_message(nullptr, "IEEE subnormal handling had to be corrected after loading %s", filename);
log_info(os)("IEEE subnormal handling had to be corrected after loading %s", filename);
+ JFR_ONLY(load_event.set_fp_env_correction_success(true);)
} else {
Events::log_dll_message(nullptr, "IEEE subnormal handling could not be corrected after loading %s", filename);
log_info(os)("IEEE subnormal handling could not be corrected after loading %s", filename);
+ assert(false, "fesetenv didn't work");
}
- assert(ieee_handling_after_issue, "fesetenv didn't work");
}
#endif // IA32
}
@@ -2096,7 +2097,6 @@ const char* distro_files[] = {
"/etc/mandrake-release",
"/etc/sun-release",
"/etc/redhat-release",
- "/etc/SuSE-release",
"/etc/lsb-release",
"/etc/turbolinux-release",
"/etc/gentoo-release",
@@ -2104,6 +2104,7 @@ const char* distro_files[] = {
"/etc/angstrom-version",
"/etc/system-release",
"/etc/os-release",
+ "/etc/SuSE-release", // Deprecated in favor of os-release since SuSE 12
nullptr };
void os::Linux::print_distro_info(outputStream* st) {
@@ -4077,10 +4078,6 @@ bool os::can_commit_large_page_memory() {
return UseTransparentHugePages;
}
-bool os::can_execute_large_page_memory() {
- return UseTransparentHugePages;
-}
-
char* os::pd_attempt_map_memory_to_file_at(char* requested_addr, size_t bytes, int file_desc) {
assert(file_desc >= 0, "file_desc is not valid");
char* result = pd_attempt_reserve_memory_at(requested_addr, bytes, !ExecMem);
diff --git a/src/hotspot/os/windows/os_windows.cpp b/src/hotspot/os/windows/os_windows.cpp
index 223bc0bd13514..1b5c7850bf23f 100644
--- a/src/hotspot/os/windows/os_windows.cpp
+++ b/src/hotspot/os/windows/os_windows.cpp
@@ -3436,10 +3436,6 @@ bool os::can_commit_large_page_memory() {
return false;
}
-bool os::can_execute_large_page_memory() {
- return true;
-}
-
static char* reserve_large_pages_individually(size_t size, char* req_addr, bool exec) {
log_debug(pagesize)("Reserving large pages individually.");
diff --git a/src/hotspot/os_cpu/linux_riscv/os_linux_riscv.cpp b/src/hotspot/os_cpu/linux_riscv/os_linux_riscv.cpp
index 8b9d1178ca567..282467bc9e096 100644
--- a/src/hotspot/os_cpu/linux_riscv/os_linux_riscv.cpp
+++ b/src/hotspot/os_cpu/linux_riscv/os_linux_riscv.cpp
@@ -232,7 +232,7 @@ bool PosixSignals::pd_hotspot_signal_handler(int sig, siginfo_t* info,
CompiledMethod* nm = (cb != nullptr) ? cb->as_compiled_method_or_null() : nullptr;
bool is_unsafe_arraycopy = (thread->doing_unsafe_access() && UnsafeCopyMemory::contains_pc(pc));
if ((nm != nullptr && nm->has_unsafe_access()) || is_unsafe_arraycopy) {
- address next_pc = pc + NativeCall::instruction_size;
+ address next_pc = Assembler::locate_next_instruction(pc);
if (is_unsafe_arraycopy) {
next_pc = UnsafeCopyMemory::page_error_continue_pc(pc);
}
@@ -271,7 +271,7 @@ bool PosixSignals::pd_hotspot_signal_handler(int sig, siginfo_t* info,
thread->thread_state() == _thread_in_native) &&
sig == SIGBUS && /* info->si_code == BUS_OBJERR && */
thread->doing_unsafe_access()) {
- address next_pc = pc + NativeCall::instruction_size;
+ address next_pc = Assembler::locate_next_instruction(pc);
if (UnsafeCopyMemory::contains_pc(pc)) {
next_pc = UnsafeCopyMemory::page_error_continue_pc(pc);
}
diff --git a/src/hotspot/share/c1/c1_Compilation.cpp b/src/hotspot/share/c1/c1_Compilation.cpp
index 74fd825a07ab5..53fb5fbcf9efe 100644
--- a/src/hotspot/share/c1/c1_Compilation.cpp
+++ b/src/hotspot/share/c1/c1_Compilation.cpp
@@ -76,7 +76,6 @@ static const char * timer_name[] = {
};
static elapsedTimer timers[max_phase_timers];
-static uint totalInstructionNodes = 0;
class PhaseTraceTime: public TraceTime {
private:
@@ -494,7 +493,6 @@ void Compilation::compile_method() {
if (log() != nullptr) // Print code cache state into compiler log
log()->code_cache_state();
- totalInstructionNodes += Instruction::number_of_instructions();
}
diff --git a/src/hotspot/share/c1/c1_FrameMap.cpp b/src/hotspot/share/c1/c1_FrameMap.cpp
index c55e41f458398..ace4fe8209db3 100644
--- a/src/hotspot/share/c1/c1_FrameMap.cpp
+++ b/src/hotspot/share/c1/c1_FrameMap.cpp
@@ -72,7 +72,7 @@ CallingConvention* FrameMap::java_calling_convention(const BasicTypeArray* signa
}
}
- intptr_t out_preserve = SharedRuntime::java_calling_convention(sig_bt, regs, sizeargs);
+ intptr_t out_preserve = align_up(SharedRuntime::java_calling_convention(sig_bt, regs, sizeargs), 2);
LIR_OprList* args = new LIR_OprList(signature->length());
for (i = 0; i < sizeargs;) {
BasicType t = sig_bt[i];
diff --git a/src/hotspot/share/c1/c1_GraphBuilder.cpp b/src/hotspot/share/c1/c1_GraphBuilder.cpp
index edf6f29478c4d..fb2aa28ec86a3 100644
--- a/src/hotspot/share/c1/c1_GraphBuilder.cpp
+++ b/src/hotspot/share/c1/c1_GraphBuilder.cpp
@@ -4468,7 +4468,9 @@ void GraphBuilder::append_unsafe_get_and_set(ciMethod* callee, bool is_add) {
#ifndef PRODUCT
void GraphBuilder::print_stats() {
- vmap()->print();
+ if (UseLocalValueNumbering) {
+ vmap()->print();
+ }
}
#endif // PRODUCT
diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp
index d65c8b2b79ee6..2553b508e1fe3 100644
--- a/src/hotspot/share/classfile/javaClasses.cpp
+++ b/src/hotspot/share/classfile/javaClasses.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1343,7 +1343,7 @@ const char* java_lang_Class::as_external_name(oop java_class) {
Klass* java_lang_Class::array_klass_acquire(oop java_class) {
Klass* k = ((Klass*)java_class->metadata_field_acquire(_array_klass_offset));
- assert(k == nullptr || k->is_klass() && k->is_array_klass(), "should be array klass");
+ assert(k == nullptr || (k->is_klass() && k->is_array_klass()), "should be array klass");
return k;
}
diff --git a/src/hotspot/share/classfile/stringTable.hpp b/src/hotspot/share/classfile/stringTable.hpp
index 8178e3b3bb7c3..02723a42f420b 100644
--- a/src/hotspot/share/classfile/stringTable.hpp
+++ b/src/hotspot/share/classfile/stringTable.hpp
@@ -25,7 +25,7 @@
#ifndef SHARE_CLASSFILE_STRINGTABLE_HPP
#define SHARE_CLASSFILE_STRINGTABLE_HPP
-#include "memory/allocation.hpp"
+#include "memory/allStatic.hpp"
#include "memory/padded.hpp"
#include "oops/oop.hpp"
#include "oops/oopHandle.hpp"
@@ -37,15 +37,11 @@ class DumpedInternedStrings;
class JavaThread;
class SerializeClosure;
-class StringTable;
class StringTableConfig;
-class StringTableCreateEntry;
-class StringTable : public CHeapObj{
+class StringTable : AllStatic {
friend class VMStructs;
- friend class Symbol;
friend class StringTableConfig;
- friend class StringTableCreateEntry;
static volatile bool _has_work;
diff --git a/src/hotspot/share/code/codeCache.cpp b/src/hotspot/share/code/codeCache.cpp
index 8018604af60bf..bf8c1d84e71a0 100644
--- a/src/hotspot/share/code/codeCache.cpp
+++ b/src/hotspot/share/code/codeCache.cpp
@@ -355,16 +355,8 @@ void CodeCache::initialize_heaps() {
}
size_t CodeCache::page_size(bool aligned, size_t min_pages) {
- if (os::can_execute_large_page_memory()) {
- if (InitialCodeCacheSize < ReservedCodeCacheSize) {
- // Make sure that the page size allows for an incremental commit of the reserved space
- min_pages = MAX2(min_pages, (size_t)8);
- }
- return aligned ? os::page_size_for_region_aligned(ReservedCodeCacheSize, min_pages) :
- os::page_size_for_region_unaligned(ReservedCodeCacheSize, min_pages);
- } else {
- return os::vm_page_size();
- }
+ return aligned ? os::page_size_for_region_aligned(ReservedCodeCacheSize, min_pages) :
+ os::page_size_for_region_unaligned(ReservedCodeCacheSize, min_pages);
}
ReservedCodeSpace CodeCache::reserve_heap_memory(size_t size, size_t rs_ps) {
@@ -1171,7 +1163,11 @@ void CodeCache::initialize() {
FLAG_SET_ERGO(NonNMethodCodeHeapSize, (uintx)os::vm_page_size());
FLAG_SET_ERGO(ProfiledCodeHeapSize, 0);
FLAG_SET_ERGO(NonProfiledCodeHeapSize, 0);
- ReservedCodeSpace rs = reserve_heap_memory(ReservedCodeCacheSize, page_size(false, 8));
+
+ // If InitialCodeCacheSize is equal to ReservedCodeCacheSize, then it's more likely
+ // users want to use the largest available page.
+ const size_t min_pages = (InitialCodeCacheSize == ReservedCodeCacheSize) ? 1 : 8;
+ ReservedCodeSpace rs = reserve_heap_memory(ReservedCodeCacheSize, page_size(false, min_pages));
// Register CodeHeaps with LSan as we sometimes embed pointers to malloc memory.
LSAN_REGISTER_ROOT_REGION(rs.base(), rs.size());
add_heap(rs, "CodeCache", CodeBlobType::All);
diff --git a/src/hotspot/share/code/nmethod.cpp b/src/hotspot/share/code/nmethod.cpp
index 54a017818fe13..cb185446cccb2 100644
--- a/src/hotspot/share/code/nmethod.cpp
+++ b/src/hotspot/share/code/nmethod.cpp
@@ -3019,7 +3019,7 @@ void nmethod::print_nmethod_labels(outputStream* stream, address block_begin, bo
assert(sig_index == sizeargs, "");
}
const char* spname = "sp"; // make arch-specific?
- intptr_t out_preserve = SharedRuntime::java_calling_convention(sig_bt, regs, sizeargs);
+ SharedRuntime::java_calling_convention(sig_bt, regs, sizeargs);
int stack_slot_offset = this->frame_size() * wordSize;
int tab1 = 14, tab2 = 24;
int sig_index = 0;
diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp b/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp
index efc6584bda048..a4315ec5f6c48 100644
--- a/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp
+++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp
@@ -167,9 +167,9 @@ class G1CMMarkStack {
size_t _num_buckets;
bool _should_grow;
TaskQueueEntryChunk* volatile* _buckets;
- char _pad0[DEFAULT_CACHE_LINE_SIZE];
+ char _pad0[DEFAULT_PADDING_SIZE];
volatile size_t _size;
- char _pad4[DEFAULT_CACHE_LINE_SIZE - sizeof(size_t)];
+ char _pad4[DEFAULT_PADDING_SIZE - sizeof(size_t)];
size_t bucket_size(size_t bucket) {
return (bucket == 0) ?
@@ -232,12 +232,12 @@ class G1CMMarkStack {
ChunkAllocator _chunk_allocator;
- char _pad0[DEFAULT_CACHE_LINE_SIZE];
+ char _pad0[DEFAULT_PADDING_SIZE];
TaskQueueEntryChunk* volatile _free_list; // Linked list of free chunks that can be allocated by users.
- char _pad1[DEFAULT_CACHE_LINE_SIZE - sizeof(TaskQueueEntryChunk*)];
+ char _pad1[DEFAULT_PADDING_SIZE - sizeof(TaskQueueEntryChunk*)];
TaskQueueEntryChunk* volatile _chunk_list; // List of chunks currently containing data.
volatile size_t _chunks_in_chunk_list;
- char _pad2[DEFAULT_CACHE_LINE_SIZE - sizeof(TaskQueueEntryChunk*) - sizeof(size_t)];
+ char _pad2[DEFAULT_PADDING_SIZE - sizeof(TaskQueueEntryChunk*) - sizeof(size_t)];
// Atomically add the given chunk to the list.
void add_chunk_to_list(TaskQueueEntryChunk* volatile* list, TaskQueueEntryChunk* elem);
diff --git a/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp b/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp
index b05dd34009a6d..b2ac4b25e9065 100644
--- a/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp
+++ b/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp
@@ -58,56 +58,46 @@ G1ConcurrentRefineThread* G1ConcurrentRefineThreadControl::create_refinement_thr
return result;
}
-G1ConcurrentRefineThreadControl::G1ConcurrentRefineThreadControl() :
+G1ConcurrentRefineThreadControl::G1ConcurrentRefineThreadControl(uint max_num_threads) :
_cr(nullptr),
- _threads(nullptr),
- _max_num_threads(0)
+ _threads(max_num_threads)
{}
G1ConcurrentRefineThreadControl::~G1ConcurrentRefineThreadControl() {
- if (_threads != nullptr) {
- for (uint i = 0; i < _max_num_threads; i++) {
- G1ConcurrentRefineThread* t = _threads[i];
- if (t == nullptr) {
-#ifdef ASSERT
- for (uint j = i + 1; j < _max_num_threads; ++j) {
- assert(_threads[j] == nullptr, "invariant");
- }
-#endif // ASSERT
- break;
- } else {
- delete t;
- }
+ while (_threads.is_nonempty()) {
+ delete _threads.pop();
+ }
+}
+
+bool G1ConcurrentRefineThreadControl::ensure_threads_created(uint worker_id, bool initializing) {
+ assert(worker_id < max_num_threads(), "precondition");
+
+ while ((uint)_threads.length() <= worker_id) {
+ G1ConcurrentRefineThread* rt = create_refinement_thread(_threads.length(), initializing);
+ if (rt == nullptr) {
+ return false;
}
- FREE_C_HEAP_ARRAY(G1ConcurrentRefineThread*, _threads);
+ _threads.push(rt);
}
+
+ return true;
}
-jint G1ConcurrentRefineThreadControl::initialize(G1ConcurrentRefine* cr, uint max_num_threads) {
+jint G1ConcurrentRefineThreadControl::initialize(G1ConcurrentRefine* cr) {
assert(cr != nullptr, "G1ConcurrentRefine must not be null");
_cr = cr;
- _max_num_threads = max_num_threads;
- if (max_num_threads > 0) {
- _threads = NEW_C_HEAP_ARRAY(G1ConcurrentRefineThread*, max_num_threads, mtGC);
-
- _threads[0] = create_refinement_thread(0, true);
- if (_threads[0] == nullptr) {
+ if (max_num_threads() > 0) {
+ _threads.push(create_refinement_thread(0, true));
+ if (_threads.at(0) == nullptr) {
vm_shutdown_during_initialization("Could not allocate primary refinement thread");
return JNI_ENOMEM;
}
- if (UseDynamicNumberOfGCThreads) {
- for (uint i = 1; i < max_num_threads; ++i) {
- _threads[i] = nullptr;
- }
- } else {
- for (uint i = 1; i < max_num_threads; ++i) {
- _threads[i] = create_refinement_thread(i, true);
- if (_threads[i] == nullptr) {
- vm_shutdown_during_initialization("Could not allocate refinement threads.");
- return JNI_ENOMEM;
- }
+ if (!UseDynamicNumberOfGCThreads) {
+ if (!ensure_threads_created(max_num_threads() - 1, true)) {
+ vm_shutdown_during_initialization("Could not allocate refinement threads");
+ return JNI_ENOMEM;
}
}
}
@@ -117,38 +107,28 @@ jint G1ConcurrentRefineThreadControl::initialize(G1ConcurrentRefine* cr, uint ma
#ifdef ASSERT
void G1ConcurrentRefineThreadControl::assert_current_thread_is_primary_refinement_thread() const {
- assert(_threads != nullptr, "No threads");
- assert(Thread::current() == _threads[0], "Not primary thread");
+ assert(Thread::current() == _threads.at(0), "Not primary thread");
}
#endif // ASSERT
bool G1ConcurrentRefineThreadControl::activate(uint worker_id) {
- assert(worker_id < _max_num_threads, "precondition");
- G1ConcurrentRefineThread* thread_to_activate = _threads[worker_id];
- if (thread_to_activate == nullptr) {
- thread_to_activate = create_refinement_thread(worker_id, false);
- if (thread_to_activate == nullptr) {
- return false;
- }
- _threads[worker_id] = thread_to_activate;
+ if (ensure_threads_created(worker_id, false)) {
+ _threads.at(worker_id)->activate();
+ return true;
}
- thread_to_activate->activate();
- return true;
+
+ return false;
}
void G1ConcurrentRefineThreadControl::worker_threads_do(ThreadClosure* tc) {
- for (uint i = 0; i < _max_num_threads; i++) {
- if (_threads[i] != nullptr) {
- tc->do_thread(_threads[i]);
- }
+ for (G1ConcurrentRefineThread* t : _threads) {
+ tc->do_thread(t);
}
}
void G1ConcurrentRefineThreadControl::stop() {
- for (uint i = 0; i < _max_num_threads; i++) {
- if (_threads[i] != nullptr) {
- _threads[i]->stop();
- }
+ for (G1ConcurrentRefineThread* t : _threads) {
+ t->stop();
}
}
@@ -170,12 +150,12 @@ G1ConcurrentRefine::G1ConcurrentRefine(G1Policy* policy) :
_last_adjust(),
_needs_adjust(false),
_threads_needed(policy, adjust_threads_period_ms()),
- _thread_control(),
+ _thread_control(G1ConcRefinementThreads),
_dcqs(G1BarrierSet::dirty_card_queue_set())
{}
jint G1ConcurrentRefine::initialize() {
- return _thread_control.initialize(this, G1ConcRefinementThreads);
+ return _thread_control.initialize(this);
}
G1ConcurrentRefine* G1ConcurrentRefine::create(G1Policy* policy, jint* ecode) {
diff --git a/src/hotspot/share/gc/g1/g1ConcurrentRefine.hpp b/src/hotspot/share/gc/g1/g1ConcurrentRefine.hpp
index 4cb66d5d625f4..dd0b62a22ea8c 100644
--- a/src/hotspot/share/gc/g1/g1ConcurrentRefine.hpp
+++ b/src/hotspot/share/gc/g1/g1ConcurrentRefine.hpp
@@ -30,6 +30,7 @@
#include "memory/allocation.hpp"
#include "utilities/debug.hpp"
#include "utilities/globalDefinitions.hpp"
+#include "utilities/growableArray.hpp"
#include "utilities/macros.hpp"
// Forward decl
@@ -43,24 +44,25 @@ class ThreadClosure;
// iterate over them.
class G1ConcurrentRefineThreadControl {
G1ConcurrentRefine* _cr;
- G1ConcurrentRefineThread** _threads;
- uint _max_num_threads;
+ GrowableArrayCHeap _threads;
// Create the refinement thread for the given worker id.
// If initializing is true, ignore InjectGCWorkerCreationFailure.
G1ConcurrentRefineThread* create_refinement_thread(uint worker_id, bool initializing);
+ bool ensure_threads_created(uint worker_id, bool initializing);
+
NONCOPYABLE(G1ConcurrentRefineThreadControl);
public:
- G1ConcurrentRefineThreadControl();
+ G1ConcurrentRefineThreadControl(uint max_num_threads);
~G1ConcurrentRefineThreadControl();
- jint initialize(G1ConcurrentRefine* cr, uint max_num_threads);
+ jint initialize(G1ConcurrentRefine* cr);
void assert_current_thread_is_primary_refinement_thread() const NOT_DEBUG_RETURN;
- uint max_num_threads() const { return _max_num_threads; }
+ uint max_num_threads() const { return _threads.capacity(); }
// Activate the indicated thread. If the thread has not yet been allocated,
// allocate and then activate. If allocation is needed and fails, return
diff --git a/src/hotspot/share/gc/g1/g1DirtyCardQueue.hpp b/src/hotspot/share/gc/g1/g1DirtyCardQueue.hpp
index bf25e3828d11f..1dd3a9afacee8 100644
--- a/src/hotspot/share/gc/g1/g1DirtyCardQueue.hpp
+++ b/src/hotspot/share/gc/g1/g1DirtyCardQueue.hpp
@@ -135,7 +135,7 @@ class G1DirtyCardQueueSet: public PtrQueueSet {
// and install the next list, and meanwhile there can be a thread dealing
// with the previous list.
PausedList* volatile _plist;
- DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, sizeof(PausedList*));
+ DEFINE_PAD_MINUS_SIZE(1, DEFAULT_PADDING_SIZE, sizeof(PausedList*));
NONCOPYABLE(PausedBuffers);
@@ -157,19 +157,19 @@ class G1DirtyCardQueueSet: public PtrQueueSet {
HeadTail take_all();
};
- DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE, 0);
+ DEFINE_PAD_MINUS_SIZE(0, DEFAULT_PADDING_SIZE, 0);
// Upper bound on the number of cards in the completed and paused buffers.
volatile size_t _num_cards;
- DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, sizeof(size_t));
+ DEFINE_PAD_MINUS_SIZE(1, DEFAULT_PADDING_SIZE, sizeof(size_t));
// If the queue contains more cards than configured here, the
// mutator must start doing some of the concurrent refinement work.
volatile size_t _mutator_refinement_threshold;
- DEFINE_PAD_MINUS_SIZE(2, DEFAULT_CACHE_LINE_SIZE, sizeof(size_t));
+ DEFINE_PAD_MINUS_SIZE(2, DEFAULT_PADDING_SIZE, sizeof(size_t));
// Buffers ready for refinement.
// NonblockingQueue has inner padding of one cache line.
NonblockingQueue _completed;
// Add a trailer padding after NonblockingQueue.
- DEFINE_PAD_MINUS_SIZE(3, DEFAULT_CACHE_LINE_SIZE, sizeof(BufferNode*));
+ DEFINE_PAD_MINUS_SIZE(3, DEFAULT_PADDING_SIZE, sizeof(BufferNode*));
// Buffers for which refinement is temporarily paused.
// PausedBuffers has inner padding, including trailer.
PausedBuffers _paused;
diff --git a/src/hotspot/share/gc/g1/g1MonotonicArena.hpp b/src/hotspot/share/gc/g1/g1MonotonicArena.hpp
index 8a6bb88e008ca..586766a8c8f97 100644
--- a/src/hotspot/share/gc/g1/g1MonotonicArena.hpp
+++ b/src/hotspot/share/gc/g1/g1MonotonicArena.hpp
@@ -125,7 +125,7 @@ class G1MonotonicArena::Segment {
char* _bottom; // Actual data.
// Do not add class member variables beyond this point
- static size_t header_size() { return align_up(sizeof(Segment), DEFAULT_CACHE_LINE_SIZE); }
+ static size_t header_size() { return align_up(sizeof(Segment), DEFAULT_PADDING_SIZE); }
static size_t payload_size(uint slot_size, uint num_slots) {
// The cast (size_t) is required to guard against overflow wrap around.
diff --git a/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp b/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp
index 8d7ee0b1dfdd0..92aec50def6f2 100644
--- a/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp
+++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp
@@ -95,7 +95,7 @@ G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h,
// entries, since entry 0 keeps track of surviving bytes for non-young regions.
// We also add a few elements at the beginning and at the end in
// an attempt to eliminate cache contention
- const size_t padding_elem_num = (DEFAULT_CACHE_LINE_SIZE / sizeof(size_t));
+ const size_t padding_elem_num = (DEFAULT_PADDING_SIZE / sizeof(size_t));
size_t array_length = padding_elem_num + _surviving_words_length + padding_elem_num;
_surviving_young_words_base = NEW_C_HEAP_ARRAY(size_t, array_length, mtGC);
diff --git a/src/hotspot/share/gc/g1/g1RedirtyCardsQueue.hpp b/src/hotspot/share/gc/g1/g1RedirtyCardsQueue.hpp
index f270e31f77266..970cce1623ec6 100644
--- a/src/hotspot/share/gc/g1/g1RedirtyCardsQueue.hpp
+++ b/src/hotspot/share/gc/g1/g1RedirtyCardsQueue.hpp
@@ -66,11 +66,11 @@ class G1RedirtyCardsLocalQueueSet : private PtrQueueSet {
// collected (and processed) buffers reverts back to collecting, allowing
// the set to be reused for another round of redirtying.
class G1RedirtyCardsQueueSet : public PtrQueueSet {
- DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, 0);
+ DEFINE_PAD_MINUS_SIZE(1, DEFAULT_PADDING_SIZE, 0);
BufferNode::Stack _list;
- DEFINE_PAD_MINUS_SIZE(2, DEFAULT_CACHE_LINE_SIZE, sizeof(size_t));
+ DEFINE_PAD_MINUS_SIZE(2, DEFAULT_PADDING_SIZE, sizeof(size_t));
volatile size_t _entry_count;
- DEFINE_PAD_MINUS_SIZE(3, DEFAULT_CACHE_LINE_SIZE, sizeof(BufferNode*));
+ DEFINE_PAD_MINUS_SIZE(3, DEFAULT_PADDING_SIZE, sizeof(BufferNode*));
BufferNode* _tail;
DEBUG_ONLY(mutable bool _collecting;)
diff --git a/src/hotspot/share/gc/parallel/gcAdaptivePolicyCounters.hpp b/src/hotspot/share/gc/parallel/gcAdaptivePolicyCounters.hpp
index 57b48d49f9516..e83813c78f48f 100644
--- a/src/hotspot/share/gc/parallel/gcAdaptivePolicyCounters.hpp
+++ b/src/hotspot/share/gc/parallel/gcAdaptivePolicyCounters.hpp
@@ -60,7 +60,6 @@ class GCAdaptivePolicyCounters : public GCPolicyCounters {
PerfVariable* _decrease_for_footprint_counter;
PerfVariable* _minor_pause_young_slope_counter;
- PerfVariable* _major_pause_old_slope_counter;
PerfVariable* _decide_at_full_gc_counter;
diff --git a/src/hotspot/share/gc/parallel/mutableNUMASpace.hpp b/src/hotspot/share/gc/parallel/mutableNUMASpace.hpp
index 77ecb4da46671..18271fabd050d 100644
--- a/src/hotspot/share/gc/parallel/mutableNUMASpace.hpp
+++ b/src/hotspot/share/gc/parallel/mutableNUMASpace.hpp
@@ -184,8 +184,6 @@ class MutableNUMASpace : public MutableSpace {
virtual size_t used_in_words() const;
virtual size_t free_in_words() const;
- using MutableSpace::capacity_in_words;
-
virtual size_t tlab_capacity(Thread* thr) const;
virtual size_t tlab_used(Thread* thr) const;
virtual size_t unsafe_max_tlab_alloc(Thread* thr) const;
diff --git a/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.cpp b/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.cpp
index 0eb16b4dbc3ff..be6d9a501b575 100644
--- a/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.cpp
+++ b/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.cpp
@@ -280,7 +280,7 @@ void PSAdaptiveSizePolicy::compute_eden_space_size(
//
// Make changes only to affect one of the pauses (the larger)
// at a time.
- adjust_eden_for_pause_time(&desired_promo_size, &desired_eden_size);
+ adjust_eden_for_pause_time(&desired_eden_size);
} else if (_avg_minor_pause->padded_average() > gc_minor_pause_goal_sec()) {
// Adjust only for the minor pause time goal
@@ -455,7 +455,7 @@ void PSAdaptiveSizePolicy::compute_old_gen_free_space(
// at a time.
if (is_full_gc) {
set_decide_at_full_gc(decide_at_full_gc_true);
- adjust_promo_for_pause_time(&desired_promo_size, &desired_eden_size);
+ adjust_promo_for_pause_time(&desired_promo_size);
}
} else if (adjusted_mutator_cost() < _throughput_goal) {
// This branch used to require that (mutator_cost() > 0.0 in 1.4.2.
@@ -592,8 +592,7 @@ void PSAdaptiveSizePolicy::adjust_eden_for_minor_pause_time(size_t* desired_eden
}
}
-void PSAdaptiveSizePolicy::adjust_promo_for_pause_time(size_t* desired_promo_size_ptr,
- size_t* desired_eden_size_ptr) {
+void PSAdaptiveSizePolicy::adjust_promo_for_pause_time(size_t* desired_promo_size_ptr) {
size_t promo_heap_delta = 0;
// Add some checks for a threshold for a change. For example,
@@ -627,8 +626,7 @@ void PSAdaptiveSizePolicy::adjust_promo_for_pause_time(size_t* desired_promo_siz
*desired_promo_size_ptr, promo_heap_delta);
}
-void PSAdaptiveSizePolicy::adjust_eden_for_pause_time(size_t* desired_promo_size_ptr,
- size_t* desired_eden_size_ptr) {
+void PSAdaptiveSizePolicy::adjust_eden_for_pause_time(size_t* desired_eden_size_ptr) {
size_t eden_heap_delta = 0;
// Add some checks for a threshold for a change. For example,
@@ -875,17 +873,6 @@ size_t PSAdaptiveSizePolicy::scale_down(size_t change,
return reduced_change;
}
-size_t PSAdaptiveSizePolicy::eden_increment(size_t cur_eden,
- uint percent_change) {
- size_t eden_heap_delta;
- eden_heap_delta = cur_eden / 100 * percent_change;
- return eden_heap_delta;
-}
-
-size_t PSAdaptiveSizePolicy::eden_increment(size_t cur_eden) {
- return eden_increment(cur_eden, YoungGenerationSizeIncrement);
-}
-
size_t PSAdaptiveSizePolicy::eden_increment_with_supplement_aligned_up(
size_t cur_eden) {
size_t result = eden_increment(cur_eden,
@@ -898,23 +885,6 @@ size_t PSAdaptiveSizePolicy::eden_decrement_aligned_down(size_t cur_eden) {
return align_down(eden_heap_delta, _space_alignment);
}
-size_t PSAdaptiveSizePolicy::eden_decrement(size_t cur_eden) {
- size_t eden_heap_delta = eden_increment(cur_eden) /
- AdaptiveSizeDecrementScaleFactor;
- return eden_heap_delta;
-}
-
-size_t PSAdaptiveSizePolicy::promo_increment(size_t cur_promo,
- uint percent_change) {
- size_t promo_heap_delta;
- promo_heap_delta = cur_promo / 100 * percent_change;
- return promo_heap_delta;
-}
-
-size_t PSAdaptiveSizePolicy::promo_increment(size_t cur_promo) {
- return promo_increment(cur_promo, TenuredGenerationSizeIncrement);
-}
-
size_t PSAdaptiveSizePolicy::promo_increment_with_supplement_aligned_up(
size_t cur_promo) {
size_t result = promo_increment(cur_promo,
@@ -927,12 +897,6 @@ size_t PSAdaptiveSizePolicy::promo_decrement_aligned_down(size_t cur_promo) {
return align_down(promo_heap_delta, _space_alignment);
}
-size_t PSAdaptiveSizePolicy::promo_decrement(size_t cur_promo) {
- size_t promo_heap_delta = promo_increment(cur_promo);
- promo_heap_delta = promo_heap_delta / AdaptiveSizeDecrementScaleFactor;
- return promo_heap_delta;
-}
-
uint PSAdaptiveSizePolicy::compute_survivor_space_size_and_threshold(
bool is_survivor_overflow,
uint tenuring_threshold,
diff --git a/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.hpp b/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.hpp
index 1cdc4f0d048e4..f6d4be029fbab 100644
--- a/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.hpp
+++ b/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.hpp
@@ -119,9 +119,8 @@ class PSAdaptiveSizePolicy : public AdaptiveSizePolicy {
void adjust_eden_for_minor_pause_time(size_t* desired_eden_size_ptr);
// Change the generation sizes to achieve a GC pause time goal
// Returned sizes are not necessarily aligned.
- void adjust_promo_for_pause_time(size_t* desired_promo_size_ptr,
- size_t* desired_eden_size_ptr);
- void adjust_eden_for_pause_time(size_t* desired_promo_size_ptr, size_t* desired_eden_size_ptr);
+ void adjust_promo_for_pause_time(size_t* desired_promo_size_ptr);
+ void adjust_eden_for_pause_time(size_t* desired_eden_size_ptr);
// Change the generation sizes to achieve an application throughput goal
// Returned sizes are not necessarily aligned.
void adjust_promo_for_throughput(bool is_full_gc,
@@ -136,14 +135,10 @@ class PSAdaptiveSizePolicy : public AdaptiveSizePolicy {
size_t desired_total);
// Size in bytes for an increment or decrement of eden.
- virtual size_t eden_increment(size_t cur_eden, uint percent_change);
- virtual size_t eden_decrement(size_t cur_eden);
size_t eden_decrement_aligned_down(size_t cur_eden);
size_t eden_increment_with_supplement_aligned_up(size_t cur_eden);
// Size in bytes for an increment or decrement of the promotion area
- virtual size_t promo_increment(size_t cur_promo, uint percent_change);
- virtual size_t promo_decrement(size_t cur_promo);
size_t promo_decrement_aligned_down(size_t cur_promo);
size_t promo_increment_with_supplement_aligned_up(size_t cur_promo);
@@ -174,9 +169,6 @@ class PSAdaptiveSizePolicy : public AdaptiveSizePolicy {
virtual GCPolicyKind kind() const { return _gc_ps_adaptive_size_policy; }
public:
- virtual size_t eden_increment(size_t cur_eden);
- virtual size_t promo_increment(size_t cur_promo);
-
// Accessors for use by performance counters
AdaptivePaddedNoZeroDevAverage* avg_promoted() const {
return _gc_stats.avg_promoted();
diff --git a/src/hotspot/share/gc/parallel/psCompactionManager.inline.hpp b/src/hotspot/share/gc/parallel/psCompactionManager.inline.hpp
index 0774597dbfa3c..c0eb546022892 100644
--- a/src/hotspot/share/gc/parallel/psCompactionManager.inline.hpp
+++ b/src/hotspot/share/gc/parallel/psCompactionManager.inline.hpp
@@ -47,9 +47,9 @@ class PCMarkAndPushClosure: public OopClosure {
public:
PCMarkAndPushClosure(ParCompactionManager* cm) : _compaction_manager(cm) { }
- template void do_oop_nv(T* p) { _compaction_manager->mark_and_push(p); }
- virtual void do_oop(oop* p) { do_oop_nv(p); }
- virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
+ template void do_oop_work(T* p) { _compaction_manager->mark_and_push(p); }
+ virtual void do_oop(oop* p) { do_oop_work(p); }
+ virtual void do_oop(narrowOop* p) { do_oop_work(p); }
};
class PCIterateMarkAndPushClosure: public ClaimMetadataVisitingOopIterateClosure {
@@ -60,9 +60,9 @@ class PCIterateMarkAndPushClosure: public ClaimMetadataVisitingOopIterateClosure
ClaimMetadataVisitingOopIterateClosure(ClassLoaderData::_claim_stw_fullgc_mark, rp),
_compaction_manager(cm) { }
- template void do_oop_nv(T* p) { _compaction_manager->mark_and_push(p); }
- virtual void do_oop(oop* p) { do_oop_nv(p); }
- virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
+ template void do_oop_work(T* p) { _compaction_manager->mark_and_push(p); }
+ virtual void do_oop(oop* p) { do_oop_work(p); }
+ virtual void do_oop(narrowOop* p) { do_oop_work(p); }
};
inline bool ParCompactionManager::steal(int queue_num, oop& t) {
diff --git a/src/hotspot/share/gc/parallel/psParallelCompact.inline.hpp b/src/hotspot/share/gc/parallel/psParallelCompact.inline.hpp
index ccf01ea30876b..ff6052d5070a7 100644
--- a/src/hotspot/share/gc/parallel/psParallelCompact.inline.hpp
+++ b/src/hotspot/share/gc/parallel/psParallelCompact.inline.hpp
@@ -130,9 +130,9 @@ class PCAdjustPointerClosure: public BasicOopIterateClosure {
public:
PCAdjustPointerClosure(ParCompactionManager* cm) : _cm(cm) {
}
- template void do_oop_nv(T* p) { PSParallelCompact::adjust_pointer(p, _cm); }
- virtual void do_oop(oop* p) { do_oop_nv(p); }
- virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
+ template void do_oop_work(T* p) { PSParallelCompact::adjust_pointer(p, _cm); }
+ virtual void do_oop(oop* p) { do_oop_work(p); }
+ virtual void do_oop(narrowOop* p) { do_oop_work(p); }
virtual ReferenceIterationMode reference_iteration_mode() { return DO_FIELDS; }
private:
diff --git a/src/hotspot/share/gc/parallel/psPromotionManager.cpp b/src/hotspot/share/gc/parallel/psPromotionManager.cpp
index 7610a6e13d77b..149acc1a4297f 100644
--- a/src/hotspot/share/gc/parallel/psPromotionManager.cpp
+++ b/src/hotspot/share/gc/parallel/psPromotionManager.cpp
@@ -173,13 +173,9 @@ void PSPromotionManager::reset_stats() {
#endif // TASKQUEUE_STATS
PSPromotionManager::PSPromotionManager() {
- ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
-
// We set the old lab's start array.
_old_lab.set_start_array(old_gen()->start_array());
- uint queue_size = claimed_stack_depth()->max_elems();
-
if (ParallelGCThreads == 1) {
_target_stack_size = 0;
} else {
diff --git a/src/hotspot/share/gc/parallel/psPromotionManager.inline.hpp b/src/hotspot/share/gc/parallel/psPromotionManager.inline.hpp
index c1cbeb0f597bb..fd830b831552f 100644
--- a/src/hotspot/share/gc/parallel/psPromotionManager.inline.hpp
+++ b/src/hotspot/share/gc/parallel/psPromotionManager.inline.hpp
@@ -95,14 +95,14 @@ class PSPushContentsClosure: public BasicOopIterateClosure {
public:
PSPushContentsClosure(PSPromotionManager* pm) : BasicOopIterateClosure(PSScavenge::reference_processor()), _pm(pm) {}
- template void do_oop_nv(T* p) {
+ template void do_oop_work(T* p) {
if (PSScavenge::should_scavenge(p)) {
_pm->claim_or_forward_depth(p);
}
}
- virtual void do_oop(oop* p) { do_oop_nv(p); }
- virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
+ virtual void do_oop(oop* p) { do_oop_work(p); }
+ virtual void do_oop(narrowOop* p) { do_oop_work(p); }
};
//
diff --git a/src/hotspot/share/gc/parallel/psScavenge.hpp b/src/hotspot/share/gc/parallel/psScavenge.hpp
index 69fa18aa0bec7..0c61bc9c30e1e 100644
--- a/src/hotspot/share/gc/parallel/psScavenge.hpp
+++ b/src/hotspot/share/gc/parallel/psScavenge.hpp
@@ -33,12 +33,10 @@
#include "oops/oop.hpp"
#include "utilities/stack.hpp"
-class OopStack;
class ReferenceProcessor;
class ParallelScavengeHeap;
class ParallelScavengeTracer;
class PSIsAliveClosure;
-class PSRefProcTaskExecutor;
class STWGCTimer;
class PSScavenge: AllStatic {
diff --git a/src/hotspot/share/gc/parallel/psVirtualspace.cpp b/src/hotspot/share/gc/parallel/psVirtualspace.cpp
index f0ccd9a751c85..a4d686d867042 100644
--- a/src/hotspot/share/gc/parallel/psVirtualspace.cpp
+++ b/src/hotspot/share/gc/parallel/psVirtualspace.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -113,7 +113,7 @@ void PSVirtualSpace::verify() const {
// Reserved region must be non-empty or both addrs must be 0.
assert(reserved_low_addr() < reserved_high_addr() ||
- reserved_low_addr() == nullptr && reserved_high_addr() == nullptr,
+ (reserved_low_addr() == nullptr && reserved_high_addr() == nullptr),
"bad reserved addrs");
assert(committed_low_addr() <= committed_high_addr(), "bad committed addrs");
diff --git a/src/hotspot/share/gc/shared/adaptiveSizePolicy.hpp b/src/hotspot/share/gc/shared/adaptiveSizePolicy.hpp
index 09e452c2d4997..959fb3102589e 100644
--- a/src/hotspot/share/gc/shared/adaptiveSizePolicy.hpp
+++ b/src/hotspot/share/gc/shared/adaptiveSizePolicy.hpp
@@ -51,15 +51,11 @@ class AdaptiveSizePolicy : public CHeapObj {
decrease_old_gen_for_throughput_true = -7,
decrease_young_gen_for_througput_true = -6,
- increase_old_gen_for_min_pauses_true = -5,
- decrease_old_gen_for_min_pauses_true = -4,
- decrease_young_gen_for_maj_pauses_true = -3,
increase_young_gen_for_min_pauses_true = -2,
increase_old_gen_for_maj_pauses_true = -1,
decrease_young_gen_for_min_pauses_true = 1,
decrease_old_gen_for_maj_pauses_true = 2,
- increase_young_gen_for_maj_pauses_true = 3,
increase_old_gen_for_throughput_true = 4,
increase_young_gen_for_througput_true = 5,
@@ -267,12 +263,12 @@ class AdaptiveSizePolicy : public CHeapObj {
// to use minor_collection_end() in its current form.
}
- virtual size_t eden_increment(size_t cur_eden);
- virtual size_t eden_increment(size_t cur_eden, uint percent_change);
- virtual size_t eden_decrement(size_t cur_eden);
- virtual size_t promo_increment(size_t cur_eden);
- virtual size_t promo_increment(size_t cur_eden, uint percent_change);
- virtual size_t promo_decrement(size_t cur_eden);
+ size_t eden_increment(size_t cur_eden);
+ size_t eden_increment(size_t cur_eden, uint percent_change);
+ size_t eden_decrement(size_t cur_eden);
+ size_t promo_increment(size_t cur_eden);
+ size_t promo_increment(size_t cur_eden, uint percent_change);
+ size_t promo_decrement(size_t cur_eden);
virtual void clear_generation_free_space_flags();
diff --git a/src/hotspot/share/gc/shared/collectedHeap.cpp b/src/hotspot/share/gc/shared/collectedHeap.cpp
index 422fef2431889..1b65ee90b5d7a 100644
--- a/src/hotspot/share/gc/shared/collectedHeap.cpp
+++ b/src/hotspot/share/gc/shared/collectedHeap.cpp
@@ -558,9 +558,13 @@ void CollectedHeap::record_whole_heap_examined_timestamp() {
void CollectedHeap::full_gc_dump(GCTimer* timer, bool before) {
assert(timer != nullptr, "timer is null");
+ static uint count = 0;
if ((HeapDumpBeforeFullGC && before) || (HeapDumpAfterFullGC && !before)) {
- GCTraceTime(Info, gc) tm(before ? "Heap Dump (before full gc)" : "Heap Dump (after full gc)", timer);
- HeapDumper::dump_heap();
+ if (FullGCHeapDumpLimit == 0 || count < FullGCHeapDumpLimit) {
+ GCTraceTime(Info, gc) tm(before ? "Heap Dump (before full gc)" : "Heap Dump (after full gc)", timer);
+ HeapDumper::dump_heap();
+ count++;
+ }
}
LogTarget(Trace, gc, classhisto) lt;
diff --git a/src/hotspot/share/gc/shared/freeListAllocator.hpp b/src/hotspot/share/gc/shared/freeListAllocator.hpp
index d8ab4c4e8bc1b..74b896963a736 100644
--- a/src/hotspot/share/gc/shared/freeListAllocator.hpp
+++ b/src/hotspot/share/gc/shared/freeListAllocator.hpp
@@ -109,10 +109,10 @@ class FreeListAllocator {
typedef LockFreeStack Stack;
FreeListConfig* _config;
- char _name[DEFAULT_CACHE_LINE_SIZE - sizeof(FreeListConfig*)]; // Use name as padding.
+ char _name[DEFAULT_PADDING_SIZE - sizeof(FreeListConfig*)]; // Use name as padding.
#define DECLARE_PADDED_MEMBER(Id, Type, Name) \
- Type Name; DEFINE_PAD_MINUS_SIZE(Id, DEFAULT_CACHE_LINE_SIZE, sizeof(Type))
+ Type Name; DEFINE_PAD_MINUS_SIZE(Id, DEFAULT_PADDING_SIZE, sizeof(Type))
DECLARE_PADDED_MEMBER(1, volatile size_t, _free_count);
DECLARE_PADDED_MEMBER(2, Stack, _free_list);
DECLARE_PADDED_MEMBER(3, volatile bool, _transfer_lock);
diff --git a/src/hotspot/share/gc/shared/gc_globals.hpp b/src/hotspot/share/gc/shared/gc_globals.hpp
index e2b30bc615e13..ae8674c84a9d0 100644
--- a/src/hotspot/share/gc/shared/gc_globals.hpp
+++ b/src/hotspot/share/gc/shared/gc_globals.hpp
@@ -408,11 +408,6 @@
"Allowed collection cost difference between generations") \
range(0, 100) \
\
- product(uint, AdaptiveSizePolicyCollectionCostMargin, 50, \
- "If collection costs are within margin, reduce both by full " \
- "delta") \
- range(0, 100) \
- \
product(uint, YoungGenerationSizeIncrement, 20, \
"Adaptive size percentage change in young generation") \
range(0, 100) \
diff --git a/src/hotspot/share/gc/shared/satbMarkQueue.hpp b/src/hotspot/share/gc/shared/satbMarkQueue.hpp
index d92523d7e4f78..78fe203329623 100644
--- a/src/hotspot/share/gc/shared/satbMarkQueue.hpp
+++ b/src/hotspot/share/gc/shared/satbMarkQueue.hpp
@@ -85,7 +85,7 @@ class SATBMarkQueue: public PtrQueue {
class SATBMarkQueueSet: public PtrQueueSet {
- DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, 0);
+ DEFINE_PAD_MINUS_SIZE(1, DEFAULT_PADDING_SIZE, 0);
PaddedEnd _list;
volatile size_t _count_and_process_flag;
// These are rarely (if ever) changed, so same cache line as count.
@@ -93,7 +93,7 @@ class SATBMarkQueueSet: public PtrQueueSet {
size_t _buffer_enqueue_threshold;
// SATB is only active during marking. Enqueuing is only done when active.
bool _all_active;
- DEFINE_PAD_MINUS_SIZE(2, DEFAULT_CACHE_LINE_SIZE, 4 * sizeof(size_t));
+ DEFINE_PAD_MINUS_SIZE(2, DEFAULT_PADDING_SIZE, 4 * sizeof(size_t));
BufferNode* get_completed_buffer();
void abandon_completed_buffers();
diff --git a/src/hotspot/share/gc/shared/taskTerminator.hpp b/src/hotspot/share/gc/shared/taskTerminator.hpp
index aac4e065a5ceb..540d91c88bb48 100644
--- a/src/hotspot/share/gc/shared/taskTerminator.hpp
+++ b/src/hotspot/share/gc/shared/taskTerminator.hpp
@@ -72,9 +72,9 @@ class TaskTerminator : public CHeapObj {
uint _n_threads;
TaskQueueSetSuper* _queue_set;
- DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE, 0);
+ DEFINE_PAD_MINUS_SIZE(0, DEFAULT_PADDING_SIZE, 0);
volatile uint _offered_termination;
- DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, sizeof(volatile uint));
+ DEFINE_PAD_MINUS_SIZE(1, DEFAULT_PADDING_SIZE, sizeof(volatile uint));
Monitor _blocker;
Thread* _spin_master;
diff --git a/src/hotspot/share/gc/shared/taskqueue.hpp b/src/hotspot/share/gc/shared/taskqueue.hpp
index a5e3dfdf8079d..2e21ba33b0bf7 100644
--- a/src/hotspot/share/gc/shared/taskqueue.hpp
+++ b/src/hotspot/share/gc/shared/taskqueue.hpp
@@ -233,11 +233,11 @@ class TaskQueueSuper: public CHeapObj {
}
private:
- DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE, 0);
+ DEFINE_PAD_MINUS_SIZE(0, DEFAULT_PADDING_SIZE, 0);
// Index of the first free element after the last one pushed (mod N).
volatile uint _bottom;
- DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, sizeof(uint));
+ DEFINE_PAD_MINUS_SIZE(1, DEFAULT_PADDING_SIZE, sizeof(uint));
// top() is the index of the oldest pushed element (mod N), and tag()
// is the associated epoch, to distinguish different modifications of
@@ -245,7 +245,7 @@ class TaskQueueSuper: public CHeapObj {
// (_bottom - top()) mod N == N-1; the latter indicates underflow
// during concurrent pop_local/pop_global.
volatile Age _age;
- DEFINE_PAD_MINUS_SIZE(2, DEFAULT_CACHE_LINE_SIZE, sizeof(Age));
+ DEFINE_PAD_MINUS_SIZE(2, DEFAULT_PADDING_SIZE, sizeof(Age));
NONCOPYABLE(TaskQueueSuper);
@@ -396,7 +396,7 @@ class GenericTaskQueue: public TaskQueueSuper {
// Element array.
E* _elems;
- DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, sizeof(E*));
+ DEFINE_PAD_MINUS_SIZE(1, DEFAULT_PADDING_SIZE, sizeof(E*));
// Queue owner local variables. Not to be accessed by other threads.
static const uint InvalidQueueId = uint(-1);
@@ -404,7 +404,7 @@ class GenericTaskQueue: public TaskQueueSuper {
int _seed; // Current random seed used for selecting a random queue during stealing.
- DEFINE_PAD_MINUS_SIZE(2, DEFAULT_CACHE_LINE_SIZE, sizeof(uint) + sizeof(int));
+ DEFINE_PAD_MINUS_SIZE(2, DEFAULT_PADDING_SIZE, sizeof(uint) + sizeof(int));
public:
int next_random_queue_id();
diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp
index acb52602735a5..12eb2aad5e803 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp
@@ -1742,7 +1742,7 @@ void ShenandoahHeap::prepare_update_heap_references(bool concurrent) {
_update_refs_iterator.reset();
}
-void ShenandoahHeap::set_gc_state_all_threads() {
+void ShenandoahHeap::propagate_gc_state_to_java_threads() {
assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at Shenandoah safepoint");
if (_gc_state_changed) {
_gc_state_changed = false;
@@ -1753,7 +1753,7 @@ void ShenandoahHeap::set_gc_state_all_threads() {
}
}
-void ShenandoahHeap::set_gc_state_mask(uint mask, bool value) {
+void ShenandoahHeap::set_gc_state(uint mask, bool value) {
assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at Shenandoah safepoint");
_gc_state.set_cond(mask, value);
_gc_state_changed = true;
@@ -1761,13 +1761,13 @@ void ShenandoahHeap::set_gc_state_mask(uint mask, bool value) {
void ShenandoahHeap::set_concurrent_mark_in_progress(bool in_progress) {
assert(!has_forwarded_objects(), "Not expected before/after mark phase");
- set_gc_state_mask(MARKING, in_progress);
+ set_gc_state(MARKING, in_progress);
ShenandoahBarrierSet::satb_mark_queue_set().set_active_all_threads(in_progress, !in_progress);
}
void ShenandoahHeap::set_evacuation_in_progress(bool in_progress) {
assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Only call this at safepoint");
- set_gc_state_mask(EVACUATION, in_progress);
+ set_gc_state(EVACUATION, in_progress);
}
void ShenandoahHeap::set_concurrent_strong_root_in_progress(bool in_progress) {
@@ -1779,7 +1779,7 @@ void ShenandoahHeap::set_concurrent_strong_root_in_progress(bool in_progress) {
}
void ShenandoahHeap::set_concurrent_weak_root_in_progress(bool cond) {
- set_gc_state_mask(WEAK_ROOTS, cond);
+ set_gc_state(WEAK_ROOTS, cond);
}
GCTracer* ShenandoahHeap::tracer() {
@@ -1906,7 +1906,7 @@ void ShenandoahHeap::parallel_cleaning(bool full_gc) {
}
void ShenandoahHeap::set_has_forwarded_objects(bool cond) {
- set_gc_state_mask(HAS_FORWARDED, cond);
+ set_gc_state(HAS_FORWARDED, cond);
}
void ShenandoahHeap::set_unload_classes(bool uc) {
@@ -1945,7 +1945,7 @@ void ShenandoahHeap::set_full_gc_move_in_progress(bool in_progress) {
}
void ShenandoahHeap::set_update_refs_in_progress(bool in_progress) {
- set_gc_state_mask(UPDATEREFS, in_progress);
+ set_gc_state(UPDATEREFS, in_progress);
}
void ShenandoahHeap::register_nmethod(nmethod* nm) {
diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp
index 1873ee040e3f7..deb0a972167e9 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp
@@ -293,12 +293,19 @@ class ShenandoahHeap : public CollectedHeap, public ShenandoahSpaceInfo {
size_t _gc_no_progress_count;
- void set_gc_state_mask(uint mask, bool value);
+ // This updates the singlular, global gc state. This must happen on a safepoint.
+ void set_gc_state(uint mask, bool value);
public:
char gc_state() const;
- void set_gc_state_all_threads();
- bool has_gc_state_changed() { return _gc_state_changed; }
+
+ // This copies the global gc state into a thread local variable for java threads.
+ // It is primarily intended to support quick access at barriers.
+ void propagate_gc_state_to_java_threads();
+
+ // This is public to support assertions that the state hasn't been changed off of
+ // a safepoint and that any changes were propagated to java threads after the safepoint.
+ bool has_gc_state_changed() const { return _gc_state_changed; }
void set_concurrent_mark_in_progress(bool in_progress);
void set_evacuation_in_progress(bool in_progress);
diff --git a/src/hotspot/share/gc/shenandoah/shenandoahThreadLocalData.hpp b/src/hotspot/share/gc/shenandoah/shenandoahThreadLocalData.hpp
index 422595e93135c..9eec573cc567b 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoahThreadLocalData.hpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahThreadLocalData.hpp
@@ -89,6 +89,7 @@ class ShenandoahThreadLocalData {
}
static char gc_state(Thread* thread) {
+ assert(thread->is_Java_thread(), "GC state is only synchronized to java threads");
return data(thread)->_gc_state;
}
diff --git a/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.cpp b/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.cpp
index 970f99ad0f563..eeeb1dcad195a 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.cpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.cpp
@@ -62,41 +62,41 @@ void VM_ShenandoahReferenceOperation::doit_epilogue() {
void VM_ShenandoahInitMark::doit() {
ShenandoahGCPauseMark mark(_gc_id, "Init Mark", SvcGCMarker::CONCURRENT);
_gc->entry_init_mark();
- ShenandoahHeap::heap()->set_gc_state_all_threads();
+ ShenandoahHeap::heap()->propagate_gc_state_to_java_threads();
}
void VM_ShenandoahFinalMarkStartEvac::doit() {
ShenandoahGCPauseMark mark(_gc_id, "Final Mark", SvcGCMarker::CONCURRENT);
_gc->entry_final_mark();
- ShenandoahHeap::heap()->set_gc_state_all_threads();
+ ShenandoahHeap::heap()->propagate_gc_state_to_java_threads();
}
void VM_ShenandoahFullGC::doit() {
ShenandoahGCPauseMark mark(_gc_id, "Full GC", SvcGCMarker::FULL);
_full_gc->entry_full(_gc_cause);
- ShenandoahHeap::heap()->set_gc_state_all_threads();
+ ShenandoahHeap::heap()->propagate_gc_state_to_java_threads();
}
void VM_ShenandoahDegeneratedGC::doit() {
ShenandoahGCPauseMark mark(_gc_id, "Degenerated GC", SvcGCMarker::CONCURRENT);
_gc->entry_degenerated();
- ShenandoahHeap::heap()->set_gc_state_all_threads();
+ ShenandoahHeap::heap()->propagate_gc_state_to_java_threads();
}
void VM_ShenandoahInitUpdateRefs::doit() {
ShenandoahGCPauseMark mark(_gc_id, "Init Update Refs", SvcGCMarker::CONCURRENT);
_gc->entry_init_updaterefs();
- ShenandoahHeap::heap()->set_gc_state_all_threads();
+ ShenandoahHeap::heap()->propagate_gc_state_to_java_threads();
}
void VM_ShenandoahFinalUpdateRefs::doit() {
ShenandoahGCPauseMark mark(_gc_id, "Final Update Refs", SvcGCMarker::CONCURRENT);
_gc->entry_final_updaterefs();
- ShenandoahHeap::heap()->set_gc_state_all_threads();
+ ShenandoahHeap::heap()->propagate_gc_state_to_java_threads();
}
void VM_ShenandoahFinalRoots::doit() {
ShenandoahGCPauseMark mark(_gc_id, "Final Roots", SvcGCMarker::CONCURRENT);
_gc->entry_final_roots();
- ShenandoahHeap::heap()->set_gc_state_all_threads();
+ ShenandoahHeap::heap()->propagate_gc_state_to_java_threads();
}
diff --git a/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp b/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp
index 6a977c2e4a40c..f67cafdb8fe7c 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp
@@ -620,7 +620,7 @@ void ShenandoahVerifier::verify_at_safepoint(const char *label,
guarantee(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "only when nothing else happens");
guarantee(ShenandoahVerify, "only when enabled, and bitmap is initialized in ShenandoahHeap::initialize");
- ShenandoahHeap::heap()->set_gc_state_all_threads();
+ ShenandoahHeap::heap()->propagate_gc_state_to_java_threads();
// Avoid side-effect of changing workers' active thread count, but bypass concurrent/parallel protocol check
ShenandoahPushWorkerScope verify_worker_scope(_heap->workers(), _heap->max_workers(), false /*bypass check*/);
diff --git a/src/hotspot/share/gc/x/xHeap.cpp b/src/hotspot/share/gc/x/xHeap.cpp
index 14661330e132f..75d9bc0846033 100644
--- a/src/hotspot/share/gc/x/xHeap.cpp
+++ b/src/hotspot/share/gc/x/xHeap.cpp
@@ -249,7 +249,7 @@ void XHeap::mark_start() {
// Enter mark phase
XGlobalPhase = XPhaseMark;
- // Reset marking information and mark roots
+ // Reset marking information
_mark.start();
// Update statistics
diff --git a/src/hotspot/share/gc/z/zGeneration.cpp b/src/hotspot/share/gc/z/zGeneration.cpp
index 3f62ba5bfd14a..5e42fbd7ef8d9 100644
--- a/src/hotspot/share/gc/z/zGeneration.cpp
+++ b/src/hotspot/share/gc/z/zGeneration.cpp
@@ -861,7 +861,7 @@ void ZGenerationYoung::mark_start() {
// Enter mark phase
set_phase(Phase::Mark);
- // Reset marking information and mark roots
+ // Reset marking information
_mark.start();
// Flip remembered set bits
@@ -1213,7 +1213,7 @@ void ZGenerationOld::mark_start() {
// Enter mark phase
set_phase(Phase::Mark);
- // Reset marking information and mark roots
+ // Reset marking information
_mark.start();
// Update statistics
diff --git a/src/hotspot/share/interpreter/bytecodes.cpp b/src/hotspot/share/interpreter/bytecodes.cpp
index 89dab8382d3a9..af3c1a2dbef3a 100644
--- a/src/hotspot/share/interpreter/bytecodes.cpp
+++ b/src/hotspot/share/interpreter/bytecodes.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -536,7 +536,7 @@ jchar Bytecodes::compute_flags(const char* format, jchar more_flags) {
}
guarantee(has_size == 0 || // no field yet
this_size == has_size || // same size
- this_size < has_size && *fp == '\0', // last field can be short
+ (this_size < has_size && *fp == '\0'), // last field can be short
"mixed field sizes in format");
has_size = this_size;
}
diff --git a/src/hotspot/share/jfr/metadata/metadata.xml b/src/hotspot/share/jfr/metadata/metadata.xml
index c1f626a819201..53fa17555c687 100644
--- a/src/hotspot/share/jfr/metadata/metadata.xml
+++ b/src/hotspot/share/jfr/metadata/metadata.xml
@@ -957,6 +957,8 @@
+
+
();
}
@@ -90,8 +90,17 @@ void NativeLibraryUnloadEvent::set_result(bool result) {
_result = result;
}
+static void set_additional_data(EventNativeLibraryLoad& event, const NativeLibraryLoadEvent& helper) {
+ event.set_fpEnvCorrectionAttempt(helper.get_fp_env_correction_attempt());
+ event.set_fpEnvCorrectionSuccess(helper.get_fp_env_correction_success());
+}
+
+static void set_additional_data(EventNativeLibraryUnload& event, const NativeLibraryUnloadEvent& helper) {
+ // no additional entries atm. for the unload event
+}
+
template
-static void commit(HelperType& helper) {
+static void commit(const HelperType& helper) {
if (!helper.has_start_time()) {
return;
}
@@ -101,6 +110,7 @@ static void commit(HelperType& helper) {
event.set_name(helper.name());
event.set_errorMessage(helper.error_msg());
event.set_success(helper.success());
+ set_additional_data(event, helper);
Thread* thread = Thread::current();
assert(thread != nullptr, "invariant");
if (thread->is_Java_thread()) {
diff --git a/src/hotspot/share/jfr/support/jfrNativeLibraryLoadEvent.hpp b/src/hotspot/share/jfr/support/jfrNativeLibraryLoadEvent.hpp
index fe8431fdc438e..30281ad4d0540 100644
--- a/src/hotspot/share/jfr/support/jfrNativeLibraryLoadEvent.hpp
+++ b/src/hotspot/share/jfr/support/jfrNativeLibraryLoadEvent.hpp
@@ -52,10 +52,16 @@ class JfrNativeLibraryEventBase : public StackObj {
class NativeLibraryLoadEvent : public JfrNativeLibraryEventBase {
private:
void** _result;
+ bool _fp_env_correction_attempt;
+ bool _fp_env_correction_success;
public:
NativeLibraryLoadEvent(const char* name, void** result);
~NativeLibraryLoadEvent();
bool success() const;
+ bool get_fp_env_correction_attempt() const { return _fp_env_correction_attempt; }
+ bool get_fp_env_correction_success() const { return _fp_env_correction_success; }
+ void set_fp_env_correction_attempt(bool v) { _fp_env_correction_attempt = v; }
+ void set_fp_env_correction_success(bool v) { _fp_env_correction_success = v; }
};
class NativeLibraryUnloadEvent : public JfrNativeLibraryEventBase {
diff --git a/src/hotspot/share/jfr/utilities/jfrVersionSystem.hpp b/src/hotspot/share/jfr/utilities/jfrVersionSystem.hpp
index 5005b5b8f3f8d..39c40fd714779 100644
--- a/src/hotspot/share/jfr/utilities/jfrVersionSystem.hpp
+++ b/src/hotspot/share/jfr/utilities/jfrVersionSystem.hpp
@@ -105,9 +105,9 @@ class JfrVersionSystem : public JfrCHeapObj {
NodePtr synchronize_with(Type version, NodePtr last) const;
DEBUG_ONLY(void assert_state(const Node* node) const;)
struct PaddedTip {
- DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE, 0);
+ DEFINE_PAD_MINUS_SIZE(0, DEFAULT_PADDING_SIZE, 0);
volatile Type _value;
- DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, sizeof(volatile Type));
+ DEFINE_PAD_MINUS_SIZE(1, DEFAULT_PADDING_SIZE, sizeof(volatile Type));
};
PaddedTip _tip;
NodePtr _head;
diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVM.hpp b/src/hotspot/share/jvmci/jvmciCompilerToVM.hpp
index 421ebd7396f43..ff159a490c184 100644
--- a/src/hotspot/share/jvmci/jvmciCompilerToVM.hpp
+++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.hpp
@@ -115,6 +115,13 @@ class CompilerToVM {
// Minimum alignment of an offset into CodeBuffer::SECT_CONSTS
static int data_section_item_alignment;
+ /*
+ * Pointer to JvmtiExport::_should_notify_object_alloc.
+ * Exposed as an int* instead of an address so the
+ * underlying type is part of the JVMCIVMStructs definition.
+ */
+ static int* _should_notify_object_alloc;
+
public:
static void initialize(JVMCI_TRAPS);
diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp b/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp
index a3e2bd525ecf6..89fa78b10f30e 100644
--- a/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp
+++ b/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp
@@ -45,6 +45,7 @@
#include "memory/universe.hpp"
#include "oops/compressedOops.hpp"
#include "oops/klass.inline.hpp"
+#include "prims/jvmtiExport.hpp"
#ifdef COMPILER2
#include "opto/c2compiler.hpp"
#endif
@@ -130,6 +131,8 @@ address CompilerToVM::Data::symbol_clinit;
int CompilerToVM::Data::data_section_item_alignment;
+int* CompilerToVM::Data::_should_notify_object_alloc;
+
void CompilerToVM::Data::initialize(JVMCI_TRAPS) {
Klass_vtable_start_offset = in_bytes(Klass::vtable_start_offset());
Klass_vtable_length_offset = in_bytes(Klass::vtable_length_offset());
@@ -196,6 +199,8 @@ void CompilerToVM::Data::initialize(JVMCI_TRAPS) {
data_section_item_alignment = relocInfo::addr_unit();
+ _should_notify_object_alloc = &JvmtiExport::_should_notify_object_alloc;
+
BarrierSet* bs = BarrierSet::barrier_set();
if (bs->is_a(BarrierSet::CardTableBarrierSet)) {
CardTable::CardValue* base = ci_card_table_address();
diff --git a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp
index bac9a786fd9fb..2ad442db93483 100644
--- a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp
+++ b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp
@@ -122,6 +122,8 @@
\
static_field(CompilerToVM::Data, data_section_item_alignment, int) \
\
+ static_field(CompilerToVM::Data, _should_notify_object_alloc, int*) \
+ \
static_field(Abstract_VM_Version, _features, uint64_t) \
\
nonstatic_field(Annotations, _class_annotations, AnnotationArray*) \
diff --git a/src/hotspot/share/memory/padded.hpp b/src/hotspot/share/memory/padded.hpp
index 1811810c19e42..0597dbd9f3c20 100644
--- a/src/hotspot/share/memory/padded.hpp
+++ b/src/hotspot/share/memory/padded.hpp
@@ -40,14 +40,14 @@
// effective only when applied to derived-most (leaf) classes.
// When no args are passed to the base ctor.
-template
+template
class Padded : public T {
private:
char _pad_buf_[PADDING_SIZE(T, alignment)];
};
// When either 0 or 1 args may be passed to the base ctor.
-template
+template
class Padded01 : public T {
public:
Padded01(): T() { }
@@ -75,7 +75,7 @@ class PaddedEndImpl : public T {
// minimal amount of padding needed to make the size of the objects be aligned.
// This will help reducing false sharing,
// if the start address is a multiple of alignment.
-template
+template
class PaddedEnd : public PaddedEndImpl {
// C++ doesn't allow zero-length arrays. The padding is put in a
// super class that is specialized for the pad_size == 0 case.
@@ -89,7 +89,7 @@ class PaddedEnd : public PaddedEndImpl {
// Helper class to create an array of PaddedEnd objects. All elements will
// start at a multiple of alignment and the size will be aligned to alignment.
-template
+template
class PaddedArray {
public:
// Creates an aligned padded array.
@@ -100,7 +100,7 @@ class PaddedArray {
// Helper class to create an array of references to arrays of primitive types
// Both the array of references and the data arrays are aligned to the given
// alignment. The allocated memory is zero-filled.
-template
+template
class Padded2DArray {
public:
// Creates an aligned padded 2D array.
@@ -112,7 +112,7 @@ class Padded2DArray {
// Helper class to create an array of T objects. The array as a whole will
// start at a multiple of alignment and its size will be aligned to alignment.
-template
+template
class PaddedPrimitiveArray {
public:
static T* create_unfreeable(size_t length);
diff --git a/src/hotspot/share/memory/universe.cpp b/src/hotspot/share/memory/universe.cpp
index 25ec68cf8fec5..dfeb6b11f6f21 100644
--- a/src/hotspot/share/memory/universe.cpp
+++ b/src/hotspot/share/memory/universe.cpp
@@ -338,7 +338,7 @@ void Universe::genesis(TRAPS) {
// Initialization of the fillerArrayKlass must come before regular
// int-TypeArrayKlass so that the int-Array mirror points to the
// int-TypeArrayKlass.
- _fillerArrayKlassObj = TypeArrayKlass::create_klass(T_INT, "Ljdk/internal/vm/FillerArray;", CHECK);
+ _fillerArrayKlassObj = TypeArrayKlass::create_klass(T_INT, "[Ljdk/internal/vm/FillerElement;", CHECK);
for (int i = T_BOOLEAN; i < T_LONG+1; i++) {
_typeArrayKlassObjs[i] = TypeArrayKlass::create_klass((BasicType)i, CHECK);
}
diff --git a/src/hotspot/share/oops/constantPool.hpp b/src/hotspot/share/oops/constantPool.hpp
index 5963fd194c531..eec628b1e5bd3 100644
--- a/src/hotspot/share/oops/constantPool.hpp
+++ b/src/hotspot/share/oops/constantPool.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -539,7 +539,7 @@ class ConstantPool : public Metadata {
int offset = build_int_from_shorts(operands->at(n+0),
operands->at(n+1));
// The offset itself must point into the second part of the array.
- assert(offset == 0 || offset >= second_part && offset <= operands->length(), "oob (3)");
+ assert(offset == 0 || (offset >= second_part && offset <= operands->length()), "oob (3)");
return offset;
}
static void operand_offset_at_put(Array* operands, int bsms_attribute_index, int offset) {
diff --git a/src/hotspot/share/oops/method.cpp b/src/hotspot/share/oops/method.cpp
index 0922fc4eac773..5cd59a802be22 100644
--- a/src/hotspot/share/oops/method.cpp
+++ b/src/hotspot/share/oops/method.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -326,7 +326,7 @@ int Method::bci_from(address bcp) const {
}
// Do not have a ResourceMark here because AsyncGetCallTrace stack walking code
// may call this after interrupting a nested ResourceMark.
- assert(is_native() && bcp == code_base() || contains(bcp) || VMError::is_error_reported(),
+ assert((is_native() && bcp == code_base()) || contains(bcp) || VMError::is_error_reported(),
"bcp doesn't belong to this method. bcp: " PTR_FORMAT, p2i(bcp));
return int(bcp - code_base());
@@ -360,7 +360,7 @@ address Method::bcp_from(int bci) const {
assert((is_native() && bci == 0) || (!is_native() && 0 <= bci && bci < code_size()),
"illegal bci: %d for %s method", bci, is_native() ? "native" : "non-native");
address bcp = code_base() + bci;
- assert(is_native() && bcp == code_base() || contains(bcp), "bcp doesn't belong to this method");
+ assert((is_native() && bcp == code_base()) || contains(bcp), "bcp doesn't belong to this method");
return bcp;
}
diff --git a/src/hotspot/share/oops/method.hpp b/src/hotspot/share/oops/method.hpp
index 34f982d9f407c..89d5ccbb168f5 100644
--- a/src/hotspot/share/oops/method.hpp
+++ b/src/hotspot/share/oops/method.hpp
@@ -395,7 +395,8 @@ class Method : public Metadata {
void remove_unshareable_flags() NOT_CDS_RETURN;
// the number of argument reg slots that the compiled method uses on the stack.
- int num_stack_arg_slots() const { return constMethod()->num_stack_arg_slots(); }
+ int num_stack_arg_slots(bool rounded = true) const {
+ return rounded ? align_up(constMethod()->num_stack_arg_slots(), 2) : constMethod()->num_stack_arg_slots(); }
virtual void metaspace_pointers_do(MetaspaceClosure* iter);
virtual MetaspaceObj::Type type() const { return MethodType; }
diff --git a/src/hotspot/share/oops/stackChunkOop.hpp b/src/hotspot/share/oops/stackChunkOop.hpp
index 36b06ecd3246e..abfe47ad3f1c4 100644
--- a/src/hotspot/share/oops/stackChunkOop.hpp
+++ b/src/hotspot/share/oops/stackChunkOop.hpp
@@ -155,7 +155,7 @@ class stackChunkOopDesc : public instanceOopDesc {
inline void* gc_data() const;
inline BitMapView bitmap() const;
- inline BitMap::idx_t bit_index_for(intptr_t* p) const;
+ inline BitMap::idx_t bit_index_for(address p) const;
inline intptr_t* address_for_bit(BitMap::idx_t index) const;
template inline BitMap::idx_t bit_index_for(OopT* p) const;
template inline OopT* address_for_bit(BitMap::idx_t index) const;
diff --git a/src/hotspot/share/oops/stackChunkOop.inline.hpp b/src/hotspot/share/oops/stackChunkOop.inline.hpp
index e19932072664a..c75908610324d 100644
--- a/src/hotspot/share/oops/stackChunkOop.inline.hpp
+++ b/src/hotspot/share/oops/stackChunkOop.inline.hpp
@@ -256,12 +256,13 @@ inline BitMapView stackChunkOopDesc::bitmap() const {
return bitmap;
}
-inline BitMap::idx_t stackChunkOopDesc::bit_index_for(intptr_t* p) const {
+inline BitMap::idx_t stackChunkOopDesc::bit_index_for(address p) const {
return UseCompressedOops ? bit_index_for((narrowOop*)p) : bit_index_for((oop*)p);
}
template
inline BitMap::idx_t stackChunkOopDesc::bit_index_for(OopT* p) const {
+ assert(is_aligned(p, alignof(OopT)), "should be aligned: " PTR_FORMAT, p2i(p));
assert(p >= (OopT*)start_address(), "Address not in chunk");
return p - (OopT*)start_address();
}
diff --git a/src/hotspot/share/opto/callnode.cpp b/src/hotspot/share/opto/callnode.cpp
index 71f780577070c..6e75cf6710909 100644
--- a/src/hotspot/share/opto/callnode.cpp
+++ b/src/hotspot/share/opto/callnode.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -977,8 +977,8 @@ Node* CallNode::Ideal(PhaseGVN* phase, bool can_reshape) {
// Validate attached generator
CallGenerator* cg = generator();
if (cg != nullptr) {
- assert(is_CallStaticJava() && cg->is_mh_late_inline() ||
- is_CallDynamicJava() && cg->is_virtual_late_inline(), "mismatch");
+ assert((is_CallStaticJava() && cg->is_mh_late_inline()) ||
+ (is_CallDynamicJava() && cg->is_virtual_late_inline()), "mismatch");
}
#endif // ASSERT
return SafePointNode::Ideal(phase, can_reshape);
@@ -1638,8 +1638,8 @@ Node *AllocateArrayNode::make_ideal_length(const TypeOopPtr* oop_type, PhaseValu
// - the narrow_length is 0
// - the narrow_length is not wider than length
assert(narrow_length_type == TypeInt::ZERO ||
- length_type->is_con() && narrow_length_type->is_con() &&
- (narrow_length_type->_hi <= length_type->_lo) ||
+ (length_type->is_con() && narrow_length_type->is_con() &&
+ (narrow_length_type->_hi <= length_type->_lo)) ||
(narrow_length_type->_hi <= length_type->_hi &&
narrow_length_type->_lo >= length_type->_lo),
"narrow type must be narrower than length type");
@@ -1652,8 +1652,7 @@ Node *AllocateArrayNode::make_ideal_length(const TypeOopPtr* oop_type, PhaseValu
// propagate the fact that the array length must be positive.
InitializeNode* init = initialization();
if (init != nullptr) {
- length = new CastIINode(length, narrow_length_type);
- length->set_req(TypeFunc::Control, init->proj_out_or_null(TypeFunc::Control));
+ length = new CastIINode(init->proj_out_or_null(TypeFunc::Control), length, narrow_length_type);
}
}
}
diff --git a/src/hotspot/share/opto/castnode.cpp b/src/hotspot/share/opto/castnode.cpp
index ec34e5bdbe8d7..fd0d96cc79a2c 100644
--- a/src/hotspot/share/opto/castnode.cpp
+++ b/src/hotspot/share/opto/castnode.cpp
@@ -123,54 +123,12 @@ uint ConstraintCastNode::size_of() const {
return sizeof(*this);
}
-Node* ConstraintCastNode::make_cast(int opcode, Node* c, Node* n, const Type* t, DependencyType dependency,
- const TypeTuple* extra_types) {
- switch(opcode) {
- case Op_CastII: {
- Node* cast = new CastIINode(n, t, dependency, false, extra_types);
- cast->set_req(0, c);
- return cast;
- }
- case Op_CastLL: {
- Node* cast = new CastLLNode(n, t, dependency, extra_types);
- cast->set_req(0, c);
- return cast;
- }
- case Op_CastPP: {
- Node* cast = new CastPPNode(n, t, dependency, extra_types);
- cast->set_req(0, c);
- return cast;
- }
- case Op_CastFF: {
- Node* cast = new CastFFNode(n, t, dependency, extra_types);
- cast->set_req(0, c);
- return cast;
- }
- case Op_CastDD: {
- Node* cast = new CastDDNode(n, t, dependency, extra_types);
- cast->set_req(0, c);
- return cast;
- }
- case Op_CastVV: {
- Node* cast = new CastVVNode(n, t, dependency, extra_types);
- cast->set_req(0, c);
- return cast;
- }
- case Op_CheckCastPP: return new CheckCastPPNode(c, n, t, dependency, extra_types);
- default:
- fatal("Bad opcode %d", opcode);
- }
- return nullptr;
-}
-
-Node* ConstraintCastNode::make(Node* c, Node *n, const Type *t, DependencyType dependency, BasicType bt) {
+Node* ConstraintCastNode::make_cast_for_basic_type(Node* c, Node* n, const Type* t, DependencyType dependency, BasicType bt) {
switch(bt) {
- case T_INT: {
- return make_cast(Op_CastII, c, n, t, dependency, nullptr);
- }
- case T_LONG: {
- return make_cast(Op_CastLL, c, n, t, dependency, nullptr);
- }
+ case T_INT:
+ return new CastIINode(c, n, t, dependency);
+ case T_LONG:
+ return new CastLLNode(c, n, t, dependency);
default:
fatal("Bad basic type %s", type2name(bt));
}
@@ -267,7 +225,7 @@ const Type* CastIINode::Value(PhaseGVN* phase) const {
}
static Node* find_or_make_integer_cast(PhaseIterGVN* igvn, Node* parent, Node* control, const TypeInteger* type, ConstraintCastNode::DependencyType dependency, BasicType bt) {
- Node* n = ConstraintCastNode::make(control, parent, type, dependency, bt);
+ Node* n = ConstraintCastNode::make_cast_for_basic_type(control, parent, type, dependency, bt);
Node* existing = igvn->hash_find_insert(n);
if (existing != nullptr) {
n->destruct(igvn);
@@ -487,21 +445,20 @@ Node* CastP2XNode::Identity(PhaseGVN* phase) {
Node* ConstraintCastNode::make_cast_for_type(Node* c, Node* in, const Type* type, DependencyType dependency,
const TypeTuple* types) {
- Node* cast= nullptr;
if (type->isa_int()) {
- cast = make_cast(Op_CastII, c, in, type, dependency, types);
+ return new CastIINode(c, in, type, dependency, false, types);
} else if (type->isa_long()) {
- cast = make_cast(Op_CastLL, c, in, type, dependency, types);
+ return new CastLLNode(c, in, type, dependency, types);
} else if (type->isa_float()) {
- cast = make_cast(Op_CastFF, c, in, type, dependency, types);
+ return new CastFFNode(c, in, type, dependency, types);
} else if (type->isa_double()) {
- cast = make_cast(Op_CastDD, c, in, type, dependency, types);
+ return new CastDDNode(c, in, type, dependency, types);
} else if (type->isa_vect()) {
- cast = make_cast(Op_CastVV, c, in, type, dependency, types);
+ return new CastVVNode(c, in, type, dependency, types);
} else if (type->isa_ptr()) {
- cast = make_cast(Op_CastPP, c, in, type, dependency, types);
+ return new CastPPNode(c, in, type, dependency, types);
}
- return cast;
+ fatal("unreachable. Invalid cast type.");
}
Node* ConstraintCastNode::optimize_integer_cast(PhaseGVN* phase, BasicType bt) {
diff --git a/src/hotspot/share/opto/castnode.hpp b/src/hotspot/share/opto/castnode.hpp
index 82f54eb0289d5..32db08cb74829 100644
--- a/src/hotspot/share/opto/castnode.hpp
+++ b/src/hotspot/share/opto/castnode.hpp
@@ -54,10 +54,11 @@ class ConstraintCastNode: public TypeNode {
const TypeTuple* _extra_types;
public:
- ConstraintCastNode(Node* n, const Type* t, ConstraintCastNode::DependencyType dependency,
+ ConstraintCastNode(Node* ctrl, Node* n, const Type* t, ConstraintCastNode::DependencyType dependency,
const TypeTuple* extra_types)
: TypeNode(t,2), _dependency(dependency), _extra_types(extra_types) {
init_class_id(Class_ConstraintCast);
+ init_req(0, ctrl);
init_req(1, n);
}
virtual Node* Identity(PhaseGVN* phase);
@@ -68,8 +69,7 @@ class ConstraintCastNode: public TypeNode {
virtual bool depends_only_on_test() const { return _dependency == RegularDependency; }
bool carry_dependency() const { return _dependency != RegularDependency; }
TypeNode* dominating_cast(PhaseGVN* gvn, PhaseTransform* pt) const;
- static Node* make_cast(int opcode, Node* c, Node* n, const Type* t, DependencyType dependency, const TypeTuple* extra_types);
- static Node* make(Node* c, Node *n, const Type *t, DependencyType dependency, BasicType bt);
+ static Node* make_cast_for_basic_type(Node* c, Node* n, const Type* t, DependencyType dependency, BasicType bt);
#ifndef PRODUCT
virtual void dump_spec(outputStream *st) const;
@@ -102,13 +102,12 @@ class CastIINode: public ConstraintCastNode {
public:
CastIINode(Node* n, const Type* t, DependencyType dependency = RegularDependency, bool range_check_dependency = false, const TypeTuple* types = nullptr)
- : ConstraintCastNode(n, t, dependency, types), _range_check_dependency(range_check_dependency) {
+ : ConstraintCastNode(nullptr, n, t, dependency, types), _range_check_dependency(range_check_dependency) {
init_class_id(Class_CastII);
}
- CastIINode(Node* ctrl, Node* n, const Type* t, DependencyType dependency = RegularDependency, bool range_check_dependency = false)
- : ConstraintCastNode(n, t, dependency, nullptr), _range_check_dependency(range_check_dependency) {
+ CastIINode(Node* ctrl, Node* n, const Type* t, DependencyType dependency = RegularDependency, bool range_check_dependency = false, const TypeTuple* types = nullptr)
+ : ConstraintCastNode(ctrl, n, t, dependency, types), _range_check_dependency(range_check_dependency) {
init_class_id(Class_CastII);
- init_req(0, ctrl);
}
virtual int Opcode() const;
virtual uint ideal_reg() const { return Op_RegI; }
@@ -131,13 +130,8 @@ class CastIINode: public ConstraintCastNode {
class CastLLNode: public ConstraintCastNode {
public:
- CastLLNode(Node* ctrl, Node* n, const Type* t, DependencyType dependency = RegularDependency)
- : ConstraintCastNode(n, t, dependency, nullptr) {
- init_class_id(Class_CastLL);
- init_req(0, ctrl);
- }
- CastLLNode(Node* n, const Type* t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr)
- : ConstraintCastNode(n, t, dependency, types) {
+ CastLLNode(Node* ctrl, Node* n, const Type* t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr)
+ : ConstraintCastNode(ctrl, n, t, dependency, types) {
init_class_id(Class_CastLL);
}
@@ -149,8 +143,8 @@ class CastLLNode: public ConstraintCastNode {
class CastFFNode: public ConstraintCastNode {
public:
- CastFFNode(Node* n, const Type* t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr)
- : ConstraintCastNode(n, t, dependency, types) {
+ CastFFNode(Node* ctrl, Node* n, const Type* t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr)
+ : ConstraintCastNode(ctrl, n, t, dependency, types) {
init_class_id(Class_CastFF);
}
virtual int Opcode() const;
@@ -159,8 +153,8 @@ class CastFFNode: public ConstraintCastNode {
class CastDDNode: public ConstraintCastNode {
public:
- CastDDNode(Node* n, const Type* t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr)
- : ConstraintCastNode(n, t, dependency, types) {
+ CastDDNode(Node* ctrl, Node* n, const Type* t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr)
+ : ConstraintCastNode(ctrl, n, t, dependency, types) {
init_class_id(Class_CastDD);
}
virtual int Opcode() const;
@@ -169,8 +163,8 @@ class CastDDNode: public ConstraintCastNode {
class CastVVNode: public ConstraintCastNode {
public:
- CastVVNode(Node* n, const Type* t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr)
- : ConstraintCastNode(n, t, dependency, types) {
+ CastVVNode(Node* ctrl, Node* n, const Type* t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr)
+ : ConstraintCastNode(ctrl, n, t, dependency, types) {
init_class_id(Class_CastVV);
}
virtual int Opcode() const;
@@ -182,8 +176,8 @@ class CastVVNode: public ConstraintCastNode {
// cast pointer to pointer (different type)
class CastPPNode: public ConstraintCastNode {
public:
- CastPPNode (Node *n, const Type *t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr)
- : ConstraintCastNode(n, t, dependency, types) {
+ CastPPNode (Node* ctrl, Node* n, const Type* t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr)
+ : ConstraintCastNode(ctrl, n, t, dependency, types) {
}
virtual int Opcode() const;
virtual uint ideal_reg() const { return Op_RegP; }
@@ -193,10 +187,9 @@ class CastPPNode: public ConstraintCastNode {
// for _checkcast, cast pointer to pointer (different type), without JOIN,
class CheckCastPPNode: public ConstraintCastNode {
public:
- CheckCastPPNode(Node *c, Node *n, const Type *t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr)
- : ConstraintCastNode(n, t, dependency, types) {
+ CheckCastPPNode(Node* ctrl, Node* n, const Type* t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr)
+ : ConstraintCastNode(ctrl, n, t, dependency, types) {
init_class_id(Class_CheckCastPP);
- init_req(0, c);
}
virtual const Type* Value(PhaseGVN* phase) const;
diff --git a/src/hotspot/share/opto/cfgnode.cpp b/src/hotspot/share/opto/cfgnode.cpp
index 7bffd75d3f624..772e4050987f2 100644
--- a/src/hotspot/share/opto/cfgnode.cpp
+++ b/src/hotspot/share/opto/cfgnode.cpp
@@ -2148,8 +2148,7 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) {
if (phi_type->isa_ptr()) {
const Type* uin_type = phase->type(uin);
if (!phi_type->isa_oopptr() && !uin_type->isa_oopptr()) {
- cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, phi_type, ConstraintCastNode::StrongDependency,
- extra_types);
+ cast = new CastPPNode(r, uin, phi_type, ConstraintCastNode::StrongDependency, extra_types);
} else {
// Use a CastPP for a cast to not null and a CheckCastPP for
// a cast to a new klass (and both if both null-ness and
@@ -2159,8 +2158,7 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) {
// null, uin's type must be casted to not null
if (phi_type->join(TypePtr::NOTNULL) == phi_type->remove_speculative() &&
uin_type->join(TypePtr::NOTNULL) != uin_type->remove_speculative()) {
- cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, TypePtr::NOTNULL,
- ConstraintCastNode::StrongDependency, extra_types);
+ cast = new CastPPNode(r, uin, TypePtr::NOTNULL, ConstraintCastNode::StrongDependency, extra_types);
}
// If the type of phi and uin, both casted to not null,
@@ -2172,12 +2170,10 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) {
cast = phase->transform(cast);
n = cast;
}
- cast = ConstraintCastNode::make_cast(Op_CheckCastPP, r, n, phi_type, ConstraintCastNode::StrongDependency,
- extra_types);
+ cast = new CheckCastPPNode(r, uin, phi_type, ConstraintCastNode::StrongDependency, extra_types);
}
if (cast == nullptr) {
- cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, phi_type, ConstraintCastNode::StrongDependency,
- extra_types);
+ cast = new CastPPNode(r, uin, phi_type, ConstraintCastNode::StrongDependency, extra_types);
}
}
} else {
diff --git a/src/hotspot/share/opto/chaitin.hpp b/src/hotspot/share/opto/chaitin.hpp
index dd917571b0627..f01a849612588 100644
--- a/src/hotspot/share/opto/chaitin.hpp
+++ b/src/hotspot/share/opto/chaitin.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -163,8 +163,8 @@ class LRG : public ResourceObj {
bool is_scalable() {
#ifdef ASSERT
if (_is_scalable) {
- assert(_is_vector && (_num_regs == RegMask::SlotsPerVecA) ||
- _is_predicate && (_num_regs == RegMask::SlotsPerRegVectMask), "unexpected scalable reg");
+ assert((_is_vector && (_num_regs == RegMask::SlotsPerVecA)) ||
+ (_is_predicate && (_num_regs == RegMask::SlotsPerRegVectMask)), "unexpected scalable reg");
}
#endif
return Matcher::implements_scalable_vector && _is_scalable;
diff --git a/src/hotspot/share/opto/compile.cpp b/src/hotspot/share/opto/compile.cpp
index cbfa514239814..522654803aa19 100644
--- a/src/hotspot/share/opto/compile.cpp
+++ b/src/hotspot/share/opto/compile.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -3140,8 +3140,8 @@ void Compile::final_graph_reshaping_impl(Node *n, Final_Reshape_Counts& frc, Uni
int alias_idx = get_alias_index(n->as_Mem()->adr_type());
assert( n->in(0) != nullptr || alias_idx != Compile::AliasIdxRaw ||
// oop will be recorded in oop map if load crosses safepoint
- n->is_Load() && (n->as_Load()->bottom_type()->isa_oopptr() ||
- LoadNode::is_immutable_value(n->in(MemNode::Address))),
+ (n->is_Load() && (n->as_Load()->bottom_type()->isa_oopptr() ||
+ LoadNode::is_immutable_value(n->in(MemNode::Address)))),
"raw memory operations should have control edge");
}
if (n->is_MemBar()) {
@@ -4471,12 +4471,11 @@ Node* Compile::conv_I2X_index(PhaseGVN* phase, Node* idx, const TypeInt* sizetyp
Node* Compile::constrained_convI2L(PhaseGVN* phase, Node* value, const TypeInt* itype, Node* ctrl, bool carry_dependency) {
if (ctrl != nullptr) {
// Express control dependency by a CastII node with a narrow type.
- value = new CastIINode(value, itype, carry_dependency ? ConstraintCastNode::StrongDependency : ConstraintCastNode::RegularDependency, true /* range check dependency */);
// Make the CastII node dependent on the control input to prevent the narrowed ConvI2L
// node from floating above the range check during loop optimizations. Otherwise, the
// ConvI2L node may be eliminated independently of the range check, causing the data path
// to become TOP while the control path is still there (although it's unreachable).
- value->set_req(0, ctrl);
+ value = new CastIINode(ctrl, value, itype, carry_dependency ? ConstraintCastNode::StrongDependency : ConstraintCastNode::RegularDependency, true /* range check dependency */);
value = phase->transform(value);
}
const TypeLong* ltype = TypeLong::make(itype->_lo, itype->_hi, itype->_widen);
diff --git a/src/hotspot/share/opto/escape.cpp b/src/hotspot/share/opto/escape.cpp
index 514155c6af831..db99d6f6a98bb 100644
--- a/src/hotspot/share/opto/escape.cpp
+++ b/src/hotspot/share/opto/escape.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1121,7 +1121,7 @@ void ConnectionGraph::add_final_edges(Node *n) {
return;
}
assert(n->is_Store() || n->is_LoadStore() ||
- (n_ptn != nullptr) && (n_ptn->ideal_node() != nullptr),
+ ((n_ptn != nullptr) && (n_ptn->ideal_node() != nullptr)),
"node should be registered already");
int opcode = n->Opcode();
bool gc_handled = BarrierSet::barrier_set()->barrier_set_c2()->escape_add_final_edges(this, _igvn, n, opcode);
@@ -3856,7 +3856,7 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist,
record_for_optimizer(n);
} else {
assert(tn_type == TypePtr::NULL_PTR ||
- tn_t != nullptr && !tinst->maybe_java_subtype_of(tn_t),
+ (tn_t != nullptr && !tinst->maybe_java_subtype_of(tn_t)),
"unexpected type");
continue; // Skip dead path with different type
}
diff --git a/src/hotspot/share/opto/graphKit.cpp b/src/hotspot/share/opto/graphKit.cpp
index 0e9fefdc8a74c..2389121528105 100644
--- a/src/hotspot/share/opto/graphKit.cpp
+++ b/src/hotspot/share/opto/graphKit.cpp
@@ -1439,8 +1439,7 @@ Node* GraphKit::cast_not_null(Node* obj, bool do_replace_in_map) {
// Object is already not-null?
if( t == t_not_null ) return obj;
- Node *cast = new CastPPNode(obj,t_not_null);
- cast->init_req(0, control());
+ Node* cast = new CastPPNode(control(), obj,t_not_null);
cast = _gvn.transform( cast );
// Scan for instances of 'obj' in the current JVM mapping.
diff --git a/src/hotspot/share/opto/lcm.cpp b/src/hotspot/share/opto/lcm.cpp
index 61e8946ed3994..549290397e3b7 100644
--- a/src/hotspot/share/opto/lcm.cpp
+++ b/src/hotspot/share/opto/lcm.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -150,8 +150,9 @@ void PhaseCFG::implicit_null_check(Block* block, Node *proj, Node *val, int allo
bool is_decoden = ((intptr_t)val) & 1;
val = (Node*)(((intptr_t)val) & ~1);
- assert(!is_decoden || (val->in(0) == nullptr) && val->is_Mach() &&
- (val->as_Mach()->ideal_Opcode() == Op_DecodeN), "sanity");
+ assert(!is_decoden ||
+ ((val->in(0) == nullptr) && val->is_Mach() &&
+ (val->as_Mach()->ideal_Opcode() == Op_DecodeN)), "sanity");
// Search the successor block for a load or store who's base value is also
// the tested value. There may be several.
diff --git a/src/hotspot/share/opto/library_call.cpp b/src/hotspot/share/opto/library_call.cpp
index e8923d3d13495..2bc1cc261c6c6 100644
--- a/src/hotspot/share/opto/library_call.cpp
+++ b/src/hotspot/share/opto/library_call.cpp
@@ -873,8 +873,7 @@ inline Node* LibraryCallKit::generate_negative_guard(Node* index, RegionNode* re
Node* is_neg = generate_guard(bol_lt, region, PROB_MIN);
if (is_neg != nullptr && pos_index != nullptr) {
// Emulate effect of Parse::adjust_map_after_if.
- Node* ccast = new CastIINode(index, TypeInt::POS);
- ccast->set_req(0, control());
+ Node* ccast = new CastIINode(control(), index, TypeInt::POS);
(*pos_index) = _gvn.transform(ccast);
}
return is_neg;
@@ -1141,7 +1140,9 @@ bool LibraryCallKit::inline_preconditions_checkIndex(BasicType bt) {
// length is now known positive, add a cast node to make this explicit
jlong upper_bound = _gvn.type(length)->is_integer(bt)->hi_as_long();
- Node* casted_length = ConstraintCastNode::make(control(), length, TypeInteger::make(0, upper_bound, Type::WidenMax, bt), ConstraintCastNode::RegularDependency, bt);
+ Node* casted_length = ConstraintCastNode::make_cast_for_basic_type(
+ control(), length, TypeInteger::make(0, upper_bound, Type::WidenMax, bt),
+ ConstraintCastNode::RegularDependency, bt);
casted_length = _gvn.transform(casted_length);
replace_in_map(length, casted_length);
length = casted_length;
@@ -1169,7 +1170,9 @@ bool LibraryCallKit::inline_preconditions_checkIndex(BasicType bt) {
}
// index is now known to be >= 0 and < length, cast it
- Node* result = ConstraintCastNode::make(control(), index, TypeInteger::make(0, upper_bound, Type::WidenMax, bt), ConstraintCastNode::RegularDependency, bt);
+ Node* result = ConstraintCastNode::make_cast_for_basic_type(
+ control(), index, TypeInteger::make(0, upper_bound, Type::WidenMax, bt),
+ ConstraintCastNode::RegularDependency, bt);
result = _gvn.transform(result);
set_result(result);
replace_in_map(index, result);
@@ -4312,8 +4315,7 @@ bool LibraryCallKit::inline_array_copyOf(bool is_copyOfRange) {
// Improve the klass node's type from the new optimistic assumption:
ciKlass* ak = ciArrayKlass::make(env()->Object_klass());
const Type* akls = TypeKlassPtr::make(TypePtr::NotNull, ak, 0/*offset*/);
- Node* cast = new CastPPNode(klass_node, akls);
- cast->init_req(0, control());
+ Node* cast = new CastPPNode(control(), klass_node, akls);
klass_node = _gvn.transform(cast);
}
@@ -5940,8 +5942,7 @@ bool LibraryCallKit::inline_multiplyToLen() {
} __ else_(); {
// Update graphKit memory and control from IdealKit.
sync_kit(ideal);
- Node *cast = new CastPPNode(z, TypePtr::NOTNULL);
- cast->init_req(0, control());
+ Node* cast = new CastPPNode(control(), z, TypePtr::NOTNULL);
_gvn.set_type(cast, cast->bottom_type());
C->record_for_igvn(cast);
diff --git a/src/hotspot/share/opto/loopPredicate.cpp b/src/hotspot/share/opto/loopPredicate.cpp
index e4f6345c6794f..6a8efb0872a5b 100644
--- a/src/hotspot/share/opto/loopPredicate.cpp
+++ b/src/hotspot/share/opto/loopPredicate.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -797,7 +797,8 @@ BoolNode* PhaseIdealLoop::rc_predicate(IdealLoopTree* loop, Node* ctrl, int scal
overflow = false;
Node* max_idx_expr = nullptr;
const TypeInt* idx_type = TypeInt::INT;
- if ((stride > 0) == (scale > 0) == upper) {
+ // same signs and upper, or different signs and not upper.
+ if (((stride > 0) == (scale > 0)) == upper) {
guarantee(limit != nullptr, "sanity");
if (TraceLoopPredicate) {
if (limit->is_Con()) {
diff --git a/src/hotspot/share/opto/loopTransform.cpp b/src/hotspot/share/opto/loopTransform.cpp
index 3c323d7a2dc4c..3d3e7bdaa7c7b 100644
--- a/src/hotspot/share/opto/loopTransform.cpp
+++ b/src/hotspot/share/opto/loopTransform.cpp
@@ -1284,8 +1284,7 @@ Node *PhaseIdealLoop::clone_up_backedge_goo(Node *back_ctrl, Node *preheader_ctr
}
Node* PhaseIdealLoop::cast_incr_before_loop(Node* incr, Node* ctrl, Node* loop) {
- Node* castii = new CastIINode(incr, TypeInt::INT, ConstraintCastNode::UnconditionalDependency);
- castii->set_req(0, ctrl);
+ Node* castii = new CastIINode(ctrl, incr, TypeInt::INT, ConstraintCastNode::UnconditionalDependency);
register_new_node(castii, ctrl);
for (DUIterator_Fast imax, i = incr->fast_outs(imax); i < imax; i++) {
Node* n = incr->fast_out(i);
@@ -3161,9 +3160,8 @@ void PhaseIdealLoop::do_range_check(IdealLoopTree *loop, Node_List &old_new) {
// The new loop limit is <= (for an upward loop) >= (for a downward loop) than the orig limit.
// The expression that computes the new limit may be too complicated and the computed type of the new limit
// may be too pessimistic. A CastII here guarantees it's not lost.
- main_limit = new CastIINode(main_limit, TypeInt::make(upward ? min_jint : orig_limit_t->_lo,
+ main_limit = new CastIINode(pre_ctrl, main_limit, TypeInt::make(upward ? min_jint : orig_limit_t->_lo,
upward ? orig_limit_t->_hi : max_jint, Type::WidenMax));
- main_limit->init_req(0, pre_ctrl);
register_new_node(main_limit, pre_ctrl);
// Hack the now-private loop bounds
_igvn.replace_input_of(main_cmp, 2, main_limit);
@@ -3422,7 +3420,10 @@ bool IdealLoopTree::do_remove_empty_loop(PhaseIdealLoop *phase) {
Node* exact_limit = phase->exact_limit(this);
// We need to pin the exact limit to prevent it from floating above the zero trip guard.
- Node* cast_ii = ConstraintCastNode::make(cl->in(LoopNode::EntryControl), exact_limit, phase->_igvn.type(exact_limit), ConstraintCastNode::UnconditionalDependency, T_INT);
+ Node* cast_ii = ConstraintCastNode::make_cast_for_basic_type(
+ cl->in(LoopNode::EntryControl), exact_limit,
+ phase->_igvn.type(exact_limit),
+ ConstraintCastNode::UnconditionalDependency, T_INT);
phase->register_new_node(cast_ii, cl->in(LoopNode::EntryControl));
Node* final_iv = new SubINode(cast_ii, cl->stride());
diff --git a/src/hotspot/share/opto/memnode.cpp b/src/hotspot/share/opto/memnode.cpp
index c402a240acbed..4f2110bfb4cd0 100644
--- a/src/hotspot/share/opto/memnode.cpp
+++ b/src/hotspot/share/opto/memnode.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -4955,7 +4955,7 @@ static void verify_memory_slice(const MergeMemNode* m, int alias_idx, Node* n) {
//-----------------------------memory_at---------------------------------------
Node* MergeMemNode::memory_at(uint alias_idx) const {
assert(alias_idx >= Compile::AliasIdxRaw ||
- alias_idx == Compile::AliasIdxBot && !Compile::current()->do_aliasing(),
+ (alias_idx == Compile::AliasIdxBot && !Compile::current()->do_aliasing()),
"must avoid base_memory and AliasIdxTop");
// Otherwise, it is a narrow slice.
diff --git a/src/hotspot/share/opto/memnode.hpp b/src/hotspot/share/opto/memnode.hpp
index 85f4380188db9..3a521c8f63365 100644
--- a/src/hotspot/share/opto/memnode.hpp
+++ b/src/hotspot/share/opto/memnode.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -788,7 +788,7 @@ class StoreCMNode : public StoreNode {
StoreNode(c, mem, adr, at, val, oop_store, MemNode::release),
_oop_alias_idx(oop_alias_idx) {
assert(_oop_alias_idx >= Compile::AliasIdxRaw ||
- _oop_alias_idx == Compile::AliasIdxBot && !Compile::current()->do_aliasing(),
+ (_oop_alias_idx == Compile::AliasIdxBot && !Compile::current()->do_aliasing()),
"bad oop alias idx");
}
virtual int Opcode() const;
diff --git a/src/hotspot/share/opto/node.hpp b/src/hotspot/share/opto/node.hpp
index 0541409a31269..7e9c5196942fb 100644
--- a/src/hotspot/share/opto/node.hpp
+++ b/src/hotspot/share/opto/node.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -448,7 +448,7 @@ class Node {
}
// Light version of set_req() to init inputs after node creation.
void init_req( uint i, Node *n ) {
- assert( i == 0 && this == n ||
+ assert( (i == 0 && this == n) ||
is_not_dead(n), "can not use dead node");
assert( i < _cnt, "oob");
assert( !VerifyHashTableKeys || _hash_lock == 0,
diff --git a/src/hotspot/share/opto/parse2.cpp b/src/hotspot/share/opto/parse2.cpp
index 1528615987bb7..0c22409aeee08 100644
--- a/src/hotspot/share/opto/parse2.cpp
+++ b/src/hotspot/share/opto/parse2.cpp
@@ -1730,10 +1730,10 @@ void Parse::sharpen_type_after_if(BoolTest::mask btest,
const Type* tboth = tcon->join_speculative(tval);
if (tboth == tval) break; // Nothing to gain.
if (tcon->isa_int()) {
- ccast = new CastIINode(val, tboth);
+ ccast = new CastIINode(control(), val, tboth);
} else if (tcon == TypePtr::NULL_PTR) {
// Cast to null, but keep the pointer identity temporarily live.
- ccast = new CastPPNode(val, tboth);
+ ccast = new CastPPNode(control(), val, tboth);
} else {
const TypeF* tf = tcon->isa_float_constant();
const TypeD* td = tcon->isa_double_constant();
@@ -1764,7 +1764,6 @@ void Parse::sharpen_type_after_if(BoolTest::mask btest,
assert(tcc != tval && tcc->higher_equal(tval), "must improve");
// Delay transform() call to allow recovery of pre-cast value
// at the control merge.
- ccast->set_req(0, control());
_gvn.set_type_bottom(ccast);
record_for_igvn(ccast);
cast = ccast;
diff --git a/src/hotspot/share/opto/phaseX.cpp b/src/hotspot/share/opto/phaseX.cpp
index 46d76258eb4f3..c791146f75769 100644
--- a/src/hotspot/share/opto/phaseX.cpp
+++ b/src/hotspot/share/opto/phaseX.cpp
@@ -685,7 +685,7 @@ Node* PhaseGVN::transform(Node* n) {
k = i;
#ifdef ASSERT
if (loop_count >= K + C->live_nodes()) {
- dump_infinite_loop_info(i, "PhaseGVN::transform_no_reclaim");
+ dump_infinite_loop_info(i, "PhaseGVN::transform");
}
#endif
i = apply_ideal(k, /*can_reshape=*/false);
diff --git a/src/hotspot/share/opto/vector.cpp b/src/hotspot/share/opto/vector.cpp
index 1c2c9d982b5b7..641e7ebcde8f6 100644
--- a/src/hotspot/share/opto/vector.cpp
+++ b/src/hotspot/share/opto/vector.cpp
@@ -488,7 +488,7 @@ void PhaseVector::expand_vunbox_node(VectorUnboxNode* vec_unbox) {
// For proper aliasing, attach concrete payload type.
ciKlass* payload_klass = ciTypeArrayKlass::make(bt);
const Type* payload_type = TypeAryPtr::make_from_klass(payload_klass)->cast_to_ptr_type(TypePtr::NotNull);
- vec_field_ld = gvn.transform(new CastPPNode(vec_field_ld, payload_type));
+ vec_field_ld = gvn.transform(new CastPPNode(nullptr, vec_field_ld, payload_type));
Node* adr = kit.array_element_address(vec_field_ld, gvn.intcon(0), bt);
const TypePtr* adr_type = adr->bottom_type()->is_ptr();
diff --git a/src/hotspot/share/prims/foreignGlobals.cpp b/src/hotspot/share/prims/foreignGlobals.cpp
index f3653d29886f9..11b0b8ace7cb7 100644
--- a/src/hotspot/share/prims/foreignGlobals.cpp
+++ b/src/hotspot/share/prims/foreignGlobals.cpp
@@ -140,7 +140,7 @@ int ForeignGlobals::compute_out_arg_bytes(const GrowableArray& out_re
int ForeignGlobals::java_calling_convention(const BasicType* signature, int num_args, GrowableArray& out_regs) {
VMRegPair* vm_regs = NEW_RESOURCE_ARRAY(VMRegPair, num_args);
- int slots = SharedRuntime::java_calling_convention(signature, vm_regs, num_args);
+ int slots = align_up(SharedRuntime::java_calling_convention(signature, vm_regs, num_args), 2);
for (int i = 0; i < num_args; i++) {
VMRegPair pair = vm_regs[i];
// note, we ignore second here. Signature should consist of register-size values. So there should be
diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp
index bd6eda2d4681a..9a8a9a5bec0b0 100644
--- a/src/hotspot/share/prims/jvm.cpp
+++ b/src/hotspot/share/prims/jvm.cpp
@@ -3933,8 +3933,6 @@ JVM_ENTRY(void, JVM_VirtualThreadStart(JNIEnv* env, jobject vthread))
// set VTMS transition bit value in JavaThread and java.lang.VirtualThread object
JvmtiVTMSTransitionDisabler::set_is_in_VTMS_transition(thread, vthread, false);
}
-#else
- fatal("Should only be called with JVMTI enabled");
#endif
JVM_END
@@ -3950,8 +3948,6 @@ JVM_ENTRY(void, JVM_VirtualThreadEnd(JNIEnv* env, jobject vthread))
// set VTMS transition bit value in JavaThread and java.lang.VirtualThread object
JvmtiVTMSTransitionDisabler::set_is_in_VTMS_transition(thread, vthread, true);
}
-#else
- fatal("Should only be called with JVMTI enabled");
#endif
JVM_END
@@ -3969,8 +3965,6 @@ JVM_ENTRY(void, JVM_VirtualThreadMount(JNIEnv* env, jobject vthread, jboolean hi
// set VTMS transition bit value in JavaThread and java.lang.VirtualThread object
JvmtiVTMSTransitionDisabler::set_is_in_VTMS_transition(thread, vthread, hide);
}
-#else
- fatal("Should only be called with JVMTI enabled");
#endif
JVM_END
@@ -3988,8 +3982,6 @@ JVM_ENTRY(void, JVM_VirtualThreadUnmount(JNIEnv* env, jobject vthread, jboolean
// set VTMS transition bit value in JavaThread and java.lang.VirtualThread object
JvmtiVTMSTransitionDisabler::set_is_in_VTMS_transition(thread, vthread, hide);
}
-#else
- fatal("Should only be called with JVMTI enabled");
#endif
JVM_END
@@ -4003,8 +3995,6 @@ JVM_ENTRY(void, JVM_VirtualThreadHideFrames(JNIEnv* env, jobject vthread, jboole
assert(!thread->is_in_VTMS_transition(), "sanity check");
assert(thread->is_in_tmp_VTMS_transition() != (bool)hide, "sanity check");
thread->toggle_is_in_tmp_VTMS_transition();
-#else
- fatal("Should only be called with JVMTI enabled");
#endif
JVM_END
@@ -4019,8 +4009,6 @@ JVM_ENTRY(void, JVM_VirtualThreadDisableSuspend(JNIEnv* env, jobject vthread, jb
assert(thread->is_disable_suspend() != (bool)enter,
"nested or unbalanced monitor enter/exit is not allowed");
thread->toggle_is_disable_suspend();
-#else
- fatal("Should only be called with JVMTI enabled");
#endif
JVM_END
diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp
index df466acdcfa31..7dae2cce16ea2 100644
--- a/src/hotspot/share/runtime/arguments.cpp
+++ b/src/hotspot/share/runtime/arguments.cpp
@@ -525,6 +525,7 @@ static SpecialFlag const special_jvm_flags[] = {
{ "RefDiscoveryPolicy", JDK_Version::undefined(), JDK_Version::jdk(21), JDK_Version::undefined() },
{ "MetaspaceReclaimPolicy", JDK_Version::undefined(), JDK_Version::jdk(21), JDK_Version::undefined() },
+ { "AdaptiveSizePolicyCollectionCostMargin", JDK_Version::undefined(), JDK_Version::jdk(23), JDK_Version::jdk(24) },
#ifdef ASSERT
{ "DummyObsoleteTestFlag", JDK_Version::undefined(), JDK_Version::jdk(18), JDK_Version::undefined() },
#endif
@@ -2214,10 +2215,6 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* patch_m
// -bootclasspath/a:
} else if (match_option(option, "-Xbootclasspath/a:", &tail)) {
Arguments::append_sysclasspath(tail);
-#if INCLUDE_CDS
- MetaspaceShared::disable_optimized_module_handling();
- log_info(cds)("optimized module handling: disabled because bootclasspath was appended");
-#endif
// -bootclasspath/p:
} else if (match_option(option, "-Xbootclasspath/p:", &tail)) {
jio_fprintf(defaultStream::output_stream(),
diff --git a/src/hotspot/share/runtime/continuationFreezeThaw.cpp b/src/hotspot/share/runtime/continuationFreezeThaw.cpp
index fe1dfc62ee48d..969e14f150e17 100644
--- a/src/hotspot/share/runtime/continuationFreezeThaw.cpp
+++ b/src/hotspot/share/runtime/continuationFreezeThaw.cpp
@@ -1775,7 +1775,7 @@ class ThawBase : public StackObj {
inline void before_thaw_java_frame(const frame& hf, const frame& caller, bool bottom, int num_frame);
inline void after_thaw_java_frame(const frame& f, bool bottom);
inline void patch(frame& f, const frame& caller, bool bottom);
- void clear_bitmap_bits(intptr_t* start, int range);
+ void clear_bitmap_bits(address start, address end);
NOINLINE void recurse_thaw_interpreted_frame(const frame& hf, frame& caller, int num_frames);
void recurse_thaw_compiled_frame(const frame& hf, frame& caller, int num_frames, bool stub_caller);
@@ -2166,13 +2166,22 @@ inline void ThawBase::patch(frame& f, const frame& caller, bool bottom) {
assert(!bottom || (_cont.is_empty() != Continuation::is_cont_barrier_frame(f)), "");
}
-void ThawBase::clear_bitmap_bits(intptr_t* start, int range) {
+void ThawBase::clear_bitmap_bits(address start, address end) {
+ assert(is_aligned(start, wordSize), "should be aligned: " PTR_FORMAT, p2i(start));
+ assert(is_aligned(end, VMRegImpl::stack_slot_size), "should be aligned: " PTR_FORMAT, p2i(end));
+
// we need to clear the bits that correspond to arguments as they reside in the caller frame
- // or they will keep objects that are otherwise unreachable alive
- log_develop_trace(continuations)("clearing bitmap for " INTPTR_FORMAT " - " INTPTR_FORMAT, p2i(start), p2i(start+range));
+ // or they will keep objects that are otherwise unreachable alive.
+
+ // Align `end` if UseCompressedOops is not set to avoid UB when calculating the bit index, since
+ // `end` could be at an odd number of stack slots from `start`, i.e might not be oop aligned.
+ // If that's the case the bit range corresponding to the last stack slot should not have bits set
+ // anyways and we assert that before returning.
+ address effective_end = UseCompressedOops ? end : align_down(end, wordSize);
+ log_develop_trace(continuations)("clearing bitmap for " INTPTR_FORMAT " - " INTPTR_FORMAT, p2i(start), p2i(effective_end));
stackChunkOop chunk = _cont.tail();
- chunk->bitmap().clear_range(chunk->bit_index_for(start),
- chunk->bit_index_for(start+range));
+ chunk->bitmap().clear_range(chunk->bit_index_for(start), chunk->bit_index_for(effective_end));
+ assert(chunk->bitmap().count_one_bits(chunk->bit_index_for(effective_end), chunk->bit_index_for(end)) == 0, "bits should not be set");
}
NOINLINE void ThawBase::recurse_thaw_interpreted_frame(const frame& hf, frame& caller, int num_frames) {
@@ -2225,7 +2234,9 @@ NOINLINE void ThawBase::recurse_thaw_interpreted_frame(const frame& hf, frame& c
_cont.tail()->fix_thawed_frame(caller, SmallRegisterMap::instance);
} else if (_cont.tail()->has_bitmap() && locals > 0) {
assert(hf.is_heap_frame(), "should be");
- clear_bitmap_bits(heap_frame_bottom - locals, locals);
+ address start = (address)(heap_frame_bottom - locals);
+ address end = (address)heap_frame_bottom;
+ clear_bitmap_bits(start, end);
}
DEBUG_ONLY(after_thaw_java_frame(f, is_bottom_frame);)
@@ -2298,7 +2309,10 @@ void ThawBase::recurse_thaw_compiled_frame(const frame& hf, frame& caller, int n
// can only fix caller once this frame is thawed (due to callee saved regs); this happens on the stack
_cont.tail()->fix_thawed_frame(caller, SmallRegisterMap::instance);
} else if (_cont.tail()->has_bitmap() && added_argsize > 0) {
- clear_bitmap_bits(heap_frame_top + ContinuationHelper::CompiledFrame::size(hf) + frame::metadata_words_at_top, added_argsize);
+ address start = (address)(heap_frame_top + ContinuationHelper::CompiledFrame::size(hf) + frame::metadata_words_at_top);
+ int stack_args_slots = f.cb()->as_compiled_method()->method()->num_stack_arg_slots(false /* rounded */);
+ int argsize_in_bytes = stack_args_slots * VMRegImpl::stack_slot_size;
+ clear_bitmap_bits(start, start + argsize_in_bytes);
}
DEBUG_ONLY(after_thaw_java_frame(f, is_bottom_frame);)
diff --git a/src/hotspot/share/runtime/frame.cpp b/src/hotspot/share/runtime/frame.cpp
index f4893bae5db95..c68180e105b7a 100644
--- a/src/hotspot/share/runtime/frame.cpp
+++ b/src/hotspot/share/runtime/frame.cpp
@@ -1439,7 +1439,7 @@ void frame::describe(FrameValues& values, int frame_no, const RegisterMap* reg_m
assert(sig_index == sizeargs, "");
}
int stack_arg_slots = SharedRuntime::java_calling_convention(sig_bt, regs, sizeargs);
- assert(stack_arg_slots == m->num_stack_arg_slots(), "");
+ assert(stack_arg_slots == m->num_stack_arg_slots(false /* rounded */), "");
int out_preserve = SharedRuntime::out_preserve_stack_slots();
int sig_index = 0;
int arg_index = (m->is_static() ? 0 : -1);
diff --git a/src/hotspot/share/runtime/globals.hpp b/src/hotspot/share/runtime/globals.hpp
index b5ede76434a0b..af1c82b77146b 100644
--- a/src/hotspot/share/runtime/globals.hpp
+++ b/src/hotspot/share/runtime/globals.hpp
@@ -546,10 +546,17 @@ const int ObjectAlignmentInBytes = 8;
"thrown from JVM") \
\
product(bool, HeapDumpBeforeFullGC, false, MANAGEABLE, \
- "Dump heap to file before any major stop-the-world GC") \
+ "Dump heap to file before any major stop-the-world GC " \
+ "(also see FullGCHeapDumpLimit)") \
\
product(bool, HeapDumpAfterFullGC, false, MANAGEABLE, \
- "Dump heap to file after any major stop-the-world GC") \
+ "Dump heap to file after any major stop-the-world GC " \
+ "(also see FullGCHeapDumpLimit)") \
+ \
+ product(uint, FullGCHeapDumpLimit, 0, MANAGEABLE, \
+ "Limit the number of heap dumps triggered by " \
+ "HeapDumpBeforeFullGC or HeapDumpAfterFullGC " \
+ "(0 means no limit)") \
\
product(bool, HeapDumpOnOutOfMemoryError, false, MANAGEABLE, \
"Dump heap to file when java.lang.OutOfMemoryError is thrown " \
diff --git a/src/hotspot/share/runtime/mutex.hpp b/src/hotspot/share/runtime/mutex.hpp
index 3f38bcd5ed551..10671d651b100 100644
--- a/src/hotspot/share/runtime/mutex.hpp
+++ b/src/hotspot/share/runtime/mutex.hpp
@@ -221,7 +221,7 @@ class Monitor : public Mutex {
class PaddedMutex : public Mutex {
enum {
- CACHE_LINE_PADDING = (int)DEFAULT_CACHE_LINE_SIZE - (int)sizeof(Mutex),
+ CACHE_LINE_PADDING = (int)DEFAULT_PADDING_SIZE - (int)sizeof(Mutex),
PADDING_LEN = CACHE_LINE_PADDING > 0 ? CACHE_LINE_PADDING : 1
};
char _padding[PADDING_LEN];
@@ -232,7 +232,7 @@ class PaddedMutex : public Mutex {
class PaddedMonitor : public Monitor {
enum {
- CACHE_LINE_PADDING = (int)DEFAULT_CACHE_LINE_SIZE - (int)sizeof(Monitor),
+ CACHE_LINE_PADDING = (int)DEFAULT_PADDING_SIZE - (int)sizeof(Monitor),
PADDING_LEN = CACHE_LINE_PADDING > 0 ? CACHE_LINE_PADDING : 1
};
char _padding[PADDING_LEN];
diff --git a/src/hotspot/share/runtime/objectMonitor.hpp b/src/hotspot/share/runtime/objectMonitor.hpp
index fc15e20309f77..ab48bd19b5e43 100644
--- a/src/hotspot/share/runtime/objectMonitor.hpp
+++ b/src/hotspot/share/runtime/objectMonitor.hpp
@@ -121,11 +121,7 @@ class ObjectWaiter : public StackObj {
// intptr_t. There's no reason to use a 64-bit type for this field
// in a 64-bit JVM.
-#ifndef OM_CACHE_LINE_SIZE
-// Use DEFAULT_CACHE_LINE_SIZE if not already specified for
-// the current build platform.
#define OM_CACHE_LINE_SIZE DEFAULT_CACHE_LINE_SIZE
-#endif
class ObjectMonitor : public CHeapObj {
friend class ObjectSynchronizer;
diff --git a/src/hotspot/share/runtime/os.hpp b/src/hotspot/share/runtime/os.hpp
index 094fd2509a05b..8ecabde8ca144 100644
--- a/src/hotspot/share/runtime/os.hpp
+++ b/src/hotspot/share/runtime/os.hpp
@@ -531,7 +531,6 @@ class os: AllStatic {
static void large_page_init();
static size_t large_page_size();
static bool can_commit_large_page_memory();
- static bool can_execute_large_page_memory();
// Check if pointer points to readable memory (by 4-byte read access)
static bool is_readable_pointer(const void* p);
diff --git a/src/hotspot/share/runtime/sharedRuntime.cpp b/src/hotspot/share/runtime/sharedRuntime.cpp
index 9d582b790a15a..94d42622c81e6 100644
--- a/src/hotspot/share/runtime/sharedRuntime.cpp
+++ b/src/hotspot/share/runtime/sharedRuntime.cpp
@@ -2004,7 +2004,7 @@ void SharedRuntime::check_member_name_argument_is_last_argument(const methodHand
assert(member_arg_pos >= 0 && member_arg_pos < total_args_passed, "oob");
assert(sig_bt[member_arg_pos] == T_OBJECT, "dispatch argument must be an object");
- int comp_args_on_stack = java_calling_convention(sig_bt, regs_without_member_name, total_args_passed - 1);
+ java_calling_convention(sig_bt, regs_without_member_name, total_args_passed - 1);
for (int i = 0; i < member_arg_pos; i++) {
VMReg a = regs_with_member_name[i].first();
@@ -3102,7 +3102,7 @@ void AdapterHandlerLibrary::create_native_wrapper(const methodHandle& method) {
BasicType ret_type = si.return_type();
// Now get the compiled-Java arguments layout.
- int comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed);
+ SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed);
// Generate the compiled-to-native wrapper code
nm = SharedRuntime::generate_native_wrapper(&_masm, method, compile_id, sig_bt, regs, ret_type);
diff --git a/src/hotspot/share/runtime/signature.cpp b/src/hotspot/share/runtime/signature.cpp
index b085bf5fd0514..081bdd2e0d399 100644
--- a/src/hotspot/share/runtime/signature.cpp
+++ b/src/hotspot/share/runtime/signature.cpp
@@ -178,7 +178,6 @@ void Fingerprinter::compute_fingerprint_and_return_type(bool static_flag) {
}
#if defined(_LP64) && !defined(ZERO)
- _stack_arg_slots = align_up(_stack_arg_slots, 2);
#ifdef ASSERT
int dbg_stack_arg_slots = compute_num_stack_arg_slots(_signature, _param_size, static_flag);
assert(_stack_arg_slots == dbg_stack_arg_slots, "fingerprinter: %d full: %d", _stack_arg_slots, dbg_stack_arg_slots);
@@ -235,14 +234,17 @@ void Fingerprinter::do_type_calling_convention(BasicType type) {
case T_BYTE:
case T_SHORT:
case T_INT:
-#if defined(PPC64) || defined(S390)
if (_int_args < Argument::n_int_register_parameters_j) {
_int_args++;
} else {
+#if defined(PPC64) || defined(S390)
+ _stack_arg_slots += 1;
+#else
+ _stack_arg_slots = align_up(_stack_arg_slots, 2);
_stack_arg_slots += 1;
+#endif // defined(PPC64) || defined(S390)
}
break;
-#endif // defined(PPC64) || defined(S390)
case T_LONG:
case T_OBJECT:
case T_ARRAY:
@@ -250,26 +252,27 @@ void Fingerprinter::do_type_calling_convention(BasicType type) {
if (_int_args < Argument::n_int_register_parameters_j) {
_int_args++;
} else {
- PPC64_ONLY(_stack_arg_slots = align_up(_stack_arg_slots, 2));
- S390_ONLY(_stack_arg_slots = align_up(_stack_arg_slots, 2));
+ _stack_arg_slots = align_up(_stack_arg_slots, 2);
_stack_arg_slots += 2;
}
break;
case T_FLOAT:
-#if defined(PPC64) || defined(S390)
if (_fp_args < Argument::n_float_register_parameters_j) {
_fp_args++;
} else {
+#if defined(PPC64) || defined(S390)
+ _stack_arg_slots += 1;
+#else
+ _stack_arg_slots = align_up(_stack_arg_slots, 2);
_stack_arg_slots += 1;
+#endif // defined(PPC64) || defined(S390)
}
break;
-#endif // defined(PPC64) || defined(S390)
case T_DOUBLE:
if (_fp_args < Argument::n_float_register_parameters_j) {
_fp_args++;
} else {
- PPC64_ONLY(_stack_arg_slots = align_up(_stack_arg_slots, 2));
- S390_ONLY(_stack_arg_slots = align_up(_stack_arg_slots, 2));
+ _stack_arg_slots = align_up(_stack_arg_slots, 2);
_stack_arg_slots += 2;
}
break;
diff --git a/src/hotspot/share/runtime/trimNativeHeap.cpp b/src/hotspot/share/runtime/trimNativeHeap.cpp
index 3592d39093861..ca9f74a04ed2a 100644
--- a/src/hotspot/share/runtime/trimNativeHeap.cpp
+++ b/src/hotspot/share/runtime/trimNativeHeap.cpp
@@ -71,11 +71,6 @@ class NativeHeapTrimmerThread : public NamedThread {
return --_suspend_count;
}
- bool is_stopped() const {
- assert(_lock->is_locked(), "Must be");
- return _stop;
- }
-
bool at_or_nearing_safepoint() const {
return SafepointSynchronize::is_at_safepoint() ||
SafepointSynchronize::is_synchronizing();
@@ -215,13 +210,12 @@ class NativeHeapTrimmerThread : public NamedThread {
}
void print_state(outputStream* st) const {
- // Don't pull lock during error reporting
- Mutex* const lock = VMError::is_error_reported() ? nullptr : _lock;
int64_t num_trims = 0;
bool stopped = false;
uint16_t suspenders = 0;
{
- MutexLocker ml(lock, Mutex::_no_safepoint_check_flag);
+ // Don't pull lock during error reporting
+ ConditionalMutexLocker ml(_lock, !VMError::is_error_reported(), Mutex::_no_safepoint_check_flag);
num_trims = _num_trims_performed;
stopped = _stop;
suspenders = _suspend_count;
diff --git a/src/hotspot/share/utilities/copy.cpp b/src/hotspot/share/utilities/copy.cpp
index 9ead75f2ceb90..ed7797969438b 100644
--- a/src/hotspot/share/utilities/copy.cpp
+++ b/src/hotspot/share/utilities/copy.cpp
@@ -243,6 +243,16 @@ void Copy::fill_to_memory_atomic(void* to, size_t size, jubyte value) {
}
} else {
// Not aligned, so no need to be atomic.
+#ifdef MUSL_LIBC
+ // This code is used by Unsafe and may hit the next page after truncation of mapped memory.
+ // Therefore, we use volatile to prevent compilers from replacing the loop by memset which
+ // may not trigger SIGBUS as needed (observed on Alpine Linux x86_64)
+ jbyte fill = value;
+ for (uintptr_t off = 0; off < size; off += sizeof(jbyte)) {
+ *(volatile jbyte*)(dst + off) = fill;
+ }
+#else
Copy::fill_to_bytes(dst, size, value);
+#endif
}
}
diff --git a/src/hotspot/share/utilities/globalCounter.hpp b/src/hotspot/share/utilities/globalCounter.hpp
index 7e971f33ae3e5..b336ed4a1dac5 100644
--- a/src/hotspot/share/utilities/globalCounter.hpp
+++ b/src/hotspot/share/utilities/globalCounter.hpp
@@ -46,9 +46,9 @@ class GlobalCounter : public AllStatic {
// Since do not know what we will end up next to in BSS, we make sure the
// counter is on a separate cacheline.
struct PaddedCounter {
- DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE, 0);
+ DEFINE_PAD_MINUS_SIZE(0, DEFAULT_PADDING_SIZE, 0);
volatile uintx _counter;
- DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, sizeof(volatile uintx));
+ DEFINE_PAD_MINUS_SIZE(1, DEFAULT_PADDING_SIZE, sizeof(volatile uintx));
};
// The global counter
diff --git a/src/hotspot/share/utilities/globalDefinitions.hpp b/src/hotspot/share/utilities/globalDefinitions.hpp
index a6bf8a3e7d3ca..08eb25828703f 100644
--- a/src/hotspot/share/utilities/globalDefinitions.hpp
+++ b/src/hotspot/share/utilities/globalDefinitions.hpp
@@ -602,11 +602,16 @@ const bool support_IRIW_for_not_multiple_copy_atomic_cpu = false;
const bool support_IRIW_for_not_multiple_copy_atomic_cpu = PPC64_ONLY(true) NOT_PPC64(false);
#endif
-// The expected size in bytes of a cache line, used to pad data structures.
+// The expected size in bytes of a cache line.
#ifndef DEFAULT_CACHE_LINE_SIZE
#error "Platform should define DEFAULT_CACHE_LINE_SIZE"
#endif
+// The default padding size for data structures to avoid false sharing.
+#ifndef DEFAULT_PADDING_SIZE
+#error "Platform should define DEFAULT_PADDING_SIZE"
+#endif
+
//----------------------------------------------------------------------------------------------------
// Utility macros for compilers
diff --git a/src/hotspot/share/utilities/nonblockingQueue.hpp b/src/hotspot/share/utilities/nonblockingQueue.hpp
index 0c62f07719012..814132809fa8f 100644
--- a/src/hotspot/share/utilities/nonblockingQueue.hpp
+++ b/src/hotspot/share/utilities/nonblockingQueue.hpp
@@ -62,7 +62,7 @@ template
class NonblockingQueue {
T* volatile _head;
// Padding of one cache line to avoid false sharing.
- DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, sizeof(T*));
+ DEFINE_PAD_MINUS_SIZE(1, DEFAULT_PADDING_SIZE, sizeof(T*));
T* volatile _tail;
NONCOPYABLE(NonblockingQueue);
diff --git a/src/hotspot/share/utilities/utf8.cpp b/src/hotspot/share/utilities/utf8.cpp
index 66e48d5606511..d7798778b2cea 100644
--- a/src/hotspot/share/utilities/utf8.cpp
+++ b/src/hotspot/share/utilities/utf8.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -341,10 +341,10 @@ bool UTF8::is_legal_utf8(const unsigned char* buffer, int length,
// For an unsigned char v,
// (v | v - 1) is < 128 (highest bit 0) for 0 < v < 128;
// (v | v - 1) is >= 128 (highest bit 1) for v == 0 or v >= 128.
- unsigned char res = b0 | b0 - 1 |
- b1 | b1 - 1 |
- b2 | b2 - 1 |
- b3 | b3 - 1;
+ unsigned char res = b0 | (b0 - 1) |
+ b1 | (b1 - 1) |
+ b2 | (b2 - 1) |
+ b3 | (b3 - 1);
if (res >= 128) break;
i += 4;
}
diff --git a/src/hotspot/share/utilities/waitBarrier_generic.hpp b/src/hotspot/share/utilities/waitBarrier_generic.hpp
index d3a45b33b82ef..e980b3022ef8e 100644
--- a/src/hotspot/share/utilities/waitBarrier_generic.hpp
+++ b/src/hotspot/share/utilities/waitBarrier_generic.hpp
@@ -38,7 +38,7 @@ class GenericWaitBarrier : public CHeapObj {
// This would insulate from stalls when adjacent cells have returning
// workers and contend over the cache line for current latency-critical
// cell.
- DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE, 0);
+ DEFINE_PAD_MINUS_SIZE(0, DEFAULT_PADDING_SIZE, 0);
Semaphore _sem;
@@ -81,14 +81,14 @@ class GenericWaitBarrier : public CHeapObj {
Cell _cells[CELLS_COUNT];
// Trailing padding to protect the last cell.
- DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE, 0);
+ DEFINE_PAD_MINUS_SIZE(0, DEFAULT_PADDING_SIZE, 0);
volatile int _barrier_tag;
// Trailing padding to insulate the rest of the barrier from adjacent
// data structures. The leading padding is not needed, as cell padding
// handles this for us.
- DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, 0);
+ DEFINE_PAD_MINUS_SIZE(1, DEFAULT_PADDING_SIZE, 0);
NONCOPYABLE(GenericWaitBarrier);
diff --git a/src/java.base/share/classes/com/sun/crypto/provider/DESKey.java b/src/java.base/share/classes/com/sun/crypto/provider/DESKey.java
index 17f82b2eacc34..ff7e1f4ddd57d 100644
--- a/src/java.base/share/classes/com/sun/crypto/provider/DESKey.java
+++ b/src/java.base/share/classes/com/sun/crypto/provider/DESKey.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -85,7 +85,7 @@ final class DESKey implements SecretKey {
// Use the cleaner to zero the key when no longer referenced
final byte[] k = this.key;
CleanerFactory.cleaner().register(this,
- () -> java.util.Arrays.fill(k, (byte)0x00));
+ () -> Arrays.fill(k, (byte)0x00));
}
public byte[] getEncoded() {
@@ -136,7 +136,7 @@ public boolean equals(Object obj) {
byte[] thatKey = that.getEncoded();
boolean ret = MessageDigest.isEqual(this.key, thatKey);
- java.util.Arrays.fill(thatKey, (byte)0x00);
+ Arrays.fill(thatKey, (byte)0x00);
return ret;
} finally {
// prevent this from being cleaned for the above block
@@ -168,7 +168,7 @@ private void readObject(java.io.ObjectInputStream s)
// Use the cleaner to zero the key when no longer referenced
final byte[] k = this.key;
CleanerFactory.cleaner().register(this,
- () -> java.util.Arrays.fill(k, (byte)0x00));
+ () -> Arrays.fill(k, (byte)0x00));
}
/**
diff --git a/src/java.base/share/classes/com/sun/crypto/provider/DESedeKey.java b/src/java.base/share/classes/com/sun/crypto/provider/DESedeKey.java
index f5c3d8384df73..53f72499a33d3 100644
--- a/src/java.base/share/classes/com/sun/crypto/provider/DESedeKey.java
+++ b/src/java.base/share/classes/com/sun/crypto/provider/DESedeKey.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -87,7 +87,7 @@ final class DESedeKey implements SecretKey {
// Use the cleaner to zero the key when no longer referenced
final byte[] k = this.key;
CleanerFactory.cleaner().register(this,
- () -> java.util.Arrays.fill(k, (byte)0x00));
+ () -> Arrays.fill(k, (byte)0x00));
}
public byte[] getEncoded() {
@@ -137,7 +137,7 @@ public boolean equals(Object obj) {
byte[] thatKey = that.getEncoded();
boolean ret = MessageDigest.isEqual(this.key, thatKey);
- java.util.Arrays.fill(thatKey, (byte)0x00);
+ Arrays.fill(thatKey, (byte)0x00);
return ret;
} finally {
// prevent this from being cleaned for the above block
@@ -162,7 +162,7 @@ private void readObject(java.io.ObjectInputStream s)
}
byte[] temp = key;
this.key = temp.clone();
- java.util.Arrays.fill(temp, (byte)0x00);
+ Arrays.fill(temp, (byte)0x00);
DESKeyGenerator.setParityBit(key, 0);
DESKeyGenerator.setParityBit(key, 8);
@@ -171,7 +171,7 @@ private void readObject(java.io.ObjectInputStream s)
// Use the cleaner to zero the key when no longer referenced
final byte[] k = this.key;
CleanerFactory.cleaner().register(this,
- () -> java.util.Arrays.fill(k, (byte)0x00));
+ () -> Arrays.fill(k, (byte)0x00));
}
/**
diff --git a/src/java.base/share/classes/com/sun/crypto/provider/ISO10126Padding.java b/src/java.base/share/classes/com/sun/crypto/provider/ISO10126Padding.java
index 902d302cac4b7..a86f313e2c9e1 100644
--- a/src/java.base/share/classes/com/sun/crypto/provider/ISO10126Padding.java
+++ b/src/java.base/share/classes/com/sun/crypto/provider/ISO10126Padding.java
@@ -74,7 +74,6 @@ public void padWithLen(byte[] in, int off, int len)
SunJCE.getRandom().nextBytes(padding);
System.arraycopy(padding, 0, in, off, len - 1);
in[idx - 1] = paddingOctet;
- return;
}
/**
diff --git a/src/java.base/share/classes/com/sun/crypto/provider/PBEKey.java b/src/java.base/share/classes/com/sun/crypto/provider/PBEKey.java
index 480a0810425fc..21dc463572ee2 100644
--- a/src/java.base/share/classes/com/sun/crypto/provider/PBEKey.java
+++ b/src/java.base/share/classes/com/sun/crypto/provider/PBEKey.java
@@ -84,7 +84,7 @@ final class PBEKey implements SecretKey {
// Use the cleaner to zero the key when no longer referenced
final byte[] k = this.key;
cleanable = CleanerFactory.cleaner().register(this,
- () -> java.util.Arrays.fill(k, (byte)0x00));
+ () -> Arrays.fill(k, (byte)0x00));
}
public byte[] getEncoded() {
@@ -196,7 +196,7 @@ private void readObject(java.io.ObjectInputStream s)
// Use cleaner to zero the key when no longer referenced
final byte[] k = this.key;
cleanable = CleanerFactory.cleaner().register(this,
- () -> java.util.Arrays.fill(k, (byte)0x00));
+ () -> Arrays.fill(k, (byte)0x00));
}
diff --git a/src/java.base/share/classes/com/sun/crypto/provider/PKCS5Padding.java b/src/java.base/share/classes/com/sun/crypto/provider/PKCS5Padding.java
index 7b3850bd55661..af072c6f5d708 100644
--- a/src/java.base/share/classes/com/sun/crypto/provider/PKCS5Padding.java
+++ b/src/java.base/share/classes/com/sun/crypto/provider/PKCS5Padding.java
@@ -71,7 +71,6 @@ public void padWithLen(byte[] in, int off, int len)
byte paddingOctet = (byte) (len & 0xff);
Arrays.fill(in, off, idx, paddingOctet);
- return;
}
/**
diff --git a/src/java.base/share/classes/java/io/BufferedInputStream.java b/src/java.base/share/classes/java/io/BufferedInputStream.java
index e5a44761b8aec..d4531d27db1e9 100644
--- a/src/java.base/share/classes/java/io/BufferedInputStream.java
+++ b/src/java.base/share/classes/java/io/BufferedInputStream.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1994, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -643,9 +643,13 @@ private long implTransferTo(OutputStream out) throws IOException {
if (getClass() == BufferedInputStream.class && markpos == -1) {
int avail = count - pos;
if (avail > 0) {
- // Prevent poisoning and leaking of buf
- byte[] buffer = Arrays.copyOfRange(getBufIfOpen(), pos, count);
- out.write(buffer);
+ if (isTrusted(out)) {
+ out.write(getBufIfOpen(), pos, avail);
+ } else {
+ // Prevent poisoning and leaking of buf
+ byte[] buffer = Arrays.copyOfRange(getBufIfOpen(), pos, count);
+ out.write(buffer);
+ }
pos = count;
}
try {
@@ -658,4 +662,22 @@ private long implTransferTo(OutputStream out) throws IOException {
}
}
+ /**
+ * Returns true if this class satisfies the following conditions:
+ *
+ * - does not retain a reference to the {@code byte[]}
+ * - does not leak a reference to the {@code byte[]} to non-trusted classes
+ * - does not modify the contents of the {@code byte[]}
+ * - {@code write()} method does not read the contents outside of the offset/length bounds
+ *
+ *
+ * @return true if this class is trusted
+ */
+ private static boolean isTrusted(OutputStream os) {
+ var clazz = os.getClass();
+ return clazz == ByteArrayOutputStream.class
+ || clazz == FileOutputStream.class
+ || clazz == PipedOutputStream.class;
+ }
+
}
diff --git a/src/java.base/share/classes/java/io/SequenceInputStream.java b/src/java.base/share/classes/java/io/SequenceInputStream.java
index de3fafc884d7e..b89d9ca80b0fa 100644
--- a/src/java.base/share/classes/java/io/SequenceInputStream.java
+++ b/src/java.base/share/classes/java/io/SequenceInputStream.java
@@ -242,11 +242,14 @@ public long transferTo(OutputStream out) throws IOException {
if (getClass() == SequenceInputStream.class) {
long transferred = 0;
while (in != null) {
+ long numTransferred = in.transferTo(out);
+ // increment the total transferred byte count
+ // only if we haven't already reached the Long.MAX_VALUE
if (transferred < Long.MAX_VALUE) {
try {
- transferred = Math.addExact(transferred, in.transferTo(out));
+ transferred = Math.addExact(transferred, numTransferred);
} catch (ArithmeticException ignore) {
- return Long.MAX_VALUE;
+ transferred = Long.MAX_VALUE;
}
}
nextStream();
diff --git a/src/java.base/share/classes/java/lang/StringBuffer.java b/src/java.base/share/classes/java/lang/StringBuffer.java
index ec7ecb5d2451f..d77462f0c706f 100644
--- a/src/java.base/share/classes/java/lang/StringBuffer.java
+++ b/src/java.base/share/classes/java/lang/StringBuffer.java
@@ -715,6 +715,7 @@ public synchronized StringBuffer reverse() {
*/
@Override
public synchronized StringBuffer repeat(int codePoint, int count) {
+ toStringCache = null;
super.repeat(codePoint, count);
return this;
}
@@ -726,6 +727,7 @@ public synchronized StringBuffer repeat(int codePoint, int count) {
*/
@Override
public synchronized StringBuffer repeat(CharSequence cs, int count) {
+ toStringCache = null;
super.repeat(cs, count);
return this;
}
diff --git a/src/java.base/share/classes/java/lang/VirtualThread.java b/src/java.base/share/classes/java/lang/VirtualThread.java
index 13ba543348ed7..36a673fde60cf 100644
--- a/src/java.base/share/classes/java/lang/VirtualThread.java
+++ b/src/java.base/share/classes/java/lang/VirtualThread.java
@@ -975,12 +975,12 @@ StackTraceElement[] asyncGetStackTrace() {
* Returns null if the thread is mounted or in transition.
*/
private StackTraceElement[] tryGetStackTrace() {
- int initialState = state();
+ int initialState = state() & ~SUSPENDED;
switch (initialState) {
case NEW, STARTED, TERMINATED -> {
return new StackTraceElement[0]; // unmounted, empty stack
}
- case RUNNING, PINNED -> {
+ case RUNNING, PINNED, TIMED_PINNED -> {
return null; // mounted
}
case PARKED, TIMED_PARKED -> {
@@ -992,7 +992,7 @@ private StackTraceElement[] tryGetStackTrace() {
case PARKING, TIMED_PARKING, YIELDING -> {
return null; // in transition
}
- default -> throw new InternalError();
+ default -> throw new InternalError("" + initialState);
}
// thread is unmounted, prevent it from continuing
diff --git a/src/java.base/share/classes/java/lang/invoke/Invokers.java b/src/java.base/share/classes/java/lang/invoke/Invokers.java
index f14ddc70b4062..6c383dd3f2ca3 100644
--- a/src/java.base/share/classes/java/lang/invoke/Invokers.java
+++ b/src/java.base/share/classes/java/lang/invoke/Invokers.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -190,7 +190,7 @@ static MemberName invokeBasicMethod(MethodType basicType) {
private boolean checkInvoker(MethodHandle invoker) {
assert(targetType.invokerType().equals(invoker.type()))
- : java.util.Arrays.asList(targetType, targetType.invokerType(), invoker);
+ : Arrays.asList(targetType, targetType.invokerType(), invoker);
assert(invoker.internalMemberName() == null ||
invoker.internalMemberName().getMethodType().equals(targetType));
assert(!invoker.isVarargsCollector());
@@ -200,7 +200,7 @@ private boolean checkInvoker(MethodHandle invoker) {
private boolean checkVarHandleInvoker(MethodHandle invoker) {
MethodType invokerType = targetType.insertParameterTypes(0, VarHandle.class);
assert(invokerType.equals(invoker.type()))
- : java.util.Arrays.asList(targetType, invokerType, invoker);
+ : Arrays.asList(targetType, invokerType, invoker);
assert(invoker.internalMemberName() == null ||
invoker.internalMemberName().getMethodType().equals(targetType));
assert(!invoker.isVarargsCollector());
diff --git a/src/java.base/share/classes/java/math/BigInteger.java b/src/java.base/share/classes/java/math/BigInteger.java
index 43c401dd13677..98f55ef3c8c0f 100644
--- a/src/java.base/share/classes/java/math/BigInteger.java
+++ b/src/java.base/share/classes/java/math/BigInteger.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1774,7 +1774,7 @@ private static BigInteger multiplyByInt(int[] x, int y, int sign) {
carry = product >>> 32;
}
if (carry == 0L) {
- rmag = java.util.Arrays.copyOfRange(rmag, 1, rmag.length);
+ rmag = Arrays.copyOfRange(rmag, 1, rmag.length);
} else {
rmag[rstart] = (int)carry;
}
@@ -1819,7 +1819,7 @@ BigInteger multiply(long v) {
rmag[0] = (int)carry;
}
if (carry == 0L)
- rmag = java.util.Arrays.copyOfRange(rmag, 1, rmag.length);
+ rmag = Arrays.copyOfRange(rmag, 1, rmag.length);
return new BigInteger(rmag, rsign);
}
@@ -4593,7 +4593,7 @@ private static int[] stripLeadingZeroInts(int[] val) {
// Find first nonzero byte
for (keep = 0; keep < vlen && val[keep] == 0; keep++)
;
- return java.util.Arrays.copyOfRange(val, keep, vlen);
+ return Arrays.copyOfRange(val, keep, vlen);
}
/**
@@ -4607,7 +4607,7 @@ private static int[] trustedStripLeadingZeroInts(int[] val) {
// Find first nonzero byte
for (keep = 0; keep < vlen && val[keep] == 0; keep++)
;
- return keep == 0 ? val : java.util.Arrays.copyOfRange(val, keep, vlen);
+ return keep == 0 ? val : Arrays.copyOfRange(val, keep, vlen);
}
private static int[] stripLeadingZeroBytes(byte[] a, int from, int len) {
diff --git a/src/java.base/share/classes/java/util/IdentityHashMap.java b/src/java.base/share/classes/java/util/IdentityHashMap.java
index 77f06fb94100b..f1f4b802b5f8f 100644
--- a/src/java.base/share/classes/java/util/IdentityHashMap.java
+++ b/src/java.base/share/classes/java/util/IdentityHashMap.java
@@ -267,7 +267,7 @@ private void init(int initCapacity) {
}
/**
- * Constructs a new identity hash map containing the keys-value mappings
+ * Constructs a new identity hash map containing the key-value mappings
* in the specified map.
*
* @param m the map whose mappings are to be placed into this map
diff --git a/src/java.base/share/classes/java/util/zip/ZipFile.java b/src/java.base/share/classes/java/util/zip/ZipFile.java
index 7281db3297b6b..d48910fe5efa0 100644
--- a/src/java.base/share/classes/java/util/zip/ZipFile.java
+++ b/src/java.base/share/classes/java/util/zip/ZipFile.java
@@ -95,7 +95,8 @@
*/
public class ZipFile implements ZipConstants, Closeable {
- private final String name; // zip file name
+ private final String filePath; // zip file path
+ private final String fileName; // name of the file
private volatile boolean closeRequested;
// The "resource" used by this zip file that needs to be
@@ -245,7 +246,8 @@ public ZipFile(File file, int mode, Charset charset) throws IOException
}
Objects.requireNonNull(charset, "charset");
- this.name = name;
+ this.filePath = name;
+ this.fileName = file.getName();
long t0 = System.nanoTime();
this.res = new CleanableResource(this, ZipCoder.get(charset), file, mode);
@@ -483,7 +485,16 @@ public int available() throws IOException {
* @return the path name of the ZIP file
*/
public String getName() {
- return name;
+ return filePath;
+ }
+
+ /**
+ * {@return a string identifying this {@code ZipFile}, for debugging}
+ */
+ @Override
+ public String toString() {
+ return this.fileName
+ + "@" + Integer.toHexString(System.identityHashCode(this));
}
private class ZipEntryIterator
diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/ClassReaderImpl.java b/src/java.base/share/classes/jdk/internal/classfile/impl/ClassReaderImpl.java
index 67bdaa481d372..9b6c7d7ad4c8f 100644
--- a/src/java.base/share/classes/jdk/internal/classfile/impl/ClassReaderImpl.java
+++ b/src/java.base/share/classes/jdk/internal/classfile/impl/ClassReaderImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -189,45 +189,73 @@ public BootstrapMethodEntryImpl bootstrapMethodEntry(int index) {
return bsmEntries().get(index);
}
+ private static IllegalArgumentException outOfBoundsError(IndexOutOfBoundsException cause) {
+ return new IllegalArgumentException("Reading beyond classfile bounds", cause);
+ }
+
@Override
public int readU1(int p) {
- return buffer[p] & 0xFF;
+ try {
+ return buffer[p] & 0xFF;
+ } catch (IndexOutOfBoundsException e) {
+ throw outOfBoundsError(e);
+ }
}
@Override
public int readU2(int p) {
- int b1 = buffer[p] & 0xFF;
- int b2 = buffer[p + 1] & 0xFF;
- return (b1 << 8) + b2;
+ try {
+ int b1 = buffer[p] & 0xFF;
+ int b2 = buffer[p + 1] & 0xFF;
+ return (b1 << 8) + b2;
+ } catch (IndexOutOfBoundsException e) {
+ throw outOfBoundsError(e);
+ }
}
@Override
public int readS1(int p) {
- return buffer[p];
+ try {
+ return buffer[p];
+ } catch (IndexOutOfBoundsException e) {
+ throw outOfBoundsError(e);
+ }
}
@Override
public int readS2(int p) {
- int b1 = buffer[p];
- int b2 = buffer[p + 1] & 0xFF;
- return (b1 << 8) + b2;
+ try {
+ int b1 = buffer[p];
+ int b2 = buffer[p + 1] & 0xFF;
+ return (b1 << 8) + b2;
+ } catch (IndexOutOfBoundsException e) {
+ throw outOfBoundsError(e);
+ }
}
@Override
public int readInt(int p) {
- int ch1 = buffer[p] & 0xFF;
- int ch2 = buffer[p + 1] & 0xFF;
- int ch3 = buffer[p + 2] & 0xFF;
- int ch4 = buffer[p + 3] & 0xFF;
- return (ch1 << 24) + (ch2 << 16) + (ch3 << 8) + ch4;
+ try {
+ int ch1 = buffer[p] & 0xFF;
+ int ch2 = buffer[p + 1] & 0xFF;
+ int ch3 = buffer[p + 2] & 0xFF;
+ int ch4 = buffer[p + 3] & 0xFF;
+ return (ch1 << 24) + (ch2 << 16) + (ch3 << 8) + ch4;
+ } catch (IndexOutOfBoundsException e) {
+ throw outOfBoundsError(e);
+ }
}
@Override
public long readLong(int p) {
- return ((long) buffer[p + 0] << 56) + ((long) (buffer[p + 1] & 255) << 48) +
- ((long) (buffer[p + 2] & 255) << 40) + ((long) (buffer[p + 3] & 255) << 32) +
- ((long) (buffer[p + 4] & 255) << 24) + ((buffer[p + 5] & 255) << 16) + ((buffer[p + 6] & 255) << 8) +
- (buffer[p + 7] & 255);
+ try {
+ return ((long) buffer[p + 0] << 56) + ((long) (buffer[p + 1] & 255) << 48) +
+ ((long) (buffer[p + 2] & 255) << 40) + ((long) (buffer[p + 3] & 255) << 32) +
+ ((long) (buffer[p + 4] & 255) << 24) + ((buffer[p + 5] & 255) << 16) + ((buffer[p + 6] & 255) << 8) +
+ (buffer[p + 7] & 255);
+ } catch (IndexOutOfBoundsException e) {
+ throw outOfBoundsError(e);
+ }
}
@Override
@@ -242,12 +270,20 @@ public double readDouble(int p) {
@Override
public byte[] readBytes(int p, int len) {
- return Arrays.copyOfRange(buffer, p, p + len);
+ try {
+ return Arrays.copyOfRange(buffer, p, p + len);
+ } catch (IndexOutOfBoundsException e) {
+ throw outOfBoundsError(e);
+ }
}
@Override
public void copyBytesTo(BufWriter buf, int p, int len) {
- buf.writeBytes(buffer, p, len);
+ try {
+ buf.writeBytes(buffer, p, len);
+ } catch (IndexOutOfBoundsException e) {
+ throw outOfBoundsError(e);
+ }
}
BootstrapMethodsAttribute bootstrapMethodsAttribute() {
@@ -446,8 +482,12 @@ public boolean compare(BufWriter bufWriter,
int bufWriterOffset,
int classReaderOffset,
int length) {
- return Arrays.equals(((BufWriterImpl) bufWriter).elems,
- bufWriterOffset, bufWriterOffset + length,
- buffer, classReaderOffset, classReaderOffset + length);
+ try {
+ return Arrays.equals(((BufWriterImpl) bufWriter).elems,
+ bufWriterOffset, bufWriterOffset + length,
+ buffer, classReaderOffset, classReaderOffset + length);
+ } catch (IndexOutOfBoundsException e) {
+ throw outOfBoundsError(e);
+ }
}
}
diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/SignaturesImpl.java b/src/java.base/share/classes/jdk/internal/classfile/impl/SignaturesImpl.java
index fd1e612997ac4..f3efffb5b5615 100644
--- a/src/java.base/share/classes/jdk/internal/classfile/impl/SignaturesImpl.java
+++ b/src/java.base/share/classes/jdk/internal/classfile/impl/SignaturesImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -44,49 +44,64 @@ public SignaturesImpl() {
public ClassSignature parseClassSignature(String signature) {
this.sig = signature;
sigp = 0;
- List typeParamTypes = parseParamTypes();
- RefTypeSig superclass = referenceTypeSig();
- ArrayList superinterfaces = null;
- while (sigp < sig.length()) {
- if (superinterfaces == null)
- superinterfaces = new ArrayList<>();
- superinterfaces.add(referenceTypeSig());
+ try {
+ List typeParamTypes = parseParamTypes();
+ RefTypeSig superclass = referenceTypeSig();
+ ArrayList superinterfaces = null;
+ while (sigp < sig.length()) {
+ if (superinterfaces == null)
+ superinterfaces = new ArrayList<>();
+ superinterfaces.add(referenceTypeSig());
+ }
+ return new ClassSignatureImpl(typeParamTypes, superclass, null2Empty(superinterfaces));
+ } catch (IndexOutOfBoundsException e) {
+ throw error("Not a valid class signature");
}
- return new ClassSignatureImpl(typeParamTypes, superclass, null2Empty(superinterfaces));
}
public MethodSignature parseMethodSignature(String signature) {
this.sig = signature;
sigp = 0;
- List typeParamTypes = parseParamTypes();
- assert sig.charAt(sigp) == '(';
- sigp++;
- ArrayList paramTypes = null;
- while (sig.charAt(sigp) != ')') {
- if (paramTypes == null)
- paramTypes = new ArrayList<>();
- paramTypes.add(typeSig());
- }
- sigp++;
- Signature returnType = typeSig();
- ArrayList throwsTypes = null;
- while (sigp < sig.length() && sig.charAt(sigp) == '^') {
+ try {
+ List typeParamTypes = parseParamTypes();
+ if (sig.charAt(sigp) != '(') throw error("Expected ( at possition %d of signature".formatted(sigp));
+ sigp++;
+ ArrayList paramTypes = null;
+ while (sig.charAt(sigp) != ')') {
+ if (paramTypes == null)
+ paramTypes = new ArrayList<>();
+ paramTypes.add(typeSig());
+ }
sigp++;
- if (throwsTypes == null)
- throwsTypes = new ArrayList<>();
- var t = typeSig();
- if (t instanceof ThrowableSig ts)
- throwsTypes.add(ts);
- else
- throw new IllegalArgumentException("not a valid type signature: " + sig);
+ Signature returnType = typeSig();
+ ArrayList throwsTypes = null;
+ while (sigp < sig.length()) {
+ if (sig.charAt(sigp) != '^') throw error("Expected ^ at possition %d of signature".formatted(sigp));
+ sigp++;
+ if (throwsTypes == null)
+ throwsTypes = new ArrayList<>();
+ var t = referenceTypeSig();
+ if (t instanceof ThrowableSig ts)
+ throwsTypes.add(ts);
+ else
+ throw error("Not a valid throwable signature %s in".formatted(t.signatureString()));
+ }
+ return new MethodSignatureImpl(typeParamTypes, null2Empty(throwsTypes), returnType, null2Empty(paramTypes));
+ } catch (IndexOutOfBoundsException e) {
+ throw error("Not a valid method signature");
}
- return new MethodSignatureImpl(typeParamTypes, null2Empty(throwsTypes), returnType, null2Empty(paramTypes));
}
public Signature parseSignature(String signature) {
this.sig = signature;
sigp = 0;
- return typeSig();
+ try {
+ var s = typeSig();
+ if (sigp == signature.length())
+ return s;
+ } catch (IndexOutOfBoundsException e) {
+ }
+ throw error("Not a valid type signature");
}
private List parseParamTypes() {
@@ -157,7 +172,7 @@ private RefTypeSig referenceTypeSig() {
return ty;
case '[': return ArrayTypeSig.of(typeSig());
}
- throw new IllegalArgumentException("not a valid type signature: " + sig);
+ throw error("Unexpected character %c at possition %d of signature".formatted(c, sigp - 1));
}
private TypeArg typeArg() {
@@ -292,4 +307,8 @@ public String signatureString() {
private static List null2Empty(ArrayList l) {
return l == null ? List.of() : Collections.unmodifiableList(l);
}
+
+ private IllegalArgumentException error(String message) {
+ return new IllegalArgumentException("%s: %s".formatted(message, sig));
+ }
}
diff --git a/src/java.base/share/classes/jdk/internal/io/JdkConsoleImpl.java b/src/java.base/share/classes/jdk/internal/io/JdkConsoleImpl.java
index 370fc73fcd0f4..a75ff58208558 100644
--- a/src/java.base/share/classes/jdk/internal/io/JdkConsoleImpl.java
+++ b/src/java.base/share/classes/jdk/internal/io/JdkConsoleImpl.java
@@ -119,8 +119,17 @@ public char[] readPassword(String fmt, Object ... args) {
else
ioe.addSuppressed(x);
}
- if (ioe != null)
+ if (ioe != null) {
+ Arrays.fill(passwd, ' ');
+ try {
+ if (reader instanceof LineReader lr) {
+ lr.zeroOut();
+ }
+ } catch (IOException x) {
+ // ignore
+ }
throw ioe;
+ }
}
pw.println();
}
diff --git a/src/java.base/share/classes/jdk/internal/loader/ClassLoaders.java b/src/java.base/share/classes/jdk/internal/loader/ClassLoaders.java
index 75922c34e652c..7b0f4d13e4096 100644
--- a/src/java.base/share/classes/jdk/internal/loader/ClassLoaders.java
+++ b/src/java.base/share/classes/jdk/internal/loader/ClassLoaders.java
@@ -64,19 +64,19 @@ private static void setArchivedServicesCatalog(ClassLoader loader) {
// Creates the built-in class loaders.
static {
ArchivedClassLoaders archivedClassLoaders = ArchivedClassLoaders.get();
+ // -Xbootclasspath/a or -javaagent with Boot-Class-Path attribute
+ String append = VM.getSavedProperty("jdk.boot.class.path.append");
+ URLClassPath bootUcp = (append != null && !append.isEmpty())
+ ? new URLClassPath(append, true)
+ : null;
if (archivedClassLoaders != null) {
- // assert VM.getSavedProperty("jdk.boot.class.path.append") == null
BOOT_LOADER = (BootClassLoader) archivedClassLoaders.bootLoader();
+ BOOT_LOADER.setClassPath(bootUcp);
setArchivedServicesCatalog(BOOT_LOADER);
PLATFORM_LOADER = (PlatformClassLoader) archivedClassLoaders.platformLoader();
setArchivedServicesCatalog(PLATFORM_LOADER);
} else {
- // -Xbootclasspath/a or -javaagent with Boot-Class-Path attribute
- String append = VM.getSavedProperty("jdk.boot.class.path.append");
- URLClassPath ucp = (append != null && !append.isEmpty())
- ? new URLClassPath(append, true)
- : null;
- BOOT_LOADER = new BootClassLoader(ucp);
+ BOOT_LOADER = new BootClassLoader(bootUcp);
PLATFORM_LOADER = new PlatformClassLoader(BOOT_LOADER);
}
// A class path is required when no initial module is specified.
diff --git a/src/java.base/share/classes/sun/net/ftp/impl/FtpClient.java b/src/java.base/share/classes/sun/net/ftp/impl/FtpClient.java
index f8518fff4c4d5..8b6dd9c5ec7b1 100644
--- a/src/java.base/share/classes/sun/net/ftp/impl/FtpClient.java
+++ b/src/java.base/share/classes/sun/net/ftp/impl/FtpClient.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -204,7 +204,7 @@ private static boolean isASCIISuperset(String encoding) throws Exception {
47, 63, 58, 64, 38, 61, 43, 36, 44};
byte[] b = chkS.getBytes(encoding);
- return java.util.Arrays.equals(b, chkB);
+ return Arrays.equals(b, chkB);
}
private class DefaultParser implements FtpDirParser {
diff --git a/src/java.base/share/data/tzdata/VERSION b/src/java.base/share/data/tzdata/VERSION
index 66bd061e8bcf9..560884d1a8253 100644
--- a/src/java.base/share/data/tzdata/VERSION
+++ b/src/java.base/share/data/tzdata/VERSION
@@ -21,4 +21,4 @@
# or visit www.oracle.com if you need additional information or have any
# questions.
#
-tzdata2023c
+tzdata2023d
diff --git a/src/java.base/share/data/tzdata/africa b/src/java.base/share/data/tzdata/africa
index a73405fdb01f2..b4789b16c71e5 100644
--- a/src/java.base/share/data/tzdata/africa
+++ b/src/java.base/share/data/tzdata/africa
@@ -308,13 +308,6 @@ Rule Egypt 2007 only - Sep Thu>=1 24:00 0 -
# reproduced by other (more accessible) sites[, e.g.,]...
# http://elgornal.net/news/news.aspx?id=4699258
-# From Paul Eggert (2014-06-04):
-# Sarah El Deeb and Lee Keath of AP report that the Egyptian government says
-# the change is because of blackouts in Cairo, even though Ahram Online (cited
-# above) says DST had no affect on electricity consumption. There is
-# no information about when DST will end this fall. See:
-# http://abcnews.go.com/International/wireStory/el-sissi-pushes-egyptians-line-23614833
-
# From Steffen Thorsen (2015-04-08):
# Egypt will start DST on midnight after Thursday, April 30, 2015.
# This is based on a law (no 35) from May 15, 2014 saying it starts the last
diff --git a/src/java.base/share/data/tzdata/antarctica b/src/java.base/share/data/tzdata/antarctica
index 3de5e726eb4d7..fc7176cd0d57a 100644
--- a/src/java.base/share/data/tzdata/antarctica
+++ b/src/java.base/share/data/tzdata/antarctica
@@ -103,6 +103,11 @@
# - 2018 Oct 7 4:00 - 2019 Mar 17 3:00 - 2019 Oct 4 3:00 - 2020 Mar 8 3:00
# and now - 2020 Oct 4 0:01
+# From Paul Eggert (2023-12-20):
+# Transitions from 2021 on are taken from:
+# https://www.timeanddate.com/time/zone/antarctica/casey
+# retrieved at various dates.
+
# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Antarctica/Casey 0 - -00 1969
8:00 - +08 2009 Oct 18 2:00
@@ -116,7 +121,12 @@ Zone Antarctica/Casey 0 - -00 1969
8:00 - +08 2019 Oct 4 3:00
11:00 - +11 2020 Mar 8 3:00
8:00 - +08 2020 Oct 4 0:01
- 11:00 - +11
+ 11:00 - +11 2021 Mar 14 0:00
+ 8:00 - +08 2021 Oct 3 0:01
+ 11:00 - +11 2022 Mar 13 0:00
+ 8:00 - +08 2022 Oct 2 0:01
+ 11:00 - +11 2023 Mar 9 3:00
+ 8:00 - +08
Zone Antarctica/Davis 0 - -00 1957 Jan 13
7:00 - +07 1964 Nov
0 - -00 1969 Feb
@@ -263,7 +273,50 @@ Zone Antarctica/Troll 0 - -00 2005 Feb 12
# year-round from 1960/61 to 1992
# Vostok, since 1957-12-16, temporarily closed 1994-02/1994-11
-# See Asia/Urumqi.
+# From Craig Mundell (1994-12-15):
+# http://quest.arc.nasa.gov/antarctica/QA/computers/Directions,Time,ZIP
+# Vostok, which is one of the Russian stations, is set on the same
+# time as Moscow, Russia.
+#
+# From Lee Hotz (2001-03-08):
+# I queried the folks at Columbia who spent the summer at Vostok and this is
+# what they had to say about time there:
+# "in the US Camp (East Camp) we have been on New Zealand (McMurdo)
+# time, which is 12 hours ahead of GMT. The Russian Station Vostok was
+# 6 hours behind that (although only 2 miles away, i.e. 6 hours ahead
+# of GMT). This is a time zone I think two hours east of Moscow. The
+# natural time zone is in between the two: 8 hours ahead of GMT."
+#
+# From Paul Eggert (2001-05-04):
+# This seems to be hopelessly confusing, so I asked Lee Hotz about it
+# in person. He said that some Antarctic locations set their local
+# time so that noon is the warmest part of the day, and that this
+# changes during the year and does not necessarily correspond to mean
+# solar noon. So the Vostok time might have been whatever the clocks
+# happened to be during their visit. So we still don't really know what time
+# it is at Vostok.
+#
+# From Zakhary V. Akulov (2023-12-17 22:00:48 +0700):
+# ... from December, 18, 2023 00:00 by my decision the local time of
+# the Antarctic research base Vostok will correspond to UTC+5.
+# (2023-12-19): We constantly interact with Progress base, with company who
+# builds new wintering station, with sledge convoys, with aviation - they all
+# use UTC+5. Besides, difference between Moscow time is just 2 hours now, not 4.
+# (2023-12-19, in response to the question "Has local time at Vostok
+# been UTC+6 ever since 1957, or has it changed before?"): No. At least
+# since my antarctic career start, 10 years ago, Vostok base has UTC+7.
+# (In response to a 2023-12-18 question "from 02:00 to 00:00 today"): This.
+#
+# From Paul Eggert (2023-12-18):
+# For lack of better info, guess Vostok was at +07 from founding through today,
+# except when closed.
+
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
+Zone Antarctica/Vostok 0 - -00 1957 Dec 16
+ 7:00 - +07 1994 Feb
+ 0 - -00 1994 Nov
+ 7:00 - +07 2023 Dec 18 2:00
+ 5:00 - +05
# S Africa - year-round bases
# Marion Island, -4653+03752
diff --git a/src/java.base/share/data/tzdata/asia b/src/java.base/share/data/tzdata/asia
index 6a048c3ad283e..f86f84b2d2707 100644
--- a/src/java.base/share/data/tzdata/asia
+++ b/src/java.base/share/data/tzdata/asia
@@ -678,7 +678,6 @@ Zone Asia/Shanghai 8:05:43 - LMT 1901
8:00 PRC C%sT
# Xinjiang time, used by many in western China; represented by Ürümqi / Ürümchi
# / Wulumuqi. (Please use Asia/Shanghai if you prefer Beijing time.)
-# Vostok base in Antarctica matches this since 1970.
Zone Asia/Urumqi 5:50:20 - LMT 1928
6:00 - +06
@@ -3450,6 +3449,9 @@ Zone Asia/Karachi 4:28:12 - LMT 1907
# From Heba Hamad (2023-03-22):
# ... summer time will begin in Palestine from Saturday 04-29-2023,
# 02:00 AM by 60 minutes forward.
+# From Heba Hemad (2023-10-09):
+# ... winter time will begin in Palestine from Saturday 10-28-2023,
+# 02:00 AM by 60 minutes back.
#
# From Paul Eggert (2023-03-22):
# For now, guess that spring and fall transitions will normally
@@ -3571,13 +3573,13 @@ Rule Palestine 2070 only - Oct 4 2:00 0 -
Rule Palestine 2071 only - Sep 19 2:00 0 -
Rule Palestine 2072 only - Sep 10 2:00 0 -
Rule Palestine 2072 only - Oct 15 2:00 1:00 S
+Rule Palestine 2072 max - Oct Sat<=30 2:00 0 -
Rule Palestine 2073 only - Sep 2 2:00 0 -
Rule Palestine 2073 only - Oct 7 2:00 1:00 S
Rule Palestine 2074 only - Aug 18 2:00 0 -
Rule Palestine 2074 only - Sep 29 2:00 1:00 S
Rule Palestine 2075 only - Aug 10 2:00 0 -
Rule Palestine 2075 only - Sep 14 2:00 1:00 S
-Rule Palestine 2075 max - Oct Sat<=30 2:00 0 -
Rule Palestine 2076 only - Jul 25 2:00 0 -
Rule Palestine 2076 only - Sep 5 2:00 1:00 S
Rule Palestine 2077 only - Jul 17 2:00 0 -
diff --git a/src/java.base/share/data/tzdata/australasia b/src/java.base/share/data/tzdata/australasia
index 893d7055eaba4..366cfd10cc154 100644
--- a/src/java.base/share/data/tzdata/australasia
+++ b/src/java.base/share/data/tzdata/australasia
@@ -414,8 +414,14 @@ Zone Antarctica/Macquarie 0 - -00 1899 Nov
# Please note that there will not be any daylight savings time change
# in Fiji for 2022-2023....
# https://www.facebook.com/FijianGovernment/posts/pfbid0mmWVTYmTibn66ybpFda75pDcf34SSpoSaskJW5gXwaKo5Sgc7273Q4fXWc6kQV6Hl
+
+# From Almaz Mingaleev (2023-10-06):
+# Cabinet approved the suspension of Daylight Saving and appropriate
+# legislative changes will be considered including the repeal of the
+# Daylight Saving Act 1998
+# https://www.fiji.gov.fj/Media-Centre/Speeches/English/CABINET-DECISIONS-3-OCTOBER-2023
#
-# From Paul Eggert (2022-10-27):
+# From Paul Eggert (2023-10-06):
# For now, assume DST is suspended indefinitely.
# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
diff --git a/src/java.base/share/data/tzdata/backward b/src/java.base/share/data/tzdata/backward
index c0746d6dd1bc8..7ddc6cc3d93b0 100644
--- a/src/java.base/share/data/tzdata/backward
+++ b/src/java.base/share/data/tzdata/backward
@@ -228,7 +228,6 @@ Link America/Puerto_Rico America/Tortola
Link Pacific/Port_Moresby Antarctica/DumontDUrville
Link Pacific/Auckland Antarctica/McMurdo
Link Asia/Riyadh Antarctica/Syowa
-Link Asia/Urumqi Antarctica/Vostok
Link Europe/Berlin Arctic/Longyearbyen
Link Asia/Riyadh Asia/Aden
Link Asia/Qatar Asia/Bahrain
diff --git a/src/java.base/share/data/tzdata/europe b/src/java.base/share/data/tzdata/europe
index 446d2e1e658fa..f1b084f64d034 100644
--- a/src/java.base/share/data/tzdata/europe
+++ b/src/java.base/share/data/tzdata/europe
@@ -1146,6 +1146,23 @@ Zone Atlantic/Faroe -0:27:04 - LMT 1908 Jan 11 # Tórshavn
# 2. The shift *from* DST in 2023 happens as normal, but coincides with the
# shift to UTC-02 normaltime (people will not change their clocks here).
# 3. After this, DST is still observed, but as -02/-01 instead of -03/-02.
+#
+# From Múte Bourup Egede via Jógvan Svabo Samuelsen (2023-03-15):
+# Greenland will not switch to Daylight Saving Time this year, 2023,
+# because the standard time for Greenland will change from UTC -3 to UTC -2.
+# However, Greenland will change to Daylight Saving Time again in 2024
+# and onwards.
+
+# From a contributor who wishes to remain anonymous for now (2023-10-29):
+# https://www.dr.dk/nyheder/seneste/i-nat-skal-uret-stilles-en-time-tilbage-men-foerste-gang-sker-det-ikke-i-groenland
+# with a link to that page:
+# https://naalakkersuisut.gl/Nyheder/2023/10/2710_sommertid
+# ... Ittoqqortoormiit joins the time of Nuuk at March 2024.
+# What would mean that America/Scoresbysund would either be in -01 year round
+# or in -02/-01 like America/Nuuk, but no longer in -01/+00.
+#
+# From Paul Eggert (2023-10-29):
+# For now, assume it will be like America/Nuuk.
# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Thule 1991 1992 - Mar lastSun 2:00 1:00 D
@@ -1166,10 +1183,12 @@ Zone America/Danmarkshavn -1:14:40 - LMT 1916 Jul 28
Zone America/Scoresbysund -1:27:52 - LMT 1916 Jul 28 # Ittoqqortoormiit
-2:00 - -02 1980 Apr 6 2:00
-2:00 C-Eur -02/-01 1981 Mar 29
- -1:00 EU -01/+00
+ -1:00 EU -01/+00 2024 Mar 31
+ -2:00 EU -02/-01
Zone America/Nuuk -3:26:56 - LMT 1916 Jul 28 # Godthåb
-3:00 - -03 1980 Apr 6 2:00
- -3:00 EU -03/-02 2023 Oct 29 1:00u
+ -3:00 EU -03/-02 2023 Mar 26 1:00u
+ -2:00 - -02 2023 Oct 29 1:00u
-2:00 EU -02/-01
Zone America/Thule -4:35:08 - LMT 1916 Jul 28 # Pituffik
-4:00 Thule A%sT
@@ -3734,11 +3753,7 @@ Zone Europe/Istanbul 1:55:52 - LMT 1880
# and not at 3:00 as would have been under EU rules.
# This is why I have set the change to EU rules into May 1996,
# so that the change in March is stil covered by the Ukraine rule.
-# The next change in October 1996 happened under EU rules....
-# TZ database holds three other zones for Ukraine.... I have not yet
-# worked out the consequences for these three zones, as we (me and my
-# US colleague David Cochrane) are still trying to get more
-# information upon these local deviations from Kiev rules.
+# The next change in October 1996 happened under EU rules.
#
# From Paul Eggert (2022-08-27):
# For now, assume that Ukraine's zones all followed the same rules,
diff --git a/src/java.base/share/data/tzdata/iso3166.tab b/src/java.base/share/data/tzdata/iso3166.tab
index cea17732dd138..7fa350ecbe3db 100644
--- a/src/java.base/share/data/tzdata/iso3166.tab
+++ b/src/java.base/share/data/tzdata/iso3166.tab
@@ -26,17 +26,22 @@
# This file is in the public domain, so clarified as of
# 2009-05-17 by Arthur David Olson.
#
-# From Paul Eggert (2022-11-18):
+# From Paul Eggert (2023-09-06):
# This file contains a table of two-letter country codes. Columns are
# separated by a single tab. Lines beginning with '#' are comments.
# All text uses UTF-8 encoding. The columns of the table are as follows:
#
# 1. ISO 3166-1 alpha-2 country code, current as of
-# ISO 3166-1 N1087 (2022-09-02). See: Updates on ISO 3166-1
-# https://isotc.iso.org/livelink/livelink/Open/16944257
-# 2. The usual English name for the coded region,
-# chosen so that alphabetic sorting of subsets produces helpful lists.
-# This is not the same as the English name in the ISO 3166 tables.
+# ISO/TC 46 N1108 (2023-04-05). See: ISO/TC 46 Documents
+# https://www.iso.org/committee/48750.html?view=documents
+# 2. The usual English name for the coded region. This sometimes
+# departs from ISO-listed names, sometimes so that sorted subsets
+# of names are useful (e.g., "Samoa (American)" and "Samoa
+# (western)" rather than "American Samoa" and "Samoa"),
+# sometimes to avoid confusion among non-experts (e.g.,
+# "Czech Republic" and "Turkey" rather than "Czechia" and "Türkiye"),
+# and sometimes to omit needless detail or churn (e.g., "Netherlands"
+# rather than "Netherlands (the)" or "Netherlands (Kingdom of the)").
#
# The table is sorted by country code.
#
diff --git a/src/java.base/share/data/tzdata/leapseconds b/src/java.base/share/data/tzdata/leapseconds
index 89ce8b89cd28f..ab2c1af4bed59 100644
--- a/src/java.base/share/data/tzdata/leapseconds
+++ b/src/java.base/share/data/tzdata/leapseconds
@@ -95,11 +95,11 @@ Leap 2016 Dec 31 23:59:60 + S
# Any additional leap seconds will come after this.
# This Expires line is commented out for now,
# so that pre-2020a zic implementations do not reject this file.
-#Expires 2023 Dec 28 00:00:00
+#Expires 2024 Jun 28 00:00:00
# POSIX timestamps for the data in this file:
#updated 1467936000 (2016-07-08 00:00:00 UTC)
-#expires 1703721600 (2023-12-28 00:00:00 UTC)
+#expires 1719532800 (2024-06-28 00:00:00 UTC)
-# Updated through IERS Bulletin C65
-# File expires on: 28 December 2023
+# Updated through IERS Bulletin C66
+# File expires on: 28 June 2024
diff --git a/src/java.base/share/data/tzdata/northamerica b/src/java.base/share/data/tzdata/northamerica
index e240cf35103c4..b96269a0e26f5 100644
--- a/src/java.base/share/data/tzdata/northamerica
+++ b/src/java.base/share/data/tzdata/northamerica
@@ -1,3 +1,4 @@
+#
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -1475,7 +1476,7 @@ Rule StJohns 1989 2006 - Apr Sun>=1 0:01 1:00 D
Rule StJohns 2007 2011 - Mar Sun>=8 0:01 1:00 D
Rule StJohns 2007 2010 - Nov Sun>=1 0:01 0 S
#
-# St John's has an apostrophe, but Posix file names can't have apostrophes.
+# St John's has an apostrophe, but POSIX file names can't have apostrophes.
# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/St_Johns -3:30:52 - LMT 1884
-3:30:52 StJohns N%sT 1918
diff --git a/src/java.base/share/data/tzdata/southamerica b/src/java.base/share/data/tzdata/southamerica
index 4024e7180cdb9..da2c623926247 100644
--- a/src/java.base/share/data/tzdata/southamerica
+++ b/src/java.base/share/data/tzdata/southamerica
@@ -1720,6 +1720,12 @@ Rule Para 2010 2012 - Apr Sun>=8 0:00 0 -
# From Carlos Raúl Perasso (2014-02-28):
# Decree 1264 can be found at:
# http://www.presidencia.gov.py/archivos/documentos/DECRETO1264_ey9r8zai.pdf
+#
+# From Paul Eggert (2023-07-26):
+# Transition dates are now set by Law No. 7115, not by presidential decree.
+# https://www.abc.com.py/politica/2023/07/12/promulgacion-el-cambio-de-hora-sera-por-ley/
+# From Carlos Raúl Perasso (2023-07-27):
+# http://silpy.congreso.gov.py/descarga/ley-144138
Rule Para 2013 max - Mar Sun>=22 0:00 0 -
# Zone NAME STDOFF RULES FORMAT [UNTIL]
diff --git a/src/java.base/share/data/tzdata/zone.tab b/src/java.base/share/data/tzdata/zone.tab
index 3edb0d61c8099..0a01e8777dd25 100644
--- a/src/java.base/share/data/tzdata/zone.tab
+++ b/src/java.base/share/data/tzdata/zone.tab
@@ -71,7 +71,7 @@ AR -3124-06411 America/Argentina/Cordoba Argentina (most areas: CB, CC, CN, ER,
AR -2447-06525 America/Argentina/Salta Salta (SA, LP, NQ, RN)
AR -2411-06518 America/Argentina/Jujuy Jujuy (JY)
AR -2649-06513 America/Argentina/Tucuman Tucuman (TM)
-AR -2828-06547 America/Argentina/Catamarca Catamarca (CT); Chubut (CH)
+AR -2828-06547 America/Argentina/Catamarca Catamarca (CT), Chubut (CH)
AR -2926-06651 America/Argentina/La_Rioja La Rioja (LR)
AR -3132-06831 America/Argentina/San_Juan San Juan (SJ)
AR -3253-06849 America/Argentina/Mendoza Mendoza (MZ)
@@ -110,7 +110,7 @@ BN +0456+11455 Asia/Brunei
BO -1630-06809 America/La_Paz
BQ +120903-0681636 America/Kralendijk
BR -0351-03225 America/Noronha Atlantic islands
-BR -0127-04829 America/Belem Para (east); Amapa
+BR -0127-04829 America/Belem Para (east), Amapa
BR -0343-03830 America/Fortaleza Brazil (northeast: MA, PI, CE, RN, PB)
BR -0803-03454 America/Recife Pernambuco
BR -0712-04812 America/Araguaina Tocantins
@@ -130,21 +130,21 @@ BT +2728+08939 Asia/Thimphu
BW -2439+02555 Africa/Gaborone
BY +5354+02734 Europe/Minsk
BZ +1730-08812 America/Belize
-CA +4734-05243 America/St_Johns Newfoundland; Labrador (southeast)
-CA +4439-06336 America/Halifax Atlantic - NS (most areas); PE
+CA +4734-05243 America/St_Johns Newfoundland, Labrador (SE)
+CA +4439-06336 America/Halifax Atlantic - NS (most areas), PE
CA +4612-05957 America/Glace_Bay Atlantic - NS (Cape Breton)
CA +4606-06447 America/Moncton Atlantic - New Brunswick
CA +5320-06025 America/Goose_Bay Atlantic - Labrador (most areas)
CA +5125-05707 America/Blanc-Sablon AST - QC (Lower North Shore)
-CA +4339-07923 America/Toronto Eastern - ON, QC (most areas)
+CA +4339-07923 America/Toronto Eastern - ON & QC (most areas)
CA +6344-06828 America/Iqaluit Eastern - NU (most areas)
-CA +484531-0913718 America/Atikokan EST - ON (Atikokan); NU (Coral H)
-CA +4953-09709 America/Winnipeg Central - ON (west); Manitoba
+CA +484531-0913718 America/Atikokan EST - ON (Atikokan), NU (Coral H)
+CA +4953-09709 America/Winnipeg Central - ON (west), Manitoba
CA +744144-0944945 America/Resolute Central - NU (Resolute)
CA +624900-0920459 America/Rankin_Inlet Central - NU (central)
CA +5024-10439 America/Regina CST - SK (most areas)
CA +5017-10750 America/Swift_Current CST - SK (midwest)
-CA +5333-11328 America/Edmonton Mountain - AB; BC (E); NT (E); SK (W)
+CA +5333-11328 America/Edmonton Mountain - AB, BC(E), NT(E), SK(W)
CA +690650-1050310 America/Cambridge_Bay Mountain - NU (west)
CA +682059-1334300 America/Inuvik Mountain - NT (west)
CA +4906-11631 America/Creston MST - BC (Creston)
@@ -230,8 +230,8 @@ HT +1832-07220 America/Port-au-Prince
HU +4730+01905 Europe/Budapest
ID -0610+10648 Asia/Jakarta Java, Sumatra
ID -0002+10920 Asia/Pontianak Borneo (west, central)
-ID -0507+11924 Asia/Makassar Borneo (east, south); Sulawesi/Celebes, Bali, Nusa Tengarra; Timor (west)
-ID -0232+14042 Asia/Jayapura New Guinea (West Papua / Irian Jaya); Malukus/Moluccas
+ID -0507+11924 Asia/Makassar Borneo (east, south), Sulawesi/Celebes, Bali, Nusa Tengarra, Timor (west)
+ID -0232+14042 Asia/Jayapura New Guinea (West Papua / Irian Jaya), Malukus/Moluccas
IE +5320-00615 Europe/Dublin
IL +314650+0351326 Asia/Jerusalem
IM +5409-00428 Europe/Isle_of_Man
@@ -378,7 +378,7 @@ RU +4310+13156 Asia/Vladivostok MSK+07 - Amur River
RU +643337+1431336 Asia/Ust-Nera MSK+07 - Oymyakonsky
RU +5934+15048 Asia/Magadan MSK+08 - Magadan
RU +4658+14242 Asia/Sakhalin MSK+08 - Sakhalin Island
-RU +6728+15343 Asia/Srednekolymsk MSK+08 - Sakha (E); N Kuril Is
+RU +6728+15343 Asia/Srednekolymsk MSK+08 - Sakha (E), N Kuril Is
RU +5301+15839 Asia/Kamchatka MSK+09 - Kamchatka
RU +6445+17729 Asia/Anadyr MSK+09 - Bering Sea
RW -0157+03004 Africa/Kigali
@@ -441,7 +441,7 @@ US +470659-1011757 America/North_Dakota/Center Central - ND (Oliver)
US +465042-1012439 America/North_Dakota/New_Salem Central - ND (Morton rural)
US +471551-1014640 America/North_Dakota/Beulah Central - ND (Mercer)
US +394421-1045903 America/Denver Mountain (most areas)
-US +433649-1161209 America/Boise Mountain - ID (south); OR (east)
+US +433649-1161209 America/Boise Mountain - ID (south), OR (east)
US +332654-1120424 America/Phoenix MST - AZ (except Navajo)
US +340308-1181434 America/Los_Angeles Pacific
US +611305-1495401 America/Anchorage Alaska (most areas)
diff --git a/src/java.compiler/share/classes/javax/lang/model/util/ElementFilter.java b/src/java.compiler/share/classes/javax/lang/model/util/ElementFilter.java
index 0dfd86caf1a9f..88c74322c3997 100644
--- a/src/java.compiler/share/classes/javax/lang/model/util/ElementFilter.java
+++ b/src/java.compiler/share/classes/javax/lang/model/util/ElementFilter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -169,7 +169,7 @@ private ElementFilter() {} // Do not instantiate.
}
/**
- * {@return a set of types in {@code elements}}
+ * {@return a set of classes and interfaces in {@code elements}}
* @param elements the elements to filter
*/
public static Set
diff --git a/src/java.desktop/share/classes/java/awt/image/IndexColorModel.java b/src/java.desktop/share/classes/java/awt/image/IndexColorModel.java
index 246eb1abbdd65..3547862615aea 100644
--- a/src/java.desktop/share/classes/java/awt/image/IndexColorModel.java
+++ b/src/java.desktop/share/classes/java/awt/image/IndexColorModel.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -592,7 +592,7 @@ private int calcRealMapSize(int bits, int size) {
private BigInteger getAllValid() {
int numbytes = (map_size+7)/8;
byte[] valid = new byte[numbytes];
- java.util.Arrays.fill(valid, (byte)0xff);
+ Arrays.fill(valid, (byte)0xff);
valid[0] = (byte)(0xff >>> (numbytes*8 - map_size));
return new BigInteger(1, valid);
diff --git a/src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp b/src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp
index 08e03d0095992..12c2677e32a37 100644
--- a/src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp
+++ b/src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp
@@ -46,6 +46,7 @@ typedef HRESULT(__stdcall *PFNCLOSETHEMEDATA)(HTHEME hTheme);
typedef HRESULT(__stdcall *PFNDRAWTHEMEBACKGROUND)(HTHEME hTheme, HDC hdc,
int iPartId, int iStateId, const RECT *pRect, const RECT *pClipRect);
+typedef HTHEME(__stdcall *PFNOPENTHEMEDATA)(HWND hwnd, LPCWSTR pszClassList);
typedef HTHEME(__stdcall *PFNOPENTHEMEDATAFORDPI)(HWND hwnd, LPCWSTR pszClassList, UINT dpi);
typedef HRESULT (__stdcall *PFNDRAWTHEMETEXT)(HTHEME hTheme, HDC hdc,
@@ -90,6 +91,7 @@ typedef HRESULT (__stdcall *PFNGETTHEMETRANSITIONDURATION)
(HTHEME hTheme, int iPartId, int iStateIdFrom, int iStateIdTo,
int iPropId, DWORD *pdwDuration);
+static PFNOPENTHEMEDATA OpenThemeDataFunc = NULL;
static PFNOPENTHEMEDATAFORDPI OpenThemeDataForDpiFunc = NULL;
static PFNDRAWTHEMEBACKGROUND DrawThemeBackgroundFunc = NULL;
static PFNCLOSETHEMEDATA CloseThemeDataFunc = NULL;
@@ -109,13 +111,17 @@ static PFNISTHEMEBACKGROUNDPARTIALLYTRANSPARENT
IsThemeBackgroundPartiallyTransparentFunc = NULL;
static PFNGETTHEMETRANSITIONDURATION GetThemeTransitionDurationFunc = NULL;
+constexpr unsigned int defaultDPI = 96;
-BOOL InitThemes() {
+
+static BOOL InitThemes() {
static HMODULE hModThemes = NULL;
hModThemes = JDK_LoadSystemLibrary("UXTHEME.DLL");
DTRACE_PRINTLN1("InitThemes hModThemes = %x\n", hModThemes);
if(hModThemes) {
DTRACE_PRINTLN("Loaded UxTheme.dll\n");
+ OpenThemeDataFunc = (PFNOPENTHEMEDATA)GetProcAddress(hModThemes,
+ "OpenThemeData");
OpenThemeDataForDpiFunc = (PFNOPENTHEMEDATAFORDPI)GetProcAddress(
hModThemes, "OpenThemeDataForDpi");
DrawThemeBackgroundFunc = (PFNDRAWTHEMEBACKGROUND)GetProcAddress(
@@ -152,7 +158,7 @@ BOOL InitThemes() {
(PFNGETTHEMETRANSITIONDURATION)GetProcAddress(hModThemes,
"GetThemeTransitionDuration");
- if(OpenThemeDataForDpiFunc
+ if((OpenThemeDataForDpiFunc || OpenThemeDataFunc)
&& DrawThemeBackgroundFunc
&& CloseThemeDataFunc
&& DrawThemeTextFunc
@@ -173,10 +179,12 @@ BOOL InitThemes() {
DTRACE_PRINTLN("Loaded function pointers.\n");
// We need to make sure we can load the Theme.
// Use the default DPI value of 96 on windows.
- constexpr unsigned int defaultDPI = 96;
- HTHEME hTheme = OpenThemeDataForDpiFunc (
- AwtToolkit::GetInstance().GetHWnd(),
- L"Button", defaultDPI);
+ HTHEME hTheme = OpenThemeDataForDpiFunc
+ ? OpenThemeDataForDpiFunc(AwtToolkit::GetInstance().GetHWnd(),
+ L"Button", defaultDPI)
+ : OpenThemeDataFunc(AwtToolkit::GetInstance().GetHWnd(),
+ L"Button");
+
if(hTheme) {
DTRACE_PRINTLN("Loaded Theme data.\n");
CloseThemeDataFunc(hTheme);
@@ -246,11 +254,13 @@ JNIEXPORT jlong JNICALL Java_sun_awt_windows_ThemeReader_openTheme
JNU_ThrowOutOfMemoryError(env, 0);
return 0;
}
+
// We need to open the Theme on a Window that will stick around.
// The best one for that purpose is the Toolkit window.
- HTHEME htheme = OpenThemeDataForDpiFunc(
- AwtToolkit::GetInstance().GetHWnd(),
- str, dpi);
+ HTHEME htheme = OpenThemeDataForDpiFunc
+ ? OpenThemeDataForDpiFunc(AwtToolkit::GetInstance().GetHWnd(), str, dpi)
+ : OpenThemeDataFunc(AwtToolkit::GetInstance().GetHWnd(), str);
+
JNU_ReleaseStringPlatformChars(env, widget, str);
return (jlong) htheme;
}
@@ -430,9 +440,14 @@ JNIEXPORT void JNICALL Java_sun_awt_windows_ThemeReader_paintBackground
rect.left = 0;
rect.top = 0;
- rect.bottom = rectBottom;
- rect.right = rectRight;
+ if (OpenThemeDataForDpiFunc) {
+ rect.bottom = rectBottom;
+ rect.right = rectRight;
+ } else {
+ rect.bottom = h;
+ rect.right = w;
+ }
ZeroMemory(pSrcBits,(BITS_PER_PIXEL>>3)*w*h);
HRESULT hres = DrawThemeBackgroundFunc(hTheme, memDC, part, state, &rect, NULL);
@@ -455,6 +470,28 @@ JNIEXPORT void JNICALL Java_sun_awt_windows_ThemeReader_paintBackground
ReleaseDC(NULL,defaultDC);
}
+static void rescale(SIZE *size) {
+ static int dpiX = -1;
+ static int dpiY = -1;
+
+ if (dpiX == -1 || dpiY == -1) {
+ HWND hWnd = ::GetDesktopWindow();
+ HDC hDC = ::GetDC(hWnd);
+ dpiX = ::GetDeviceCaps(hDC, LOGPIXELSX);
+ dpiY = ::GetDeviceCaps(hDC, LOGPIXELSY);
+ ::ReleaseDC(hWnd, hDC);
+ }
+
+ if (dpiX !=0 && dpiX != defaultDPI) {
+ float invScaleX = (float) defaultDPI / dpiX;
+ size->cx = (int) round(size->cx * invScaleX);
+ }
+ if (dpiY != 0 && dpiY != defaultDPI) {
+ float invScaleY = (float) defaultDPI / dpiY;
+ size->cy = (int) round(size->cy * invScaleY);
+ }
+}
+
jobject newInsets(JNIEnv *env, jint top, jint left, jint bottom, jint right) {
if (env->EnsureLocalCapacity(2) < 0) {
return NULL;
@@ -746,6 +783,10 @@ JNIEXPORT jobject JNICALL Java_sun_awt_windows_ThemeReader_getPartSize
CHECK_NULL_RETURN(dimMID, NULL);
}
+ if (!OpenThemeDataForDpiFunc) {
+ rescale(&size);
+ }
+
jobject dimObj = env->NewObject(dimClassID, dimMID, size.cx, size.cy);
if (safe_ExceptionOccurred(env)) {
env->ExceptionDescribe();
diff --git a/src/java.management/share/classes/sun/management/ThreadImpl.java b/src/java.management/share/classes/sun/management/ThreadImpl.java
index 7eb67e99bc8be..1f37b2da567fd 100644
--- a/src/java.management/share/classes/sun/management/ThreadImpl.java
+++ b/src/java.management/share/classes/sun/management/ThreadImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -267,7 +267,7 @@ protected long[] getThreadCpuTime(long[] ids) {
int length = ids.length;
long[] times = new long[length];
- java.util.Arrays.fill(times, -1);
+ Arrays.fill(times, -1);
if (verified) {
if (length == 1) {
@@ -306,7 +306,7 @@ protected long[] getThreadUserTime(long[] ids) {
int length = ids.length;
long[] times = new long[length];
- java.util.Arrays.fill(times, -1);
+ Arrays.fill(times, -1);
if (verified) {
if (length == 1) {
@@ -390,7 +390,7 @@ protected long[] getThreadAllocatedBytes(long[] ids) {
boolean verified = verifyThreadAllocatedMemory(ids);
long[] sizes = new long[ids.length];
- java.util.Arrays.fill(sizes, -1);
+ Arrays.fill(sizes, -1);
if (verified) {
getThreadAllocatedMemory1(ids, sizes);
diff --git a/src/java.sql/share/classes/java/sql/Timestamp.java b/src/java.sql/share/classes/java/sql/Timestamp.java
index dc347ab02ffaa..8fb85f73c7e4b 100644
--- a/src/java.sql/share/classes/java/sql/Timestamp.java
+++ b/src/java.sql/share/classes/java/sql/Timestamp.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2023, 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
@@ -542,7 +542,7 @@ public LocalDateTime toLocalDateTime() {
*/
public static Timestamp from(Instant instant) {
try {
- Timestamp stamp = new Timestamp(instant.getEpochSecond() * MILLIS_PER_SECOND);
+ Timestamp stamp = new Timestamp(Math.multiplyExact(instant.getEpochSecond(), MILLIS_PER_SECOND));
stamp.nanos = instant.getNano();
return stamp;
} catch (ArithmeticException ex) {
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/PropertyManager.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/PropertyManager.java
index da21fb4a511b6..c8d032109a02e 100644
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/PropertyManager.java
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/PropertyManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -46,7 +46,7 @@
* @author K Venugopal
* @author Sunitha Reddy
*
- * @LastModified: Nov 2023
+ * @LastModified: Jan 2024
*/
public class PropertyManager {
@@ -184,6 +184,9 @@ public boolean containsProperty(String property) {
* @return the value of a property
*/
public Object getProperty(String property) {
+ if (XMLInputFactory.SUPPORT_DTD.equals(property)) {
+ return fSecurityManager.is(XMLSecurityManager.Limit.STAX_SUPPORT_DTD);
+ }
/**
* Check to see if the property is managed by the security manager *
*/
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/AbstractSAXParser.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/AbstractSAXParser.java
index ff4e047d4ca99..614bd2fdc999a 100644
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/AbstractSAXParser.java
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/AbstractSAXParser.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -79,7 +79,7 @@
* @author Arnaud Le Hors, IBM
* @author Andy Clark, IBM
*
- * @LastModified: July 2023
+ * @LastModified: Jan 2024
*/
@SuppressWarnings("deprecation")
public abstract class AbstractSAXParser
@@ -1831,6 +1831,11 @@ else if (featureId.startsWith(XERCES_FEATURES_PREFIX)) {
}
*/
+ // Handle properties managed by XMLSecurityManager
+ if (featureId.equals(XMLSecurityManager.DISALLOW_DTD)) {
+ return securityManager.is(XMLSecurityManager.Limit.XERCES_DISALLOW_DTD);
+ }
+
return fConfiguration.getFeature(featureId);
}
catch (XMLConfigurationException e) {
diff --git a/src/java.xml/share/classes/javax/xml/stream/XMLStreamException.java b/src/java.xml/share/classes/javax/xml/stream/XMLStreamException.java
index 2cee1fc2489d1..47ef2e437c993 100644
--- a/src/java.xml/share/classes/javax/xml/stream/XMLStreamException.java
+++ b/src/java.xml/share/classes/javax/xml/stream/XMLStreamException.java
@@ -95,7 +95,7 @@ public XMLStreamException(String msg, Throwable th) {
public XMLStreamException(String msg, Location location, Throwable th) {
super("ParseError at [row,col]:["+location.getLineNumber()+","+
location.getColumnNumber()+"]\n"+
- "Message: "+msg);
+ "Message: "+msg, th);
nested = th;
this.location = location;
}
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java
index 0dd32fd8eca52..f6ce19fac06e5 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java
@@ -506,7 +506,7 @@ public void visitMethodDef(JCMethodDecl tree) {
public void visitApply(JCMethodInvocation invoke) {
// Get method symbol
- MethodSymbol sym = (MethodSymbol)TreeInfo.symbolFor(invoke.meth);
+ Symbol sym = TreeInfo.symbolFor(invoke.meth);
// Recurse on method expression
scan(invoke.meth);
@@ -530,7 +530,7 @@ public void visitApply(JCMethodInvocation invoke) {
invoke(invoke, sym, invoke.args, receiverRefs);
}
- private void invoke(JCTree site, MethodSymbol sym, List args, RefSet> receiverRefs) {
+ private void invoke(JCTree site, Symbol sym, List args, RefSet> receiverRefs) {
// Skip if ignoring warnings for a constructor invoked via 'this()'
if (suppressed.contains(sym))
@@ -810,6 +810,10 @@ public void visitSelect(JCFieldAccess tree) {
@Override
public void visitReference(JCMemberReference tree) {
+ if (tree.type.isErroneous()) {
+ //error recovery - ignore erroneous member references
+ return ;
+ }
// Scan target expression and extract 'this' references, if any
scan(tree.expr);
diff --git a/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CKeyStore.java b/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CKeyStore.java
index ad32c9aef4d60..4e352bf495011 100644
--- a/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CKeyStore.java
+++ b/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CKeyStore.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2023, 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
@@ -636,7 +636,7 @@ public String engineGetCertificateAlias(Certificate cert) {
if (entry.certChain != null &&
entry.certChain.length > 0 &&
entry.certChain[0].equals(cert)) {
- return entry.getAlias();
+ return mapEntry.getKey();
}
}
diff --git a/src/jdk.jcmd/share/man/jcmd.1 b/src/jdk.jcmd/share/man/jcmd.1
index 6d1c5cd008d79..f0e14a9dbd2e5 100644
--- a/src/jdk.jcmd/share/man/jcmd.1
+++ b/src/jdk.jcmd/share/man/jcmd.1
@@ -1,4 +1,4 @@
-.\" Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved.
+.\" Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved.
.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
.\"
.\" This code is free software; you can redistribute it and/or modify it
@@ -164,6 +164,23 @@ The following \f[I]options\f[R] must be specified using either
\f[V]-all\f[R]: (Optional) Show help for all commands (BOOLEAN, false) .
.RE
.TP
+\f[V]Compiler.CodeHeap_Analytics\f[R] [\f[I]function\f[R]] [\f[I]granularity\f[R]]
+Print CodeHeap analytics
+.RS
+.PP
+Impact: Low: Depends on code heap size and content.
+Holds CodeCache_lock during analysis step, usually sub-second duration.
+.PP
+\f[I]arguments\f[R]:
+.PP
+\f[I]function\f[R]: (Optional) Function to be performed (aggregate,
+UsedSpace, FreeSpace, MethodCount, MethodSpace, MethodAge, MethodNames,
+discard (STRING, all)
+.PP
+\f[I]granularity\f[R]: (Optional) Detail level - smaller value -> more
+detail (INT, 4096)
+.RE
+.TP
\f[V]Compiler.codecache\f[R]
Prints code cache layout and bounds.
.RS
@@ -178,58 +195,71 @@ Prints all compiled methods in code cache that are alive.
Impact: Medium
.RE
.TP
-\f[V]Compiler.perfmap\f[R] [\f[I]arguments\f[R]] (Linux only)
-Write map file for Linux perf tool.
+\f[V]Compiler.directives_add\f[R] \f[I]arguments\f[R]
+Adds compiler directives from a file.
.RS
.PP
Impact: Low
.PP
\f[I]arguments\f[R]:
-.IP \[bu] 2
-\f[V]filename\f[R]: (Optional) Name of the map file (STRING, no default
-value)
.PP
-If \f[V]filename\f[R] is not specified, a default file name is chosen
-using the pid of the target JVM process.
-For example, if the pid is \f[V]12345\f[R], then the default
-\f[V]filename\f[R] will be \f[V]/tmp/perf-12345.map\f[R].
+\f[I]filename\f[R]: The name of the directives file (STRING, no default
+value)
.RE
.TP
-\f[V]Compiler.queue\f[R]
-Prints methods queued for compilation.
+\f[V]Compiler.directives_clear\f[R]
+Remove all compiler directives.
.RS
.PP
Impact: Low
.RE
.TP
-\f[V]Compiler.directives_add *filename* *arguments*\f[R]
-Adds compiler directives from a file.
+\f[V]Compiler.directives_print\f[R]
+Prints all active compiler directives.
.RS
.PP
Impact: Low
-.PP
-\f[I]arguments\f[R]:
-.PP
-\f[I]filename\f[R]: The name of the directives file (STRING, no default
-value)
.RE
.TP
-\f[V]Compiler.directives_clear\f[R]
-Remove all compiler directives.
+\f[V]Compiler.directives_remove\f[R]
+Remove latest added compiler directive.
.RS
.PP
Impact: Low
.RE
.TP
-\f[V]Compiler.directives_print\f[R]
-Prints all active compiler directives.
+\f[V]Compiler.memory\f[R] [\f[I]options\f[R]]
+Print compilation footprint
+.RS
+.PP
+Impact: Medium: Pause time depends on number of compiled methods
+.PP
+\f[B]Note:\f[R]
+.PP
+The \f[I]options\f[R] must be specified using either \f[I]key\f[R] or
+\f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax.
+.PP
+\f[I]options\f[R]:
+.IP \[bu] 2
+\f[V]-H\f[R]: (Optional) Human readable format (BOOLEAN, false)
+.IP \[bu] 2
+\f[V]-s\f[R]: (Optional) Minimum memory size (MEMORY SIZE, 0)
+.RE
+.TP
+\f[V]Compiler.perfmap\f[R] [\f[I]arguments\f[R]] (Linux only)
+Write map file for Linux perf tool.
.RS
.PP
Impact: Low
+.PP
+\f[I]arguments\f[R]:
+.PP
+\f[I]filename\f[R]: (Optional) The name of the map file (STRING, no
+default value)
.RE
.TP
-\f[V]Compiler.directives_remove\f[R]
-Remove latest added compiler directive.
+\f[V]Compiler.queue\f[R]
+Prints methods queued for compilation.
.RS
.PP
Impact: Low
@@ -291,6 +321,12 @@ gzipped format using the given compression level.
.IP \[bu] 2
\f[V]-overwrite\f[R]: (Optional) If specified, the dump file will be
overwritten if it exists (BOOLEAN, false)
+.IP \[bu] 2
+\f[V]-parallel\f[R]: (Optional) Number of parallel threads to use for
+heap dump.
+The VM will try to use the specified number of threads, but might use
+fewer.
+(INT, 1)
.PP
\f[I]arguments\f[R]:
.IP \[bu] 2
@@ -354,6 +390,11 @@ If no parameters are entered, the current settings are displayed.
.PP
\f[I]options\f[R]:
.IP \[bu] 2
+\f[V]dumppath\f[R]: (Optional) Path to the location where a recording
+file is written in case the VM runs into a critical error, such as a
+system crash.
+(STRING, The default location is the current directory)
+.IP \[bu] 2
\f[V]globalbuffercount\f[R]: (Optional) Number of global buffers.
This option is a legacy option: change the \f[V]memorysize\f[R]
parameter to alter the number of global buffers.
@@ -651,7 +692,7 @@ Impact: Low
.RE
.TP
\f[V]JVMTI.data_dump\f[R]
-Signals the JVM to do a data-dump request for JVMTI.
+Signal the JVM to do a data-dump request for JVMTI.
.RS
.PP
Impact: High
@@ -767,8 +808,45 @@ Stops the remote management agent.
Impact: Low --- no impact
.RE
.TP
+\f[V]System.dump_map\f[R] [\f[I]options\f[R]] (Linux only)
+Dumps an annotated process memory map to an output file.
+.RS
+.PP
+Impact: Low
+.PP
+\f[B]Note:\f[R]
+.PP
+The following \f[I]options\f[R] must be specified using either
+\f[I]key\f[R] or \f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax.
+.PP
+\f[I]options\f[R]:
+.IP \[bu] 2
+\f[V]-H\f[R]: (Optional) Human readable format (BOOLEAN, false)
+.IP \[bu] 2
+\f[V]-F\f[R]: (Optional) File path (STRING,
+\[dq]vm_memory_map_.txt\[dq])
+.RE
+.TP
+\f[V]System.map\f[R] [\f[I]options\f[R]] (Linux only)
+Prints an annotated process memory map of the VM process.
+.RS
+.PP
+Impact: Low
+.PP
+\f[B]Note:\f[R]
+.PP
+The following \f[I]options\f[R] must be specified using either
+\f[I]key\f[R] or \f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax.
+.PP
+\f[I]options\f[R]:
+.IP \[bu] 2
+\f[V]-H\f[R]: (Optional) Human readable format (BOOLEAN, false)
+.RE
+.TP
\f[V]System.native_heap_info\f[R] (Linux only)
-Prints information about native heap usage through malloc_info(3).
+Attempts to output information regarding native heap usage through
+malloc_info(3).
+If unsuccessful outputs \[dq]Error: \[dq] and a reason.
.RS
.PP
Impact: Low
@@ -781,6 +859,31 @@ Attempts to free up memory by trimming the C-heap.
Impact: Low
.RE
.TP
+\f[V]Thread.dump_to_file\f[R] [\f[I]options\f[R]] \f[I]filepath\f[R]
+Dump threads, with stack traces, to a file in plain text or JSON format.
+.RS
+.PP
+Impact: Medium: Depends on the number of threads.
+.PP
+\f[B]Note:\f[R]
+.PP
+The following \f[I]options\f[R] must be specified using either
+\f[I]key\f[R] or \f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax.
+.PP
+\f[I]options\f[R]:
+.IP \[bu] 2
+\f[V]-overwrite\f[R]: (Optional) May overwrite existing file (BOOLEAN,
+false)
+.IP \[bu] 2
+\f[V]-format\f[R]: (Optional) Output format (\[dq]plain\[dq] or
+\[dq]json\[dq]) (STRING, plain)
+.PP
+\f[I]arguments\f[R]:
+.IP \[bu] 2
+\f[V]filepath\f[R]: The file path to the output file (STRING, no default
+value)
+.RE
+.TP
\f[V]Thread.print\f[R] [\f[I]options\f[R]]
Prints all threads with stacktraces.
.RS
@@ -802,7 +905,7 @@ false)
.RE
.TP
\f[V]VM.cds\f[R] [\f[I]arguments\f[R]]
-Dumps a static or dynamic shared archive that includes all currently
+Dump a static or dynamic shared archive that includes all currently
loaded classes.
.RS
.PP
@@ -828,78 +931,98 @@ If \f[V]dynamic_dump\f[R] is specified, the target JVM must be started
with the JVM option \f[V]-XX:+RecordDynamicDumpInfo\f[R].
.RE
.TP
-\f[V]VM.classloaders\f[R] [\f[I]options\f[R]]
-Prints classloader hierarchy.
+\f[V]VM.class_hierarchy\f[R] [\f[I]options\f[R]] [\f[I]arguments\f[R]]
+Print a list of all loaded classes, indented to show the class
+hierarchy.
+The name of each class is followed by the ClassLoaderData* of its
+ClassLoader, or \[dq]null\[dq] if it is loaded by the bootstrap class
+loader.
.RS
.PP
-Impact: Medium --- Depends on number of class loaders and classes
-loaded.
+Impact: Medium --- depends on the number of loaded classes.
+.PP
+\f[B]Note:\f[R]
.PP
The following \f[I]options\f[R] must be specified using either
\f[I]key\f[R] or \f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax.
.PP
\f[I]options\f[R]:
.IP \[bu] 2
-\f[V]show-classes\f[R]: (Optional) Print loaded classes.
+\f[V]-i\f[R]: (Optional) Inherited interfaces should be printed.
(BOOLEAN, false)
.IP \[bu] 2
-\f[V]verbose\f[R]: (Optional) Print detailed information.
+\f[V]-s\f[R]: (Optional) If a classname is specified, print its
+subclasses in addition to its superclasses.
+Without this option only the superclasses will be printed.
(BOOLEAN, false)
+.PP
+\f[I]arguments\f[R]:
.IP \[bu] 2
-\f[V]fold\f[R]: (Optional) Show loaders of the same name and class as
-one.
-(BOOLEAN, true)
+\f[I]classname\f[R]: (Optional) The name of the class whose hierarchy
+should be printed.
+If not specified, all class hierarchies are printed.
+(STRING, no default value)
+.RE
+.TP
+\f[V]VM.classes\f[R] [\f[I]options\f[R]]
+Print all loaded classes
+.RS
+.PP
+Impact: Medium: Depends on number of loaded classes.
+.PP
+The following \f[I]options\f[R] must be specified using either
+\f[I]key\f[R] or \f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax.
+.PP
+\f[I]options\f[R]:
+.IP \[bu] 2
+\f[V]-verbose\f[R]: (Optional) Dump the detailed content of a Java
+class.
+Some classes are annotated with flags: \f[V]F\f[R] = has, or inherits, a
+non-empty finalize method, \f[V]f\f[R] = has final method, \f[V]W\f[R] =
+methods rewritten, \f[V]C\f[R] = marked with \f[V]\[at]Contended\f[R]
+annotation, \f[V]R\f[R] = has been redefined, \f[V]S\f[R] = is shared
+class (BOOLEAN, false)
.RE
.TP
\f[V]VM.classloader_stats\f[R]
-Prints statistics about all ClassLoaders.
+Print statistics about all ClassLoaders.
.RS
.PP
Impact: Low
.RE
.TP
-\f[V]VM.class_hierarchy\f[R] [\f[I]options\f[R]] [\f[I]arguments\f[R]]
-Prints a list of all loaded classes, indented to show the class
-hierarchy.
-The name of each class is followed by the ClassLoaderData* of its
-ClassLoader, or \[dq]null\[dq] if it is loaded by the bootstrap class
-loader.
+\f[V]VM.classloaders\f[R] [\f[I]options\f[R]]
+Prints classloader hierarchy.
.RS
.PP
-Impact: Medium --- depends on the number of loaded classes.
-.PP
-\f[B]Note:\f[R]
+Impact: Medium --- Depends on number of class loaders and classes
+loaded.
.PP
The following \f[I]options\f[R] must be specified using either
\f[I]key\f[R] or \f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax.
.PP
\f[I]options\f[R]:
.IP \[bu] 2
-\f[V]-i\f[R]: (Optional) Inherited interfaces should be printed.
+\f[V]show-classes\f[R]: (Optional) Print loaded classes.
(BOOLEAN, false)
.IP \[bu] 2
-\f[V]-s\f[R]: (Optional) If a classname is specified, print its
-subclasses in addition to its superclasses.
-Without this option only the superclasses will be printed.
+\f[V]verbose\f[R]: (Optional) Print detailed information.
(BOOLEAN, false)
-.PP
-\f[I]arguments\f[R]:
.IP \[bu] 2
-\f[I]classname\f[R]: (Optional) The name of the class whose hierarchy
-should be printed.
-If not specified, all class hierarchies are printed.
-(STRING, no default value)
+\f[V]fold\f[R]: (Optional) Show loaders of the same name and class as
+one.
+(BOOLEAN, true)
.RE
.TP
\f[V]VM.command_line\f[R]
-Prints the command line used to start this VM instance.
+Print the command line used to start this VM instance.
.RS
.PP
Impact: Low
.RE
.TP
\f[V]VM.dynlibs\f[R]
-Prints the loaded dynamic libraries.
+Print loaded dynamic libraries.
.RS
.PP
Impact: Low
@@ -928,8 +1051,25 @@ If omitted, all events are printed.
(STRING, no default value)
.RE
.TP
+\f[V]VM.flags\f[R] [\f[I]options\f[R]]
+Print the VM flag options and their current values.
+.RS
+.PP
+Impact: Low
+.PP
+\f[B]Note:\f[R]
+.PP
+The following \f[I]options\f[R] must be specified using either
+\f[I]key\f[R] or \f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax.
+.PP
+\f[I]options\f[R]:
+.IP \[bu] 2
+\f[V]-all\f[R]: (Optional) Prints all flags supported by the VM
+(BOOLEAN, false).
+.RE
+.TP
\f[V]VM.info\f[R]
-Prints information about the JVM environment and status.
+Print information about the JVM environment and status.
.RS
.PP
Impact: Low
@@ -974,23 +1114,6 @@ configuration.
(BOOLEAN, no default value)
.RE
.TP
-\f[V]VM.flags\f[R] [\f[I]options\f[R]]
-Prints the VM flag options and their current values.
-.RS
-.PP
-Impact: Low
-.PP
-\f[B]Note:\f[R]
-.PP
-The following \f[I]options\f[R] must be specified using either
-\f[I]key\f[R] or \f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax.
-.PP
-\f[I]options\f[R]:
-.IP \[bu] 2
-\f[V]-all\f[R]: (Optional) Prints all flags supported by the VM
-(BOOLEAN, false).
-.RE
-.TP
\f[V]VM.metaspace\f[R] [\f[I]options\f[R]]
Prints the statistics for the metaspace
.RS
@@ -1025,6 +1148,10 @@ classes for each loader.
space.
(BOOLEAN, false)
.IP \[bu] 2
+\f[V]chunkfreelist\f[R]: (Optional) Shows details about global chunk
+free lists (ChunkManager).
+(BOOLEAN, false)
+.IP \[bu] 2
\f[V]scale\f[R]: (Optional) Memory usage in which to scale.
Valid values are: 1, KB, MB or GB (fixed scale) or \[dq]dynamic\[dq] for
a dynamically chosen scale.
@@ -1032,7 +1159,7 @@ a dynamically chosen scale.
.RE
.TP
\f[V]VM.native_memory\f[R] [\f[I]options\f[R]]
-Prints native memory usage
+Print native memory usage
.RS
.PP
Impact: Medium
@@ -1074,16 +1201,8 @@ purpose.
(STRING, KB)
.RE
.TP
-\f[V]VM.print_touched_methods\f[R]
-Prints all methods that have ever been touched during the lifetime of
-this JVM.
-.RS
-.PP
-Impact: Medium --- depends on Java content.
-.RE
-.TP
\f[V]VM.set_flag\f[R] [\f[I]arguments\f[R]]
-Sets the VM flag option by using the provided value.
+Sets VM flag option using the provided value.
.RS
.PP
Impact: Low
@@ -1098,7 +1217,7 @@ no default value)
.RE
.TP
\f[V]VM.stringtable\f[R] [\f[I]options\f[R]]
-Dumps the string table.
+Dump string table.
.RS
.PP
Impact: Medium --- depends on the Java content.
@@ -1115,7 +1234,7 @@ table (BOOLEAN, false)
.RE
.TP
\f[V]VM.symboltable\f[R] [\f[I]options\f[R]]
-Dumps the symbol table.
+Dump symbol table.
.RS
.PP
Impact: Medium --- depends on the Java content.
@@ -1131,6 +1250,13 @@ The following \f[I]options\f[R] must be specified using either
table (BOOLEAN, false)
.RE
.TP
+\f[V]VM.system_properties\f[R]
+Print system properties.
+.RS
+.PP
+Impact: Low
+.RE
+.TP
\f[V]VM.systemdictionary\f[R]
Prints the statistics for dictionary hashtable sizes and bucket length.
.RS
@@ -1148,15 +1274,8 @@ The following \f[I]options\f[R] must be specified using either
for all class loaders (BOOLEAN, false) .
.RE
.TP
-\f[V]VM.system_properties\f[R]
-Prints the system properties.
-.RS
-.PP
-Impact: Low
-.RE
-.TP
\f[V]VM.uptime\f[R] [\f[I]options\f[R]]
-Prints the VM uptime.
+Print VM uptime.
.RS
.PP
Impact: Low
@@ -1173,7 +1292,7 @@ The following \f[I]options\f[R] must be specified using either
.RE
.TP
\f[V]VM.version\f[R]
-Prints JVM version information.
+Print JVM version information.
.RS
.PP
Impact: Low
diff --git a/src/jdk.jdwp.agent/share/native/libjdwp/util.c b/src/jdk.jdwp.agent/share/native/libjdwp/util.c
index 6ac15d3de6e78..0bb7c8837d851 100644
--- a/src/jdk.jdwp.agent/share/native/libjdwp/util.c
+++ b/src/jdk.jdwp.agent/share/native/libjdwp/util.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1073,23 +1073,6 @@ debugMonitorWait(jrawMonitorID monitor)
}
}
-void
-debugMonitorTimedWait(jrawMonitorID monitor, jlong millis)
-{
- jvmtiError error;
- error = JVMTI_FUNC_PTR(gdata->jvmti,RawMonitorWait)
- (gdata->jvmti, monitor, millis);
- if (error == JVMTI_ERROR_INTERRUPT) {
- /* See comment above */
- handleInterrupt();
- error = JVMTI_ERROR_NONE;
- }
- error = ignore_vm_death(error);
- if (error != JVMTI_ERROR_NONE) {
- EXIT_ERROR(error, "on raw monitor timed wait");
- }
-}
-
void
debugMonitorNotify(jrawMonitorID monitor)
{
diff --git a/src/jdk.jdwp.agent/share/native/libjdwp/util.h b/src/jdk.jdwp.agent/share/native/libjdwp/util.h
index 7e3ff7047e93c..c5b8a2b5f519a 100644
--- a/src/jdk.jdwp.agent/share/native/libjdwp/util.h
+++ b/src/jdk.jdwp.agent/share/native/libjdwp/util.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -354,7 +354,6 @@ jrawMonitorID debugMonitorCreate(char *name);
void debugMonitorEnter(jrawMonitorID theLock);
void debugMonitorExit(jrawMonitorID theLock);
void debugMonitorWait(jrawMonitorID theLock);
-void debugMonitorTimedWait(jrawMonitorID theLock, jlong millis);
void debugMonitorNotify(jrawMonitorID theLock);
void debugMonitorNotifyAll(jrawMonitorID theLock);
void debugMonitorDestroy(jrawMonitorID theLock);
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/periodic/BatchManager.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/periodic/BatchManager.java
index 141cf1a932b06..8d51cb1de6f17 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/periodic/BatchManager.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/periodic/BatchManager.java
@@ -63,11 +63,7 @@ private void groupTasksIntoBatches(List tasks) {
}
for (PeriodicTask task : activeSortedTasks(tasks)) {
if (task.isSchedulable()) {
- Batch batch = task.getBatch();
- // If new task, or period has changed, find new batch
- if (batch == null) {
- batch = findBatch(task.getPeriod());
- }
+ Batch batch = findBatch(task.getPeriod(), task.getBatch());
batch.add(task);
}
}
@@ -89,7 +85,7 @@ private List activeSortedTasks(List unsorted) {
return tasks;
}
- private Batch findBatch(long period) {
+ private Batch findBatch(long period, Batch oldBatch) {
// All events with a period less than 1000 ms
// get their own unique batch. The rationale for
// this is to avoid a scenario where a user (mistakenly) specifies
@@ -102,7 +98,7 @@ private Batch findBatch(long period) {
return batch;
}
}
- Batch batch = new Batch(period);
+ Batch batch = oldBatch != null ? oldBatch : new Batch(period);
batches.add(batch);
return batch;
}
diff --git a/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java b/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java
index 6f165ec1144b6..1924ccd11f86b 100644
--- a/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java
+++ b/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java
@@ -2573,7 +2573,10 @@ private void initDataPos() throws IOException {
pos = -pos + locpos;
byte[] buf = new byte[LOCHDR];
if (readNBytesAt(buf, 0, buf.length, pos) != LOCHDR) {
- throw new ZipException("invalid loc " + pos + " for entry reading");
+ throw new ZipException("invalid LOC " + pos + " for entry reading");
+ }
+ if (LOCSIG(buf) != LOCSIG) {
+ throw new ZipException("invalid LOC header (bad signature)");
}
pos += LOCHDR + LOCNAM(buf) + LOCEXT(buf);
}
diff --git a/test/hotspot/gtest/gc/shared/test_bufferNodeAllocator.cpp b/test/hotspot/gtest/gc/shared/test_bufferNodeAllocator.cpp
index e07e073974fce..752aef02d5a52 100644
--- a/test/hotspot/gtest/gc/shared/test_bufferNodeAllocator.cpp
+++ b/test/hotspot/gtest/gc/shared/test_bufferNodeAllocator.cpp
@@ -239,7 +239,7 @@ static void run_test(BufferNode::Allocator* allocator, CompletedList* cbl) {
}
TEST_VM(BufferNodeAllocatorTest, stress_free_list_allocator) {
- const size_t buffer_capacity = DEFAULT_CACHE_LINE_SIZE / sizeof(void*);
+ const size_t buffer_capacity = DEFAULT_PADDING_SIZE / sizeof(void*);
BufferNode::Allocator allocator("Test Allocator", buffer_capacity);
CompletedList completed;
run_test(&allocator, &completed);
diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt
index 6e01458b34897..484aad97b8c12 100644
--- a/test/hotspot/jtreg/ProblemList.txt
+++ b/test/hotspot/jtreg/ProblemList.txt
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -72,8 +72,6 @@ compiler/vectorapi/VectorLogicalOpIdentityTest.java 8302459 linux-x64,windows-x6
compiler/jvmci/TestUncaughtErrorInCompileMethod.java 8309073 generic-all
-compiler/codecache/CheckLargePages.java 8319795 linux-x64
-
compiler/floatingpoint/TestSubnormalFloat.java 8317810 generic-i586
compiler/floatingpoint/TestSubnormalDouble.java 8317810 generic-i586
@@ -85,6 +83,11 @@ gc/epsilon/TestMemoryMXBeans.java 8206434 generic-all
gc/g1/humongousObjects/objectGraphTest/TestObjectGraphAfterGC.java 8156755 generic-all
gc/g1/logging/TestG1LoggingFailure.java 8169634 generic-all
gc/g1/humongousObjects/TestHeapCounters.java 8178918 generic-all
+gc/TestAllocHumongousFragment.java#adaptive 8298781 generic-all
+gc/TestAllocHumongousFragment.java#aggressive 8298781 generic-all
+gc/TestAllocHumongousFragment.java#iu-aggressive 8298781 generic-all
+gc/TestAllocHumongousFragment.java#g1 8298781 generic-all
+gc/TestAllocHumongousFragment.java#static 8298781 generic-all
gc/stress/gclocker/TestExcessGCLockerCollections.java 8229120 generic-all
gc/stress/gclocker/TestGCLockerWithParallel.java 8180622 generic-all
gc/stress/gclocker/TestGCLockerWithSerial.java 8180622 generic-all
@@ -104,6 +107,7 @@ 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/ErrorHandling/CreateCoredumpOnCrash.java 8267433 macosx-x64
+runtime/CompressedOops/CompressedClassPointers.java 8322943 aix-ppc64
runtime/StackGuardPages/TestStackGuardPagesNative.java 8303612 linux-all
runtime/ErrorHandling/TestDwarf.java#checkDecoder 8305489 linux-all
runtime/ErrorHandling/MachCodeFramesInErrorFile.java 8313315 linux-ppc64le
@@ -137,6 +141,8 @@ serviceability/attach/ConcAttachTest.java 8290043 linux-all
serviceability/jvmti/stress/StackTrace/NotSuspended/GetStackTraceNotSuspendedStressTest.java 8315980 linux-all,windows-x64
+serviceability/HeapDump/FullGCHeapDumpLimitTest.java 8322989 generic-all
+
#############################################################################
# :hotspot_misc
diff --git a/test/hotspot/jtreg/compiler/arguments/TestC1Globals.java b/test/hotspot/jtreg/compiler/arguments/TestC1Globals.java
index ff639a69bd937..3944b78bc2764 100644
--- a/test/hotspot/jtreg/compiler/arguments/TestC1Globals.java
+++ b/test/hotspot/jtreg/compiler/arguments/TestC1Globals.java
@@ -57,6 +57,17 @@
*
*/
+/**
+ * @test
+ * @bug 8322781
+ * @requires vm.debug
+ * @summary Test flag with c1 value numbering
+ *
+ * @run main/othervm -XX:+PrintValueNumbering -XX:+Verbose -XX:-UseLocalValueNumbering
+ * -Xcomp -XX:TieredStopAtLevel=1
+ * compiler.arguments.TestC1Globals
+ */
+
package compiler.arguments;
public class TestC1Globals {
diff --git a/test/hotspot/jtreg/compiler/arguments/TestCompileThresholdScaling.java b/test/hotspot/jtreg/compiler/arguments/TestCompileThresholdScaling.java
index c417cc6624884..47025572428ca 100644
--- a/test/hotspot/jtreg/compiler/arguments/TestCompileThresholdScaling.java
+++ b/test/hotspot/jtreg/compiler/arguments/TestCompileThresholdScaling.java
@@ -48,7 +48,7 @@ public static void main(String args[]) throws Throwable {
}
static void checkCompileThresholdScaling(double value, boolean fail) throws Throwable {
- OutputAnalyzer out = ProcessTools.executeTestJvm("-XX:CompileThresholdScaling=" + value, "--version");
+ OutputAnalyzer out = ProcessTools.executeTestJava("-XX:CompileThresholdScaling=" + value, "--version");
out.shouldHaveExitValue(0);
String output = out.getOutput();
diff --git a/test/hotspot/jtreg/compiler/c1/TestPrintC1Statistics.java b/test/hotspot/jtreg/compiler/c1/TestPrintC1Statistics.java
index 854ccd907c98f..3d62aa4d2717a 100644
--- a/test/hotspot/jtreg/compiler/c1/TestPrintC1Statistics.java
+++ b/test/hotspot/jtreg/compiler/c1/TestPrintC1Statistics.java
@@ -44,7 +44,7 @@ public static void main(String[] args) throws Exception {
options.add("-XX:+PrintC1Statistics");
options.add("--version");
- OutputAnalyzer oa = ProcessTools.executeTestJvm(options);
+ OutputAnalyzer oa = ProcessTools.executeTestJava(options);
oa.shouldHaveExitValue(0).shouldContain("C1 Runtime statistics");
}
diff --git a/test/hotspot/jtreg/compiler/c2/cr7200264/TestDriver.java b/test/hotspot/jtreg/compiler/c2/cr7200264/TestDriver.java
index 8fc1fa0580ddd..9975fd7511c86 100644
--- a/test/hotspot/jtreg/compiler/c2/cr7200264/TestDriver.java
+++ b/test/hotspot/jtreg/compiler/c2/cr7200264/TestDriver.java
@@ -44,7 +44,7 @@ public void run() throws Throwable {
}
private List executeApplication() throws Throwable {
- OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJvm(
+ OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava(
"-Xbatch",
"-XX:-TieredCompilation",
"-XX:+PrintCompilation",
diff --git a/test/hotspot/jtreg/compiler/ciReplay/CiReplayBase.java b/test/hotspot/jtreg/compiler/ciReplay/CiReplayBase.java
index 6ad45edd26b3a..dcb8dff8f7d37 100644
--- a/test/hotspot/jtreg/compiler/ciReplay/CiReplayBase.java
+++ b/test/hotspot/jtreg/compiler/ciReplay/CiReplayBase.java
@@ -105,9 +105,9 @@ static void test(int i) {
static {
try {
- CLIENT_VM_AVAILABLE = ProcessTools.executeTestJvm(CLIENT_VM_OPTION, VERSION_OPTION)
+ CLIENT_VM_AVAILABLE = ProcessTools.executeTestJava(CLIENT_VM_OPTION, VERSION_OPTION)
.getOutput().contains("Client");
- SERVER_VM_AVAILABLE = ProcessTools.executeTestJvm(SERVER_VM_OPTION, VERSION_OPTION)
+ SERVER_VM_AVAILABLE = ProcessTools.executeTestJava(SERVER_VM_OPTION, VERSION_OPTION)
.getOutput().contains("Server");
} catch(Throwable t) {
throw new Error("Initialization failed: " + t, t);
diff --git a/test/hotspot/jtreg/compiler/codecache/CheckLargePages.java b/test/hotspot/jtreg/compiler/codecache/CheckLargePages.java
index 5b6274681f799..ee37b7a5164d4 100644
--- a/test/hotspot/jtreg/compiler/codecache/CheckLargePages.java
+++ b/test/hotspot/jtreg/compiler/codecache/CheckLargePages.java
@@ -44,35 +44,83 @@
import java.util.List;
public class CheckLargePages {
- private final static WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
+ private final static long LP_1G = 1024 * 1024 * 1024;
+ private final static boolean LARGE_PAGES_ENABLED;
+ private final static long LARGE_PAGE_SIZE;
+ static {
+ WhiteBox whiteBox = WhiteBox.getWhiteBox();
+ LARGE_PAGES_ENABLED = whiteBox.getBooleanVMFlag("UseLargePages");
+ LARGE_PAGE_SIZE = (whiteBox.getBooleanVMFlag("UseLargePages")) ? whiteBox.getVMLargePageSize() : 0;
+ }
+
+ private static boolean isLargePageSizeEqual(long size) {
+ return LARGE_PAGE_SIZE == size;
+ }
+
+ private static void testSegmented2GbCodeCacheWith1GbPage() throws Exception {
+ ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(
+ "-XX:+UseLargePages",
+ "-XX:+SegmentedCodeCache",
+ "-XX:InitialCodeCacheSize=2g",
+ "-XX:ReservedCodeCacheSize=2g",
+ "-XX:LargePageSizeInBytes=1g",
+ "-Xlog:pagesize=info",
+ "-version");
+ OutputAnalyzer out = new OutputAnalyzer(pb.start());
+ out.shouldMatch("Code cache size too small for \\S* pages\\. Reverting to smaller page size \\((\\S*)\\)\\.");
+ out.shouldHaveExitValue(0);
+ // Parse page sizes to find next biggest page
+ String sizes = out.firstMatch("Usable page sizes:([^.]+)", 1);
+ List sizeList = Arrays.stream(sizes.trim().split("\\s*,\\s*")).map(CheckLargePages::parseMemoryString)
+ .sorted().toList();
+ final int smallerPageSizeIndex = sizeList.indexOf(LARGE_PAGE_SIZE) - 1;
+ Asserts.assertGreaterThanOrEqual(smallerPageSizeIndex, 0);
+ final long smallerPageSize = sizeList.get(smallerPageSizeIndex);
+ // Retrieve reverted page size from code cache warning
+ String revertedSizeString = out.firstMatch(
+ "Code cache size too small for (\\S*) pages. Reverting to smaller page size \\((\\S*)\\)\\.", 2);
+ Asserts.assertEquals(parseMemoryString(revertedSizeString), smallerPageSize);
+ }
+
+ private static void testDefaultCodeCacheWith1GbLargePages() throws Exception {
+ ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(
+ "-XX:+UseLargePages",
+ "-XX:LargePageSizeInBytes=1g",
+ "-XX:+PrintCodeCache",
+ "-version");
+ OutputAnalyzer out = new OutputAnalyzer(pb.start());
+ out.shouldHaveExitValue(0);
+ out.shouldContain("CodeHeap 'non-nmethods'");
+ out.shouldContain("CodeHeap 'profiled nmethods'");
+ out.shouldContain("CodeHeap 'non-profiled nmethods'");
+ }
+
+ private static void testNonSegmented1GbCodeCacheWith1GbLargePages() throws Exception {
+ ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(
+ "-XX:+UseLargePages",
+ "-XX:LargePageSizeInBytes=1g",
+ "-XX:ReservedCodeCacheSize=1g",
+ "-XX:InitialCodeCacheSize=1g",
+ "-XX:+PrintCodeCache",
+ "-Xlog:pagesize=info",
+ "-version");
+ OutputAnalyzer out = new OutputAnalyzer(pb.start());
+ out.shouldHaveExitValue(0);
+ out.shouldNotContain("CodeHeap 'non-nmethods'");
+ out.shouldNotContain("CodeHeap 'profiled nmethods'");
+ out.shouldNotContain("CodeHeap 'non-profiled nmethods'");
+ out.shouldContain("UseLargePages=1, UseTransparentHugePages=0");
+ out.shouldMatch("CodeCache: min=1[gG] max=1[gG] base=[^ ]+ size=1[gG] page_size=1[gG]");
+ }
public static void main(String[] args) throws Exception {
- final boolean largePages = WHITE_BOX.getBooleanVMFlag("UseLargePages");
- final long largePageSize = WHITE_BOX.getVMLargePageSize();
- if (largePages && (largePageSize == 1024 * 1024 * 1024)) {
- ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(
- "-XX:+UseLargePages",
- "-XX:+SegmentedCodeCache",
- "-XX:InitialCodeCacheSize=2g",
- "-XX:ReservedCodeCacheSize=2g",
- "-XX:LargePageSizeInBytes=1g",
- "-Xlog:pagesize=info",
- "-version");
- OutputAnalyzer out = new OutputAnalyzer(pb.start());
- out.shouldMatch("Code cache size too small for \\S* pages\\. Reverting to smaller page size \\((\\S*)\\)\\.");
- out.shouldHaveExitValue(0);
- // Parse page sizes to find next biggest page
- String sizes = out.firstMatch("Usable page sizes:([^.]+)", 1);
- List sizeList = Arrays.stream(sizes.trim().split("\\s*,\\s*")).map(CheckLargePages::parseMemoryString).sorted().toList();
- final int smallerPageSizeIndex = sizeList.indexOf(largePageSize) - 1;
- Asserts.assertGreaterThanOrEqual(smallerPageSizeIndex, 0);
- final long smallerPageSize = sizeList.get(smallerPageSizeIndex);
- // Retrieve reverted page size from code cache warning
- String revertedSizeString = out.firstMatch("Code cache size too small for (\\S*) pages. Reverting to smaller page size \\((\\S*)\\)\\.", 2);
- Asserts.assertEquals(parseMemoryString(revertedSizeString), smallerPageSize);
+ if (isLargePageSizeEqual(LP_1G)) {
+ testSegmented2GbCodeCacheWith1GbPage();
+ testDefaultCodeCacheWith1GbLargePages();
+ testNonSegmented1GbCodeCacheWith1GbLargePages();
} else {
- System.out.println("1GB large pages not supported: UseLargePages=" + largePages +
- (largePages ? ", largePageSize=" + largePageSize : "") + ". Skipping");
+ System.out.println("1GB large pages not supported: UseLargePages=" + LARGE_PAGES_ENABLED +
+ (LARGE_PAGES_ENABLED ? ", largePageSize=" + LARGE_PAGE_SIZE : "") + ". Skipping");
}
}
diff --git a/test/hotspot/jtreg/compiler/compilercontrol/commands/MemLimitTest.java b/test/hotspot/jtreg/compiler/compilercontrol/commands/MemLimitTest.java
index 5cf86794524b7..a6e16a317b038 100644
--- a/test/hotspot/jtreg/compiler/compilercontrol/commands/MemLimitTest.java
+++ b/test/hotspot/jtreg/compiler/compilercontrol/commands/MemLimitTest.java
@@ -39,7 +39,7 @@
public class MemLimitTest {
static void do_test(String option, boolean expectSuccess, int expectedValue) throws Exception {
- OutputAnalyzer output = ProcessTools.executeTestJvm("-Xmx64m", "-XX:CompileCommand=" + option, "-version");
+ OutputAnalyzer output = ProcessTools.executeTestJava("-Xmx64m", "-XX:CompileCommand=" + option, "-version");
if (expectSuccess) {
output.shouldHaveExitValue(0);
output.shouldNotContain("error occurred");
diff --git a/test/hotspot/jtreg/compiler/compilercontrol/commands/MemStatTest.java b/test/hotspot/jtreg/compiler/compilercontrol/commands/MemStatTest.java
index 2b6208652d372..e54ce7592e195 100644
--- a/test/hotspot/jtreg/compiler/compilercontrol/commands/MemStatTest.java
+++ b/test/hotspot/jtreg/compiler/compilercontrol/commands/MemStatTest.java
@@ -38,22 +38,22 @@
public class MemStatTest {
public static void main(String[] args) throws Exception {
// default => collect
- ProcessTools.executeTestJvm("-XX:CompileCommand=MemStat,*.*", "-version")
+ ProcessTools.executeTestJava("-XX:CompileCommand=MemStat,*.*", "-version")
.shouldHaveExitValue(0)
.shouldNotContain("CompileCommand: An error occurred during parsing")
.shouldContain("CompileCommand: MemStat *.* uintx MemStat = 1"); // should be registered
// collect explicit
- ProcessTools.executeTestJvm("-XX:CompileCommand=MemStat,*.*,collect", "-version")
+ ProcessTools.executeTestJava("-XX:CompileCommand=MemStat,*.*,collect", "-version")
.shouldHaveExitValue(0)
.shouldNotContain("CompileCommand: An error occurred during parsing")
.shouldContain("CompileCommand: MemStat *.* uintx MemStat = 1"); // should be registered
// print explicit
- ProcessTools.executeTestJvm("-XX:CompileCommand=MemStat,*.*,print", "-version")
+ ProcessTools.executeTestJava("-XX:CompileCommand=MemStat,*.*,print", "-version")
.shouldHaveExitValue(0)
.shouldNotContain("CompileCommand: An error occurred during parsing")
.shouldContain("CompileCommand: MemStat *.* uintx MemStat = 2");
// invalid suboption
- ProcessTools.executeTestJvm("-XX:CompileCommand=MemStat,*.*,invalid", "-version")
+ ProcessTools.executeTestJava("-XX:CompileCommand=MemStat,*.*,invalid", "-version")
.shouldNotHaveExitValue(0)
.shouldContain("CompileCommand: An error occurred during parsing")
.shouldContain("Error: Value cannot be read for option 'MemStat'")
diff --git a/test/hotspot/jtreg/compiler/compilercontrol/commands/OptionTest.java b/test/hotspot/jtreg/compiler/compilercontrol/commands/OptionTest.java
index 171caf685e202..7e9878f32b255 100644
--- a/test/hotspot/jtreg/compiler/compilercontrol/commands/OptionTest.java
+++ b/test/hotspot/jtreg/compiler/compilercontrol/commands/OptionTest.java
@@ -37,13 +37,13 @@
public class OptionTest {
public static void main(String[] args) throws Exception {
- ProcessTools.executeTestJvm("-XX:CompileCommand=option,package/class,ccstrlist,ControlIntrinsic,+_getClass", "-version")
+ ProcessTools.executeTestJava("-XX:CompileCommand=option,package/class,ccstrlist,ControlIntrinsic,+_getClass", "-version")
.shouldHaveExitValue(1)
.shouldContain("CompileCommand: An error occurred during parsing")
.shouldContain("Error: Did not specify any method name")
.shouldNotContain("# A fatal error has been detected by the Java Runtime Environment");
- ProcessTools.executeTestJvm("-XX:CompileCommand=option,*,ccstrlist,ControlIntrinsic,+_getClass", "-version")
+ ProcessTools.executeTestJava("-XX:CompileCommand=option,*,ccstrlist,ControlIntrinsic,+_getClass", "-version")
.shouldHaveExitValue(1)
.shouldContain("CompileCommand: An error occurred during parsing")
.shouldContain("Error: Did not specify any method name")
@@ -51,36 +51,36 @@ public static void main(String[] args) throws Exception {
// corner case:
// ccstrlist could be a valid method name, so it is accepted in the well-formed case.
- ProcessTools.executeTestJvm("-XX:CompileCommand=option,*.ccstrlist,ccstrlist,ControlIntrinsic,+_getClass", "-version")
+ ProcessTools.executeTestJava("-XX:CompileCommand=option,*.ccstrlist,ccstrlist,ControlIntrinsic,+_getClass", "-version")
.shouldContain("CompileCommand: ControlIntrinsic *.ccstrlist const char* ControlIntrinsic")
.shouldHaveExitValue(0)
.shouldNotContain("# A fatal error has been detected by the Java Runtime Environment");
- ProcessTools.executeTestJvm("-XX:CompileCommand=option,*.*,ccstrlist,ControlIntrinsic,+_getClass", "-version")
+ ProcessTools.executeTestJava("-XX:CompileCommand=option,*.*,ccstrlist,ControlIntrinsic,+_getClass", "-version")
.shouldContain("CompileCommand: ControlIntrinsic *.* const char* ControlIntrinsic")
.shouldHaveExitValue(0)
.shouldNotContain("# A fatal error has been detected by the Java Runtime Environment");
- ProcessTools.executeTestJvm("-XX:CompileCommand=option,class,PrintIntrinsics", "-version")
+ ProcessTools.executeTestJava("-XX:CompileCommand=option,class,PrintIntrinsics", "-version")
.shouldHaveExitValue(0)
.shouldNotContain("# A fatal error has been detected by the Java Runtime Environment");
// corner case:
// PrintIntrinsics could be a valid method name, so it is accepted in the well-formed case.
- ProcessTools.executeTestJvm("-XX:CompileCommand=option,class.PrintIntrinsics,PrintIntrinsics", "-version")
+ ProcessTools.executeTestJava("-XX:CompileCommand=option,class.PrintIntrinsics,PrintIntrinsics", "-version")
.shouldContain("CompileCommand: PrintIntrinsics class.PrintIntrinsics bool PrintIntrinsics = true")
.shouldHaveExitValue(0)
.shouldNotContain("# A fatal error has been detected by the Java Runtime Environment");
// corner case:
// _dontinline_* is a valid method pattern, so it should be accepted
- ProcessTools.executeTestJvm("-XX:CompileCommand=dontinline,*::dontinline_*", "-version")
+ ProcessTools.executeTestJava("-XX:CompileCommand=dontinline,*::dontinline_*", "-version")
.shouldContain("CompileCommand: dontinline *.dontinline_* bool dontinline = true")
.shouldHaveExitValue(0)
.shouldNotContain("# A fatal error has been detected by the Java Runtime Environment");
- ProcessTools.executeTestJvm("-XX:CompileCommand=dontinline,*.dontinline", "-version")
+ ProcessTools.executeTestJava("-XX:CompileCommand=dontinline,*.dontinline", "-version")
.shouldContain("CompileCommand: dontinline *.dontinline bool dontinline = true")
.shouldHaveExitValue(0)
.shouldNotContain("Error: Did not specify any method name")
diff --git a/test/hotspot/jtreg/compiler/compilercontrol/parser/HugeDirectiveUtil.java b/test/hotspot/jtreg/compiler/compilercontrol/parser/HugeDirectiveUtil.java
index 6db9a99586296..d337266dd50d9 100644
--- a/test/hotspot/jtreg/compiler/compilercontrol/parser/HugeDirectiveUtil.java
+++ b/test/hotspot/jtreg/compiler/compilercontrol/parser/HugeDirectiveUtil.java
@@ -121,7 +121,7 @@ private static List getRandomDescriptors(
protected static OutputAnalyzer execute(String fileName) {
OutputAnalyzer output;
try {
- output = ProcessTools.executeTestJvm(
+ output = ProcessTools.executeTestJava(
"-XX:+UnlockDiagnosticVMOptions",
"-XX:CompilerDirectivesLimit=1000",
"-XX:CompilerDirectivesFile=" + fileName,
diff --git a/test/hotspot/jtreg/compiler/compilercontrol/share/scenario/Executor.java b/test/hotspot/jtreg/compiler/compilercontrol/share/scenario/Executor.java
index 0111d1e90a1f6..799fabf95090c 100644
--- a/test/hotspot/jtreg/compiler/compilercontrol/share/scenario/Executor.java
+++ b/test/hotspot/jtreg/compiler/compilercontrol/share/scenario/Executor.java
@@ -101,7 +101,7 @@ public List execute() {
vmInputArgs.length + vmOptions.size());
System.arraycopy(vmOptions.toArray(), 0, cmds, vmInputArgs.length,
vmOptions.size());
- output = ProcessTools.executeTestJvm(cmds);
+ output = ProcessTools.executeTestJava(cmds);
} catch (Throwable thr) {
throw new Error("Execution failed: " + thr.getMessage(), thr);
}
diff --git a/test/hotspot/jtreg/compiler/cpuflags/TestAESIntrinsicsOnSupportedConfig.java b/test/hotspot/jtreg/compiler/cpuflags/TestAESIntrinsicsOnSupportedConfig.java
index 4c56daebfb888..ac3a6d9a8c6b1 100644
--- a/test/hotspot/jtreg/compiler/cpuflags/TestAESIntrinsicsOnSupportedConfig.java
+++ b/test/hotspot/jtreg/compiler/cpuflags/TestAESIntrinsicsOnSupportedConfig.java
@@ -72,7 +72,7 @@ private boolean isTieredLevelGreaterThan(int level) {
* @throws Throwable
*/
private void testUseAES() throws Throwable {
- OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJvm(
+ OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava(
prepareArguments(prepareBooleanFlag(AESIntrinsicsBase
.USE_AES, true)));
final String errorMessage = "Case testUseAES failed";
@@ -103,7 +103,7 @@ private void testUseAES() throws Throwable {
*/
private void testUseAESUseSSE2() throws Throwable {
if (Platform.isX86() || Platform.isX64()) {
- OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJvm(
+ OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava(
prepareArguments(prepareBooleanFlag(AESIntrinsicsBase
.USE_AES_INTRINSICS, true),
prepareNumericFlag(AESIntrinsicsBase.USE_SSE, 2)));
@@ -132,7 +132,7 @@ private void testUseAESUseSSE2() throws Throwable {
*/
private void testNoUseAESUseSSE2() throws Throwable {
if (Platform.isX86() || Platform.isX64()) {
- OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJvm(
+ OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava(
prepareArguments(prepareBooleanFlag(AESIntrinsicsBase
.USE_AES, false),
prepareNumericFlag(AESIntrinsicsBase.USE_SSE, 2)));
@@ -158,7 +158,7 @@ private void testNoUseAESUseSSE2() throws Throwable {
* @throws Throwable
*/
private void testNoUseAES() throws Throwable {
- OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJvm(
+ OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava(
prepareArguments(prepareBooleanFlag(AESIntrinsicsBase
.USE_AES, false)));
final String errorMessage = "Case testNoUseAES failed";
@@ -180,7 +180,7 @@ private void testNoUseAES() throws Throwable {
* @throws Throwable
*/
private void testNoUseAESIntrinsic() throws Throwable {
- OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJvm(
+ OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava(
prepareArguments(prepareBooleanFlag(AESIntrinsicsBase
.USE_AES_INTRINSICS, false)));
final String errorMessage = "Case testNoUseAESIntrinsic failed";
diff --git a/test/hotspot/jtreg/compiler/cpuflags/TestAESIntrinsicsOnUnsupportedConfig.java b/test/hotspot/jtreg/compiler/cpuflags/TestAESIntrinsicsOnUnsupportedConfig.java
index 03016ea3dd6ac..fdc8f63f9e0f4 100644
--- a/test/hotspot/jtreg/compiler/cpuflags/TestAESIntrinsicsOnUnsupportedConfig.java
+++ b/test/hotspot/jtreg/compiler/cpuflags/TestAESIntrinsicsOnUnsupportedConfig.java
@@ -65,7 +65,7 @@ protected void runTestCases() throws Throwable {
* @throws Throwable
*/
private void testUseAESIntrinsics() throws Throwable {
- OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJvm(
+ OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava(
AESIntrinsicsBase.prepareArguments(prepareBooleanFlag(
AESIntrinsicsBase.USE_AES_INTRINSICS, true)));
final String errorMessage = "Case testUseAESIntrinsics failed";
@@ -89,7 +89,7 @@ private void testUseAESIntrinsics() throws Throwable {
* @throws Throwable
*/
private void testUseAES() throws Throwable {
- OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJvm(
+ OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava(
AESIntrinsicsBase.prepareArguments(prepareBooleanFlag
(AESIntrinsicsBase.USE_AES, true)));
final String errorMessage = "Case testUseAES failed";
diff --git a/test/hotspot/jtreg/compiler/gcbarriers/TestMembarDependencies.java b/test/hotspot/jtreg/compiler/gcbarriers/TestMembarDependencies.java
index bbd518c67565f..3678691b21860 100644
--- a/test/hotspot/jtreg/compiler/gcbarriers/TestMembarDependencies.java
+++ b/test/hotspot/jtreg/compiler/gcbarriers/TestMembarDependencies.java
@@ -43,7 +43,7 @@ public class TestMembarDependencies {
public static void main(String args[]) throws Exception {
if (args.length == 0) {
// For debugging, add "-XX:+TraceOptoPipelining"
- OutputAnalyzer oa = ProcessTools.executeTestJvm("-XX:+IgnoreUnrecognizedVMOptions",
+ OutputAnalyzer oa = ProcessTools.executeTestJava("-XX:+IgnoreUnrecognizedVMOptions",
"-XX:-TieredCompilation", "-XX:-BackgroundCompilation", "-XX:+PrintOpto",
"-XX:CompileCommand=compileonly,compiler.membars.TestMembarDependencies::test*",
"-XX:CompileCommand=dontinline,compiler.membars.TestMembarDependencies::test_m1",
diff --git a/test/hotspot/jtreg/compiler/intrinsics/base64/TestBase64.java b/test/hotspot/jtreg/compiler/intrinsics/base64/TestBase64.java
index 5d2651c328541..0d3c9569c3379 100644
--- a/test/hotspot/jtreg/compiler/intrinsics/base64/TestBase64.java
+++ b/test/hotspot/jtreg/compiler/intrinsics/base64/TestBase64.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -46,10 +46,13 @@
import java.util.Base64;
import java.util.Base64.Decoder;
import java.util.Base64.Encoder;
+import java.util.HexFormat;
import java.util.Objects;
import java.util.Random;
import java.util.Arrays;
+import static java.lang.String.format;
+
import compiler.whitebox.CompilerWhiteBoxTest;
import jdk.test.whitebox.code.Compiler;
import jtreg.SkippedException;
@@ -69,6 +72,8 @@ public static void main(String[] args) throws Exception {
warmup();
+ length_checks();
+
test0(FileType.ASCII, Base64Type.BASIC, Base64.getEncoder(), Base64.getDecoder(),"plain.txt", "baseEncode.txt", iters);
test0(FileType.ASCII, Base64Type.URLSAFE, Base64.getUrlEncoder(), Base64.getUrlDecoder(),"plain.txt", "urlEncode.txt", iters);
test0(FileType.ASCII, Base64Type.MIME, Base64.getMimeEncoder(), Base64.getMimeDecoder(),"plain.txt", "mimeEncode.txt", iters);
@@ -302,4 +307,118 @@ private static final byte getBadBase64Char(Base64Type b64Type) {
throw new InternalError("Internal test error: getBadBase64Char called with unknown Base64Type value");
}
}
+
+ static final int POSITIONS = 30_000;
+ static final int BASE_LENGTH = 256;
+ static final HexFormat HEX_FORMAT = HexFormat.of().withUpperCase().withDelimiter(" ");
+
+ static int[] plainOffsets = new int[POSITIONS + 1];
+ static byte[] plainBytes;
+ static int[] base64Offsets = new int[POSITIONS + 1];
+ static byte[] base64Bytes;
+
+ static {
+ // Set up ByteBuffer with characters to be encoded
+ int plainLength = 0;
+ for (int i = 0; i < plainOffsets.length; i++) {
+ plainOffsets[i] = plainLength;
+ int positionLength = (BASE_LENGTH + i) % 2048;
+ plainLength += positionLength;
+ }
+ // Put one of each possible byte value into ByteBuffer
+ plainBytes = new byte[plainLength];
+ for (int i = 0; i < plainBytes.length; i++) {
+ plainBytes[i] = (byte) i;
+ }
+
+ // Grab various slices of the ByteBuffer and encode them
+ ByteBuffer plainBuffer = ByteBuffer.wrap(plainBytes);
+ int base64Length = 0;
+ for (int i = 0; i < POSITIONS; i++) {
+ base64Offsets[i] = base64Length;
+ int offset = plainOffsets[i];
+ int length = plainOffsets[i + 1] - offset;
+ ByteBuffer plainSlice = plainBuffer.slice(offset, length);
+ base64Length += Base64.getEncoder().encode(plainSlice).remaining();
+ }
+
+ // Decode the slices created above and ensure lengths match
+ base64Offsets[base64Offsets.length - 1] = base64Length;
+ base64Bytes = new byte[base64Length];
+ for (int i = 0; i < POSITIONS; i++) {
+ int plainOffset = plainOffsets[i];
+ ByteBuffer plainSlice = plainBuffer.slice(plainOffset, plainOffsets[i + 1] - plainOffset);
+ ByteBuffer encodedBytes = Base64.getEncoder().encode(plainSlice);
+ int base64Offset = base64Offsets[i];
+ int expectedLength = base64Offsets[i + 1] - base64Offset;
+ if (expectedLength != encodedBytes.remaining()) {
+ throw new IllegalStateException(format("Unexpected length: %s <> %s", encodedBytes.remaining(), expectedLength));
+ }
+ encodedBytes.get(base64Bytes, base64Offset, expectedLength);
+ }
+ }
+
+ public static void length_checks() {
+ decodeAndCheck();
+ encodeDecode();
+ System.out.println("Test complete, no invalid decodes detected");
+ }
+
+ // Use ByteBuffer to cause decode() to use the base + offset form of decode
+ // Checks for bug reported in JDK-8321599 where padding characters appear
+ // within the beginning of the ByteBuffer *before* the offset. This caused
+ // the decoded string length to be off by 1 or 2 bytes.
+ static void decodeAndCheck() {
+ for (int i = 0; i < POSITIONS; i++) {
+ ByteBuffer encodedBytes = base64BytesAtPosition(i);
+ ByteBuffer decodedBytes = Base64.getDecoder().decode(encodedBytes);
+
+ if (!decodedBytes.equals(plainBytesAtPosition(i))) {
+ String base64String = base64StringAtPosition(i);
+ String plainHexString = plainHexStringAtPosition(i);
+ String decodedHexString = HEX_FORMAT.formatHex(decodedBytes.array(), decodedBytes.arrayOffset() + decodedBytes.position(), decodedBytes.arrayOffset() + decodedBytes.limit());
+ throw new IllegalStateException(format("Mismatch for %s\n\nExpected:\n%s\n\nActual:\n%s", base64String, plainHexString, decodedHexString));
+ }
+ }
+ }
+
+ // Encode strings of lengths 1-1K, decode, and ensure length and contents correct.
+ // This checks that padding characters are properly handled by decode.
+ static void encodeDecode() {
+ String allAs = "A(=)".repeat(128);
+ for (int i = 1; i <= 512; i++) {
+ String encStr = Base64.getEncoder().encodeToString(allAs.substring(0, i).getBytes());
+ String decStr = new String(Base64.getDecoder().decode(encStr));
+
+ if ((decStr.length() != allAs.substring(0, i).length()) ||
+ (!Objects.equals(decStr, allAs.substring(0, i)))
+ ) {
+ throw new IllegalStateException(format("Mismatch: Expected: %s\n Actual: %s\n", allAs.substring(0, i), decStr));
+ }
+ }
+ }
+
+ static ByteBuffer plainBytesAtPosition(int position) {
+ int offset = plainOffsets[position];
+ int length = plainOffsets[position + 1] - offset;
+ return ByteBuffer.wrap(plainBytes, offset, length);
+ }
+
+ static String plainHexStringAtPosition(int position) {
+ int offset = plainOffsets[position];
+ int length = plainOffsets[position + 1] - offset;
+ return HEX_FORMAT.formatHex(plainBytes, offset, offset + length);
+ }
+
+ static String base64StringAtPosition(int position) {
+ int offset = base64Offsets[position];
+ int length = base64Offsets[position + 1] - offset;
+ return new String(base64Bytes, offset, length, StandardCharsets.UTF_8);
+ }
+
+ static ByteBuffer base64BytesAtPosition(int position) {
+ int offset = base64Offsets[position];
+ int length = base64Offsets[position + 1] - offset;
+ return ByteBuffer.wrap(base64Bytes, offset, length);
+ }
}
diff --git a/test/hotspot/jtreg/compiler/intrinsics/bmi/BMITestRunner.java b/test/hotspot/jtreg/compiler/intrinsics/bmi/BMITestRunner.java
index 4060bacbfbaf9..159e471e3fcef 100644
--- a/test/hotspot/jtreg/compiler/intrinsics/bmi/BMITestRunner.java
+++ b/test/hotspot/jtreg/compiler/intrinsics/bmi/BMITestRunner.java
@@ -146,7 +146,7 @@ public static OutputAnalyzer runTest(Class extends Expr> expr,
new Integer(iterations).toString()
});
- OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJvm(vmOpts);
+ OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava(vmOpts);
outputAnalyzer.shouldHaveExitValue(0);
diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/FlagVMProcess.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/FlagVMProcess.java
index f15d4bec39840..cb362b3bbfbbf 100644
--- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/FlagVMProcess.java
+++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/FlagVMProcess.java
@@ -112,7 +112,7 @@ private void prepareVMFlags(Class> testClass, List additionalFlags) {
private void start() {
try {
// Run "flag" VM with White Box access to determine the test VM flags and if IR verification should be done.
- oa = ProcessTools.executeTestJvm(cmds);
+ oa = ProcessTools.executeTestJava(cmds);
} catch (Exception e) {
throw new TestRunException("Failed to execute TestFramework flag VM", e);
}
diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/TestVMProcess.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/TestVMProcess.java
index 2c63bbe95895c..04f8096d96917 100644
--- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/TestVMProcess.java
+++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/TestVMProcess.java
@@ -149,7 +149,7 @@ private void start() {
ProcessBuilder process = ProcessTools.createLimitedTestJavaProcessBuilder(cmds);
try {
// Calls 'main' of TestVM to run all specified tests with commands 'cmds'.
- // Use executeProcess instead of executeTestJvm as we have already added the JTreg VM and
+ // Use executeProcess instead of executeTestJava as we have already added the JTreg VM and
// Java options in prepareTestVMFlags().
oa = ProcessTools.executeProcess(process);
} catch (Exception e) {
diff --git a/test/hotspot/jtreg/compiler/loopopts/UseCountedLoopSafepointsTest.java b/test/hotspot/jtreg/compiler/loopopts/UseCountedLoopSafepointsTest.java
index a971c947ff466..effbbbe46bd28 100644
--- a/test/hotspot/jtreg/compiler/loopopts/UseCountedLoopSafepointsTest.java
+++ b/test/hotspot/jtreg/compiler/loopopts/UseCountedLoopSafepointsTest.java
@@ -59,9 +59,10 @@ public static void main (String args[]) {
private static void check(boolean enabled) {
OutputAnalyzer oa;
try {
- oa = ProcessTools.executeTestJvm("-XX:+UnlockDiagnosticVMOptions", "-Xbootclasspath/a:.",
- "-XX:" + (enabled ? "+" : "-") + "UseCountedLoopSafepoints",
- "-XX:+WhiteBoxAPI",
+ oa = ProcessTools.executeTestJava(
+ "-XX:+UnlockDiagnosticVMOptions", "-Xbootclasspath/a:.",
+ "-XX:" + (enabled ? "+" : "-") + "UseCountedLoopSafepoints",
+ "-XX:+WhiteBoxAPI",
"-XX:-Inline", "-Xbatch", "-XX:+PrintIdeal", "-XX:LoopUnrollLimit=0",
"-XX:CompileOnly=" + UseCountedLoopSafepoints.class.getName() + "::testMethod",
UseCountedLoopSafepoints.class.getName());
diff --git a/test/hotspot/jtreg/compiler/loopstripmining/CheckLoopStripMining.java b/test/hotspot/jtreg/compiler/loopstripmining/CheckLoopStripMining.java
index 48bd723a13ede..9e8ac6b013a06 100644
--- a/test/hotspot/jtreg/compiler/loopstripmining/CheckLoopStripMining.java
+++ b/test/hotspot/jtreg/compiler/loopstripmining/CheckLoopStripMining.java
@@ -38,7 +38,7 @@
public class CheckLoopStripMining {
public static void main(String args[]) throws Exception {
- ProcessTools.executeTestJvm("-XX:+UnlockDiagnosticVMOptions",
+ ProcessTools.executeTestJava("-XX:+UnlockDiagnosticVMOptions",
"-XX:+SafepointTimeout",
"-XX:+SafepointALot",
"-XX:+AbortVMOnSafepointTimeout",
@@ -54,7 +54,7 @@ public static void main(String args[]) throws Exception {
.shouldHaveExitValue(0)
.stdoutShouldContain("sum: 715827882");
- ProcessTools.executeTestJvm("-XX:+UnlockDiagnosticVMOptions",
+ ProcessTools.executeTestJava("-XX:+UnlockDiagnosticVMOptions",
"-XX:+SafepointTimeout",
"-XX:+SafepointALot",
"-XX:+AbortVMOnSafepointTimeout",
diff --git a/test/hotspot/jtreg/compiler/oracle/PrintIdealPhaseTest.java b/test/hotspot/jtreg/compiler/oracle/PrintIdealPhaseTest.java
index 13e36e049d1dc..d87f68efeee41 100644
--- a/test/hotspot/jtreg/compiler/oracle/PrintIdealPhaseTest.java
+++ b/test/hotspot/jtreg/compiler/oracle/PrintIdealPhaseTest.java
@@ -81,7 +81,7 @@ private void runTest(String cmdPhases, List expectedPhases, String logFi
options.add("-XX:CompileCommand=PrintIdealPhase," + getTestClass() + "::test," + cmdPhases);
options.add(getTestClass());
- OutputAnalyzer oa = ProcessTools.executeTestJvm(options);
+ OutputAnalyzer oa = ProcessTools.executeTestJava(options);
if (valid) {
oa.shouldHaveExitValue(0)
.shouldContain("CompileCommand: PrintIdealPhase compiler/oracle/PrintIdealPhaseTest$TestMain.test const char* PrintIdealPhase = '"+cmdPhases.replace(',', ' ')+"'")
diff --git a/test/hotspot/jtreg/compiler/print/CompileCommandMemLimit.java b/test/hotspot/jtreg/compiler/print/CompileCommandMemLimit.java
index b3be2c69820c9..d9f9aa3f7d4e4 100644
--- a/test/hotspot/jtreg/compiler/print/CompileCommandMemLimit.java
+++ b/test/hotspot/jtreg/compiler/print/CompileCommandMemLimit.java
@@ -105,7 +105,7 @@ private static void test(String include, String exclude) throws Exception {
}
options.add(getTestClass());
- OutputAnalyzer oa = ProcessTools.executeTestJvm(options);
+ OutputAnalyzer oa = ProcessTools.executeTestJava(options);
oa.reportDiagnosticSummary();
diff --git a/test/hotspot/jtreg/compiler/print/CompileCommandPrintCompilation.java b/test/hotspot/jtreg/compiler/print/CompileCommandPrintCompilation.java
index 1fb102acb07e5..358a5a0a6b35e 100644
--- a/test/hotspot/jtreg/compiler/print/CompileCommandPrintCompilation.java
+++ b/test/hotspot/jtreg/compiler/print/CompileCommandPrintCompilation.java
@@ -56,7 +56,7 @@ private static void test(String include, String exclude) throws Exception {
options.add("-XX:CompileCommand=PrintCompilation," + getTestMethod(include));
options.add(getTestClass());
- OutputAnalyzer oa = ProcessTools.executeTestJvm(options);
+ OutputAnalyzer oa = ProcessTools.executeTestJava(options);
oa.shouldHaveExitValue(0)
.shouldContain(getTestMethod(include))
diff --git a/test/hotspot/jtreg/compiler/print/CompileCommandPrintMemStat.java b/test/hotspot/jtreg/compiler/print/CompileCommandPrintMemStat.java
index 3d68f10723436..c0a99863fbf24 100644
--- a/test/hotspot/jtreg/compiler/print/CompileCommandPrintMemStat.java
+++ b/test/hotspot/jtreg/compiler/print/CompileCommandPrintMemStat.java
@@ -55,7 +55,7 @@ private static void test(String include, String exclude) throws Exception {
options.add("-XX:CompileCommand=MemStat," + getTestMethod(include) + ",print");
options.add(getTestClass());
- OutputAnalyzer oa = ProcessTools.executeTestJvm(options);
+ OutputAnalyzer oa = ProcessTools.executeTestJava(options);
// We expect two printouts for "PrintMemStat". A line at compilation time, and a line in a summary report
// that is printed when we exit. Both use the typical ::name format but use / as separator and also
diff --git a/test/hotspot/jtreg/compiler/print/PrintCompilation.java b/test/hotspot/jtreg/compiler/print/PrintCompilation.java
index c04b2bf5206da..3b3db304cefd2 100644
--- a/test/hotspot/jtreg/compiler/print/PrintCompilation.java
+++ b/test/hotspot/jtreg/compiler/print/PrintCompilation.java
@@ -47,7 +47,7 @@ public static void main(String[] args) throws Exception {
options.add("-XX:CompileCommand=compileonly," + getTestClass() + "::*");
options.add(getTestClass());
- OutputAnalyzer oa = ProcessTools.executeTestJvm(options);
+ OutputAnalyzer oa = ProcessTools.executeTestJava(options);
oa.shouldHaveExitValue(0)
.shouldContain(getTestMethod("method1"))
diff --git a/test/hotspot/jtreg/compiler/runtime/TestConstantsInError.java b/test/hotspot/jtreg/compiler/runtime/TestConstantsInError.java
index df221959bb54d..3daf12df87989 100644
--- a/test/hotspot/jtreg/compiler/runtime/TestConstantsInError.java
+++ b/test/hotspot/jtreg/compiler/runtime/TestConstantsInError.java
@@ -261,7 +261,7 @@ static void run(TestConstantsInError test) throws Exception {
c1Args.addAll(List.of("-XX:+TieredCompilation", "-XX:TieredStopAtLevel=1", "-XX:+TracePatching"));
c1Args.addAll(commonArgs);
- OutputAnalyzer outputC1 = ProcessTools.executeTestJvm(c1Args)
+ OutputAnalyzer outputC1 = ProcessTools.executeTestJava(c1Args)
.shouldHaveExitValue(0);
test.process(outputC1, true);
@@ -270,7 +270,7 @@ static void run(TestConstantsInError test) throws Exception {
c2Args.add("-XX:-TieredCompilation");
c2Args.addAll(commonArgs);
- OutputAnalyzer outputC2 = ProcessTools.executeTestJvm(c2Args)
+ OutputAnalyzer outputC2 = ProcessTools.executeTestJava(c2Args)
.shouldHaveExitValue(0);
test.process(outputC2, false);
diff --git a/test/hotspot/jtreg/compiler/vectorapi/TestVectorErgonomics.java b/test/hotspot/jtreg/compiler/vectorapi/TestVectorErgonomics.java
index eb25472370f92..4f9f8ca3bd22e 100644
--- a/test/hotspot/jtreg/compiler/vectorapi/TestVectorErgonomics.java
+++ b/test/hotspot/jtreg/compiler/vectorapi/TestVectorErgonomics.java
@@ -37,43 +37,43 @@
public class TestVectorErgonomics {
public static void main(String[] args) throws Throwable {
- ProcessTools.executeTestJvm("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions",
- "-XX:+EnableVectorReboxing", "-Xlog:compilation", "-version")
+ ProcessTools.executeTestJava("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions",
+ "-XX:+EnableVectorReboxing", "-Xlog:compilation", "-version")
.shouldHaveExitValue(0)
.shouldContain("EnableVectorReboxing=true");
- ProcessTools.executeTestJvm("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions",
- "-XX:+EnableVectorAggressiveReboxing", "-Xlog:compilation", "-version")
+ ProcessTools.executeTestJava("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions",
+ "-XX:+EnableVectorAggressiveReboxing", "-Xlog:compilation", "-version")
.shouldHaveExitValue(0)
.shouldContain("EnableVectorAggressiveReboxing=true");
- ProcessTools.executeTestJvm("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions",
- "-XX:-EnableVectorReboxing", "-Xlog:compilation", "-version")
+ ProcessTools.executeTestJava("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions",
+ "-XX:-EnableVectorReboxing", "-Xlog:compilation", "-version")
.shouldHaveExitValue(0)
.shouldContain("EnableVectorReboxing=false")
.shouldContain("EnableVectorAggressiveReboxing=false");
- ProcessTools.executeTestJvm("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions",
- "-XX:-EnableVectorAggressiveReboxing", "-Xlog:compilation", "-version")
+ ProcessTools.executeTestJava("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions",
+ "-XX:-EnableVectorAggressiveReboxing", "-Xlog:compilation", "-version")
.shouldHaveExitValue(0)
.shouldContain("EnableVectorAggressiveReboxing=false");
- ProcessTools.executeTestJvm("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions",
- "-XX:-EnableVectorSupport", "-Xlog:compilation", "-version")
+ ProcessTools.executeTestJava("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions",
+ "-XX:-EnableVectorSupport", "-Xlog:compilation", "-version")
.shouldHaveExitValue(0)
.shouldContain("EnableVectorSupport=false")
.shouldContain("EnableVectorReboxing=false")
.shouldContain("EnableVectorAggressiveReboxing=false");
- ProcessTools.executeTestJvm("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions",
- "-XX:-EnableVectorSupport", "-XX:+EnableVectorReboxing", "-Xlog:compilation", "-version")
+ ProcessTools.executeTestJava("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions",
+ "-XX:-EnableVectorSupport", "-XX:+EnableVectorReboxing", "-Xlog:compilation", "-version")
.shouldHaveExitValue(0)
.shouldContain("EnableVectorSupport=false")
.shouldContain("EnableVectorReboxing=false")
.shouldContain("EnableVectorAggressiveReboxing=false");
- ProcessTools.executeTestJvm("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions",
- "-XX:-EnableVectorSupport", "-XX:+EnableVectorAggressiveReboxing", "-Xlog:compilation", "-version")
+ ProcessTools.executeTestJava("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions",
+ "-XX:-EnableVectorSupport", "-XX:+EnableVectorAggressiveReboxing", "-Xlog:compilation", "-version")
.shouldHaveExitValue(0)
.shouldContain("EnableVectorSupport=false")
.shouldContain("EnableVectorReboxing=false")
diff --git a/test/hotspot/jtreg/gc/TestFillerObjectInstantiation.java b/test/hotspot/jtreg/gc/TestFillerObjectInstantiation.java
index bec7c4858f5a9..edb63f88af279 100644
--- a/test/hotspot/jtreg/gc/TestFillerObjectInstantiation.java
+++ b/test/hotspot/jtreg/gc/TestFillerObjectInstantiation.java
@@ -45,6 +45,6 @@ private static void testInstantiationFails(String classname) throws Exception {
public static void main(String[] args) throws Exception {
testInstantiationFails("jdk.internal.vm.FillerObject");
- testInstantiationFails("jdk.internal.vm.FillerArray");
+ testInstantiationFails("jdk.internal.vm.FillerElement");
}
}
diff --git a/test/hotspot/jtreg/gc/arguments/TestSoftMaxHeapSizeFlag.java b/test/hotspot/jtreg/gc/arguments/TestSoftMaxHeapSizeFlag.java
index a61e7545522d1..3d8f31db864d5 100644
--- a/test/hotspot/jtreg/gc/arguments/TestSoftMaxHeapSizeFlag.java
+++ b/test/hotspot/jtreg/gc/arguments/TestSoftMaxHeapSizeFlag.java
@@ -42,36 +42,36 @@ public class TestSoftMaxHeapSizeFlag {
public static void main(String args[]) throws Exception {
// Test default value
- ProcessTools.executeTestJvm("-Xms" + Xms, "-Xmx" + Xmx,
- "-XX:+PrintFlagsFinal", "-version")
+ ProcessTools.executeTestJava("-Xms" + Xms, "-Xmx" + Xmx,
+ "-XX:+PrintFlagsFinal", "-version")
.shouldMatch("SoftMaxHeapSize[ ]+=[ ]+" + Xmx)
.shouldHaveExitValue(0);
// Test setting small value
- ProcessTools.executeTestJvm("-Xms" + Xms, "-Xmx" + Xmx,
- "-XX:SoftMaxHeapSize=" + Xms,
- "-XX:+PrintFlagsFinal", "-version")
+ ProcessTools.executeTestJava("-Xms" + Xms, "-Xmx" + Xmx,
+ "-XX:SoftMaxHeapSize=" + Xms,
+ "-XX:+PrintFlagsFinal", "-version")
.shouldMatch("SoftMaxHeapSize[ ]+=[ ]+" + Xms)
.shouldHaveExitValue(0);
// Test setting middle value
- ProcessTools.executeTestJvm("-Xms" + Xms, "-Xmx" + Xmx,
- "-XX:SoftMaxHeapSize=" + betweenXmsAndXmx,
- "-XX:+PrintFlagsFinal", "-version")
+ ProcessTools.executeTestJava("-Xms" + Xms, "-Xmx" + Xmx,
+ "-XX:SoftMaxHeapSize=" + betweenXmsAndXmx,
+ "-XX:+PrintFlagsFinal", "-version")
.shouldMatch("SoftMaxHeapSize[ ]+=[ ]+" + betweenXmsAndXmx)
.shouldHaveExitValue(0);
// Test setting largest value
- ProcessTools.executeTestJvm("-Xms" + Xms, "-Xmx" + Xmx,
- "-XX:SoftMaxHeapSize=" + Xmx,
- "-XX:+PrintFlagsFinal", "-version")
+ ProcessTools.executeTestJava("-Xms" + Xms, "-Xmx" + Xmx,
+ "-XX:SoftMaxHeapSize=" + Xmx,
+ "-XX:+PrintFlagsFinal", "-version")
.shouldMatch("SoftMaxHeapSize[ ]+=[ ]+" + Xmx)
.shouldHaveExitValue(0);
// Test setting a too large value
- ProcessTools.executeTestJvm("-Xms" + Xms, "-Xmx" + Xmx,
- "-XX:SoftMaxHeapSize=" + greaterThanXmx,
- "-XX:+PrintFlagsFinal", "-version")
+ ProcessTools.executeTestJava("-Xms" + Xms, "-Xmx" + Xmx,
+ "-XX:SoftMaxHeapSize=" + greaterThanXmx,
+ "-XX:+PrintFlagsFinal", "-version")
.shouldContain("SoftMaxHeapSize must be less than or equal to the maximum heap size")
.shouldHaveExitValue(1);
}
diff --git a/test/hotspot/jtreg/gc/g1/ihop/TestIHOPErgo.java b/test/hotspot/jtreg/gc/g1/ihop/TestIHOPErgo.java
index a93232dd82e01..a962efba4602e 100644
--- a/test/hotspot/jtreg/gc/g1/ihop/TestIHOPErgo.java
+++ b/test/hotspot/jtreg/gc/g1/ihop/TestIHOPErgo.java
@@ -129,7 +129,7 @@ private static void runTest(int heapSize, int sleepTime, boolean isIhopAdaptive)
}
private static OutputAnalyzer executeTest(List options) throws Throwable, RuntimeException {
- OutputAnalyzer out = ProcessTools.executeTestJvm(options);
+ OutputAnalyzer out = ProcessTools.executeTestJava(options);
if (out.getExitValue() != 0) {
System.out.println(out.getOutput());
throw new RuntimeException("AppIHOP failed with exit code" + out.getExitValue());
diff --git a/test/hotspot/jtreg/gc/g1/ihop/TestIHOPStatic.java b/test/hotspot/jtreg/gc/g1/ihop/TestIHOPStatic.java
index c84374fa359c0..7f5259a0855b3 100644
--- a/test/hotspot/jtreg/gc/g1/ihop/TestIHOPStatic.java
+++ b/test/hotspot/jtreg/gc/g1/ihop/TestIHOPStatic.java
@@ -129,7 +129,7 @@ private static void runTest(int ihop, long pctToFill, long heapSize, boolean exp
Collections.addAll(options, COMMON_OPTIONS);
options.add(AppIHOP.class.getName());
- OutputAnalyzer out = ProcessTools.executeTestJvm(options);
+ OutputAnalyzer out = ProcessTools.executeTestJava(options);
if (out.getExitValue() != 0) {
System.out.println(out.getOutput());
diff --git a/test/hotspot/jtreg/gc/g1/logging/TestG1LoggingFailure.java b/test/hotspot/jtreg/gc/g1/logging/TestG1LoggingFailure.java
index befa34dea65d6..eb008f04e521c 100644
--- a/test/hotspot/jtreg/gc/g1/logging/TestG1LoggingFailure.java
+++ b/test/hotspot/jtreg/gc/g1/logging/TestG1LoggingFailure.java
@@ -63,7 +63,7 @@ public static void main(String[] args) throws Throwable {
}
private static void startVM(List options) throws Throwable, RuntimeException {
- OutputAnalyzer out = ProcessTools.executeTestJvm(options);
+ OutputAnalyzer out = ProcessTools.executeTestJava(options);
out.shouldNotContain("pure virtual method called");
diff --git a/test/hotspot/jtreg/gc/g1/plab/TestPLABEvacuationFailure.java b/test/hotspot/jtreg/gc/g1/plab/TestPLABEvacuationFailure.java
index ecceca21f2b81..4e18e29d1550e 100644
--- a/test/hotspot/jtreg/gc/g1/plab/TestPLABEvacuationFailure.java
+++ b/test/hotspot/jtreg/gc/g1/plab/TestPLABEvacuationFailure.java
@@ -108,7 +108,7 @@ private static void runTest(int wastePct, int plabSize, int parGCThreads, int he
"-XX:" + (plabIsFixed ? "-" : "+") + "ResizePLAB",
"-XX:MaxHeapSize=" + heapSize + "m");
testOptions.add(AppPLABEvacuationFailure.class.getName());
- OutputAnalyzer out = ProcessTools.executeTestJvm(testOptions);
+ OutputAnalyzer out = ProcessTools.executeTestJava(testOptions);
appPlabEvacFailureOutput = out.getOutput();
if (out.getExitValue() != 0) {
diff --git a/test/hotspot/jtreg/gc/g1/plab/TestPLABPromotion.java b/test/hotspot/jtreg/gc/g1/plab/TestPLABPromotion.java
index 785e07f8df52d..f0549623789b5 100644
--- a/test/hotspot/jtreg/gc/g1/plab/TestPLABPromotion.java
+++ b/test/hotspot/jtreg/gc/g1/plab/TestPLABPromotion.java
@@ -117,7 +117,7 @@ public static void main(String[] args) throws Throwable {
testCase.print(System.out);
List options = PLABUtils.prepareOptions(testCase.toOptions());
options.add(AppPLABPromotion.class.getName());
- OutputAnalyzer out = ProcessTools.executeTestJvm(options);
+ OutputAnalyzer out = ProcessTools.executeTestJava(options);
PLABUtils.commonCheck(out);
output = out.getOutput();
checkResults(testCase);
diff --git a/test/hotspot/jtreg/gc/g1/plab/TestPLABResize.java b/test/hotspot/jtreg/gc/g1/plab/TestPLABResize.java
index 0c9ebb12e8234..82246d790f457 100644
--- a/test/hotspot/jtreg/gc/g1/plab/TestPLABResize.java
+++ b/test/hotspot/jtreg/gc/g1/plab/TestPLABResize.java
@@ -87,7 +87,7 @@ public static void main(String[] args) throws Throwable {
testCase.print(System.out);
List options = PLABUtils.prepareOptions(testCase.toOptions());
options.add(AppPLABResize.class.getName());
- OutputAnalyzer out = ProcessTools.executeTestJvm(options);
+ OutputAnalyzer out = ProcessTools.executeTestJava(options);
PLABUtils.commonCheck(out);
checkResults(out.getOutput(), testCase);
}
diff --git a/test/hotspot/jtreg/gc/stress/gclocker/TestExcessGCLockerCollections.java b/test/hotspot/jtreg/gc/stress/gclocker/TestExcessGCLockerCollections.java
index d18548abdfe18..e819501aca34a 100644
--- a/test/hotspot/jtreg/gc/stress/gclocker/TestExcessGCLockerCollections.java
+++ b/test/hotspot/jtreg/gc/stress/gclocker/TestExcessGCLockerCollections.java
@@ -169,7 +169,7 @@ public static void main(String args[]) throws Exception {
finalArgs.addAll(Arrays.asList(args));
// GC and other options obtained from test framework.
- OutputAnalyzer output = ProcessTools.executeTestJvm(finalArgs);
+ OutputAnalyzer output = ProcessTools.executeTestJava(finalArgs);
output.shouldHaveExitValue(0);
//System.out.println("------------- begin stdout ----------------");
//System.out.println(output.getStdout());
diff --git a/test/hotspot/jtreg/gc/x/TestHighUsage.java b/test/hotspot/jtreg/gc/x/TestHighUsage.java
index 370d80318006a..32b0af19e4b79 100644
--- a/test/hotspot/jtreg/gc/x/TestHighUsage.java
+++ b/test/hotspot/jtreg/gc/x/TestHighUsage.java
@@ -85,15 +85,15 @@ public static void main(String[] args) throws Exception {
}
public static void main(String[] args) throws Exception {
- ProcessTools.executeTestJvm("-XX:+UseZGC",
- "-XX:-ZGenerational",
- "-XX:-ZProactive",
- "-Xms128M",
- "-Xmx128M",
- "-XX:ParallelGCThreads=1",
- "-XX:ConcGCThreads=1",
- "-Xlog:gc,gc+start",
- Test.class.getName())
+ ProcessTools.executeTestJava("-XX:+UseZGC",
+ "-XX:-ZGenerational",
+ "-XX:-ZProactive",
+ "-Xms128M",
+ "-Xmx128M",
+ "-XX:ParallelGCThreads=1",
+ "-XX:ConcGCThreads=1",
+ "-Xlog:gc,gc+start",
+ Test.class.getName())
.shouldNotContain("Allocation Stall")
.shouldContain("High Usage")
.shouldHaveExitValue(0);
diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/UncaughtNativeExceptionTest.java b/test/hotspot/jtreg/runtime/ErrorHandling/UncaughtNativeExceptionTest.java
index 3f26461643a6c..c32027f82b0f9 100644
--- a/test/hotspot/jtreg/runtime/ErrorHandling/UncaughtNativeExceptionTest.java
+++ b/test/hotspot/jtreg/runtime/ErrorHandling/UncaughtNativeExceptionTest.java
@@ -54,8 +54,8 @@ public static void main(String[] args) throws Throwable {
// and don't terminate abruptly due to stack overflow error
@Test
public void testNativeExceptionReporting() throws Exception {
- OutputAnalyzer output = ProcessTools.executeTestJvm(
- // executeTestJvm doesn't seem to forward 'java.library.path'
+ OutputAnalyzer output = ProcessTools.executeTestJava(
+ // executeTestJava doesn't seem to forward 'java.library.path'
"-Djava.library.path=" + System.getProperty("java.library.path"),
Crasher.class.getName());
diff --git a/test/hotspot/jtreg/runtime/LoadLibrary/TestSunBootLibraryPath.java b/test/hotspot/jtreg/runtime/LoadLibrary/TestSunBootLibraryPath.java
index 356064d79a486..deb2a000d3d52 100644
--- a/test/hotspot/jtreg/runtime/LoadLibrary/TestSunBootLibraryPath.java
+++ b/test/hotspot/jtreg/runtime/LoadLibrary/TestSunBootLibraryPath.java
@@ -46,11 +46,11 @@ public static void main(String[] args) throws Exception {
// Start a java process with this property set, and check that:
// 1) The process failed and
// 2) The error message was correct.
- ProcessTools.executeTestJvm("-Dsun.boot.library.path=" + tooLongPath,
- "TestSunBootLibraryPath",
- "'Do-Nothing'")
- .shouldNotHaveExitValue(0)
- .stdoutShouldContain(expectedErrorMessage);
+ ProcessTools.executeTestJava("-Dsun.boot.library.path=" + tooLongPath,
+ "TestSunBootLibraryPath",
+ "'Do-Nothing'")
+ .shouldNotHaveExitValue(0)
+ .stdoutShouldContain(expectedErrorMessage);
} else if (!args[0].equals("Do-Nothing")) {
// Fail, to prevent accidental args from causing accidental test passing.
throw new IllegalArgumentException("Test was launched with an invalid argument.");
diff --git a/test/hotspot/jtreg/runtime/Shutdown/ShutdownTest.java b/test/hotspot/jtreg/runtime/Shutdown/ShutdownTest.java
index 30b1ebe252aa8..68dc6b2e1a7e9 100644
--- a/test/hotspot/jtreg/runtime/Shutdown/ShutdownTest.java
+++ b/test/hotspot/jtreg/runtime/Shutdown/ShutdownTest.java
@@ -66,7 +66,7 @@ public static void main(String args[]) {
private static void startVM(String... options) throws Throwable {
// Combine VM flags given from command-line and your additional options
- OutputAnalyzer output = ProcessTools.executeTestJvm(options);
+ OutputAnalyzer output = ProcessTools.executeTestJava(options);
output.shouldContain("- ShutdownTest -");
output.shouldHaveExitValue(0);
diff --git a/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/modulepath/OptimizeModuleHandlingTest.java b/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/modulepath/OptimizeModuleHandlingTest.java
index eecc218a71aa3..53de474d9cd41 100644
--- a/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/modulepath/OptimizeModuleHandlingTest.java
+++ b/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/modulepath/OptimizeModuleHandlingTest.java
@@ -306,7 +306,7 @@ public static void runWithJarPath(String... extraRuntimeArgs) throws Exception {
.shouldNotContain(OPTIMIZE_ENABLED)
.shouldNotContain(OPTIMIZE_DISABLED);
});
- tty("10. run with CDS on, with main/test jars on classpath also with -Xbootclasspath/a: should not pass");
+ tty("10. run with CDS on, with main/test jars on classpath also with -Xbootclasspath/a: should pass");
TestCommon.run("-Xlog:cds",
"-cp", mainJar.toString() + PATH_SEPARATOR + testJar.toString(),
"-Xbootclasspath/a:", ".",
@@ -314,9 +314,51 @@ public static void runWithJarPath(String... extraRuntimeArgs) throws Exception {
.assertAbnormalExit(out -> {
out.shouldNotContain(CLASS_FOUND_MESSAGE)
.shouldNotContain(CLASS_NOT_FOUND_MESSAGE)
- .shouldContain(OPTIMIZE_DISABLED)
.shouldNotContain(OPTIMIZE_ENABLED)
.shouldContain(MAP_FAILED);
});
+
+ // Dump an archive with -Xbootclasspath/a
+ output = TestCommon.createArchive(
+ testJar.toString(),
+ appClasses,
+ "-Xbootclasspath/a:" + mainJar.toString());
+ TestCommon.checkDump(output);
+ tty("11. run with CDS on, with test jar on classpath and with main jar on -Xbootclasspath/a: should pass");
+ TestCommon.run("-Xlog:cds",
+ "-cp", testJar.toString(),
+ "-Xbootclasspath/a:" + mainJar.toString(),
+ MAIN_CLASS)
+ .assertNormalExit(out -> {
+ out.shouldNotContain(CLASS_FOUND_MESSAGE)
+ .shouldNotContain(CLASS_NOT_FOUND_MESSAGE)
+ .shouldContain(OPTIMIZE_ENABLED);
+ });
+ tty("12. run with CDS on, with main jar on classpath and with test jar on -Xbootclasspath/a: should not pass due to class paths mismatch");
+ TestCommon.run("-Xlog:cds",
+ "-cp", mainJar.toString(),
+ "-Xbootclasspath/a:" + testJar.toString(),
+ MAIN_CLASS)
+ .assertAbnormalExit(out -> {
+ out.shouldNotContain(CLASS_FOUND_MESSAGE)
+ .shouldNotContain(CLASS_NOT_FOUND_MESSAGE)
+ .shouldNotContain(OPTIMIZE_ENABLED)
+ .shouldContain(MAP_FAILED);
+ });
+ // Dump an archive with only -Xbootclasspath/a
+ output = TestCommon.createArchive(
+ null,
+ appClasses,
+ "-Xbootclasspath/a:" + mainJar.toString());
+ TestCommon.checkDump(output);
+ tty("13. run with CDS on, with the same -Xbootclasspath/a as dump time and adding a -cp with test.jar: should pass");
+ TestCommon.run("-Xlog:cds,class+load",
+ "-cp", testJar.toString(),
+ "-Xbootclasspath/a:" + mainJar.toString(),
+ MAIN_CLASS)
+ .assertNormalExit(out -> {
+ out.shouldMatch(MAIN_FROM_CDS)
+ .shouldContain(OPTIMIZE_ENABLED);
+ });
}
}
diff --git a/test/hotspot/jtreg/runtime/cds/serviceability/ReplaceCriticalClassesForSubgraphs.java b/test/hotspot/jtreg/runtime/cds/serviceability/ReplaceCriticalClassesForSubgraphs.java
index f7d50fd7fe6bf..71d984d3a638c 100644
--- a/test/hotspot/jtreg/runtime/cds/serviceability/ReplaceCriticalClassesForSubgraphs.java
+++ b/test/hotspot/jtreg/runtime/cds/serviceability/ReplaceCriticalClassesForSubgraphs.java
@@ -47,7 +47,8 @@ public String[] getTests() {
// CDS should not be disabled -- these critical classes cannot be replaced because
// JvmtiExport::early_class_hook_env() is false.
- "-subgraph java/lang/module/ResolvedModule jdk.internal.module.ArchivedModuleGraph",
+ "-subgraph java/lang/module/Configuration java.lang.module.Configuration",
+ "-subgraph java/lang/ModuleLayer java.lang.ModuleLayer",
"-subgraph java/lang/Integer java.lang.Integer$IntegerCache",
// Tests for archived full module graph. We cannot use whitebox, which requires appending to bootclasspath.
diff --git a/test/hotspot/jtreg/runtime/jni/FindClass/FindClassFromBoot.java b/test/hotspot/jtreg/runtime/jni/FindClass/FindClassFromBoot.java
index 06db9c07c73da..4f59af310bf52 100644
--- a/test/hotspot/jtreg/runtime/jni/FindClass/FindClassFromBoot.java
+++ b/test/hotspot/jtreg/runtime/jni/FindClass/FindClassFromBoot.java
@@ -42,7 +42,7 @@ public static void main(String... args) throws Exception {
Path patches = Paths.get(System.getProperty("test.classes"), "patches", "java.base");
String syspaths = System.getProperty("sun.boot.library.path") +
File.pathSeparator + System.getProperty("java.library.path");
- ProcessTools.executeTestJvm("-Dsun.boot.library.path=" + syspaths,
+ ProcessTools.executeTestJava("-Dsun.boot.library.path=" + syspaths,
"--patch-module", "java.base=" + patches.toString(),
"BootLoaderTest")
.shouldHaveExitValue(0);
diff --git a/test/hotspot/jtreg/runtime/jni/FindClassUtf8/FindClassUtf8.java b/test/hotspot/jtreg/runtime/jni/FindClassUtf8/FindClassUtf8.java
index 4f90838c10705..7b0a4cc46bf77 100644
--- a/test/hotspot/jtreg/runtime/jni/FindClassUtf8/FindClassUtf8.java
+++ b/test/hotspot/jtreg/runtime/jni/FindClassUtf8/FindClassUtf8.java
@@ -43,10 +43,10 @@ public final class FindClassUtf8 {
public static void main(String... args) throws Exception {
if (args.length == 1) {
// run java -Xcheck:jni FindClassUtf8 and check that the -Xcheck:jni message comes out.
- ProcessTools.executeTestJvm("-Djava.library.path=" + Utils.TEST_NATIVE_PATH,
- "-Xcheck:jni",
- "-XX:-CreateCoredumpOnCrash",
- "FindClassUtf8")
+ ProcessTools.executeTestJava("-Djava.library.path=" + Utils.TEST_NATIVE_PATH,
+ "-Xcheck:jni",
+ "-XX:-CreateCoredumpOnCrash",
+ "FindClassUtf8")
.shouldContain("JNI class name is not a valid UTF8 string")
.shouldNotHaveExitValue(0); // you get a core dump from -Xcheck:jni failures
} else {
diff --git a/test/hotspot/jtreg/runtime/jni/atExit/TestAtExit.java b/test/hotspot/jtreg/runtime/jni/atExit/TestAtExit.java
index a54eaedbad4b6..82d834c869cc1 100644
--- a/test/hotspot/jtreg/runtime/jni/atExit/TestAtExit.java
+++ b/test/hotspot/jtreg/runtime/jni/atExit/TestAtExit.java
@@ -61,13 +61,13 @@ public static void main(String[] args) throws Exception {
String jlp = "-Djava.library.path=" + Utils.TEST_NATIVE_PATH;
// First run will terminate via DestroyJavaVM
- OutputAnalyzer output = ProcessTools.executeTestJvm(jlp, main);
+ OutputAnalyzer output = ProcessTools.executeTestJava(jlp, main);
output.shouldNotContain("Unexpected");
output.shouldHaveExitValue(0);
output.reportDiagnosticSummary();
// Second run will terminate via System.exit()
- output = ProcessTools.executeTestJvm(jlp, main, "doExit");
+ output = ProcessTools.executeTestJava(jlp, main, "doExit");
output.shouldNotContain("Unexpected");
output.shouldHaveExitValue(0);
output.reportDiagnosticSummary();
diff --git a/test/hotspot/jtreg/runtime/jni/checked/TestCheckedJniExceptionCheck.java b/test/hotspot/jtreg/runtime/jni/checked/TestCheckedJniExceptionCheck.java
index e731bab63744c..3c6efeb9a2ddd 100644
--- a/test/hotspot/jtreg/runtime/jni/checked/TestCheckedJniExceptionCheck.java
+++ b/test/hotspot/jtreg/runtime/jni/checked/TestCheckedJniExceptionCheck.java
@@ -205,9 +205,9 @@ public static void main(String[] args) throws Throwable {
}
// launch and check output
- checkOuputForCorrectWarnings(ProcessTools.executeTestJvm("-Xcheck:jni",
- "-Djava.library.path=" + Utils.TEST_NATIVE_PATH,
- "TestCheckedJniExceptionCheck"));
+ checkOuputForCorrectWarnings(ProcessTools.executeTestJava("-Xcheck:jni",
+ "-Djava.library.path=" + Utils.TEST_NATIVE_PATH,
+ "TestCheckedJniExceptionCheck"));
}
}
diff --git a/test/hotspot/jtreg/runtime/jni/checked/TestCheckedReleaseArrayElements.java b/test/hotspot/jtreg/runtime/jni/checked/TestCheckedReleaseArrayElements.java
index 6395e3b9f0b30..6bc09b8a03451 100644
--- a/test/hotspot/jtreg/runtime/jni/checked/TestCheckedReleaseArrayElements.java
+++ b/test/hotspot/jtreg/runtime/jni/checked/TestCheckedReleaseArrayElements.java
@@ -45,7 +45,7 @@ public static void main(String[] args) throws Throwable {
if (args == null || args.length == 0) {
test();
} else {
- // Uses executeProcess() instead of executeTestJvm() to avoid passing options
+ // Uses executeProcess() instead of executeTestJava() to avoid passing options
// that might generate output on stderr (which should be empty for this test).
ProcessBuilder pb =
ProcessTools.createLimitedTestJavaProcessBuilder("-Xcheck:jni",
diff --git a/test/hotspot/jtreg/runtime/jni/nativeStack/TestNativeStack.java b/test/hotspot/jtreg/runtime/jni/nativeStack/TestNativeStack.java
index a7b8d945eecc8..d336097b8bda1 100644
--- a/test/hotspot/jtreg/runtime/jni/nativeStack/TestNativeStack.java
+++ b/test/hotspot/jtreg/runtime/jni/nativeStack/TestNativeStack.java
@@ -51,19 +51,19 @@ public class TestNativeStack {
public static void main(String[] args) throws Throwable {
// case 1: Trigger a JNI warning with Xcheck:jni
OutputAnalyzer oa =
- ProcessTools.executeTestJvm("-Xcheck:jni",
- "-Djava.library.path=" + Utils.TEST_NATIVE_PATH,
- "TestNativeStack$Main");
+ ProcessTools.executeTestJava("-Xcheck:jni",
+ "-Djava.library.path=" + Utils.TEST_NATIVE_PATH,
+ "TestNativeStack$Main");
oa.shouldHaveExitValue(0);
oa.shouldContain("WARNING in native method");
oa.shouldContain("thread_start");
oa.reportDiagnosticSummary();
// Case 2: Trigger a JNI FatalError call
- oa = ProcessTools.executeTestJvm("-XX:-CreateCoredumpOnCrash",
- "-Djava.library.path=" + Utils.TEST_NATIVE_PATH,
- "TestNativeStack$Main",
- "error");
+ oa = ProcessTools.executeTestJava("-XX:-CreateCoredumpOnCrash",
+ "-Djava.library.path=" + Utils.TEST_NATIVE_PATH,
+ "TestNativeStack$Main",
+ "error");
oa.shouldNotHaveExitValue(0);
oa.shouldContain("FATAL ERROR in native method");
oa.shouldContain("thread_start");
diff --git a/test/hotspot/jtreg/runtime/jni/registerNativesWarning/TestRegisterNativesWarning.java b/test/hotspot/jtreg/runtime/jni/registerNativesWarning/TestRegisterNativesWarning.java
index e22c75a6a449b..e3d043ee4af76 100644
--- a/test/hotspot/jtreg/runtime/jni/registerNativesWarning/TestRegisterNativesWarning.java
+++ b/test/hotspot/jtreg/runtime/jni/registerNativesWarning/TestRegisterNativesWarning.java
@@ -65,17 +65,17 @@ public static void main(String[] args) throws Exception {
String cp = Utils.TEST_CLASS_PATH;
String libp = Utils.TEST_NATIVE_PATH;
- OutputAnalyzer output = ProcessTools.executeTestJvm("-Djava.library.path=" + libp,
- Tester.class.getName());
+ OutputAnalyzer output = ProcessTools.executeTestJava("-Djava.library.path=" + libp,
+ Tester.class.getName());
output.shouldContain(warning);
output.shouldHaveExitValue(0);
output.reportDiagnosticSummary();
// If we run everything from the "boot" loader there should be no warning
- output = ProcessTools.executeTestJvm("-Djava.library.path=" + libp,
- "-Xbootclasspath/a:" + cp,
- "-Dsun.boot.library.path=" + libp,
- Tester.class.getName());
+ output = ProcessTools.executeTestJava("-Djava.library.path=" + libp,
+ "-Xbootclasspath/a:" + cp,
+ "-Dsun.boot.library.path=" + libp,
+ Tester.class.getName());
output.shouldNotContain(warning);
output.shouldHaveExitValue(0);
output.reportDiagnosticSummary();
diff --git a/test/hotspot/jtreg/runtime/os/TestTracePageSizes.java b/test/hotspot/jtreg/runtime/os/TestTracePageSizes.java
index e4ad27b46e5db..a94d9af4c27a5 100644
--- a/test/hotspot/jtreg/runtime/os/TestTracePageSizes.java
+++ b/test/hotspot/jtreg/runtime/os/TestTracePageSizes.java
@@ -350,7 +350,7 @@ public RangeWithPageSize(String start, String end, String pageSize, String thpEl
this.start = Long.parseUnsignedLong(start, 16);
this.end = Long.parseUnsignedLong(end, 16);
this.pageSize = Long.parseLong(pageSize);
- this.thpEligible = Integer.parseInt(thpEligible) == 1;
+ this.thpEligible = thpEligible == null ? false : (Integer.parseInt(thpEligible) == 1);
vmFlagHG = false;
vmFlagHT = false;
@@ -365,12 +365,11 @@ public RangeWithPageSize(String start, String end, String pageSize, String thpEl
}
}
- // When the THP policy is 'always' instead of 'madvise, the vmFlagHG property is false.
- // Check the THPeligible property instead.
- isTHP = !vmFlagHT && this.thpEligible;
+ // When the THP policy is 'always' instead of 'madvise, the vmFlagHG property is false,
+ // therefore also check thpEligible. If this is still causing problems in the future,
+ // we might have to check the AnonHugePages field.
- // vmFlagHG should imply isTHP
- assert !vmFlagHG || isTHP;
+ isTHP = vmFlagHG || this.thpEligible;
}
public long getPageSize() {
diff --git a/test/hotspot/jtreg/runtime/stringtable/StringTableCleaningTest.java b/test/hotspot/jtreg/runtime/stringtable/StringTableCleaningTest.java
index 4c54273c8c727..a62d61166fc0b 100644
--- a/test/hotspot/jtreg/runtime/stringtable/StringTableCleaningTest.java
+++ b/test/hotspot/jtreg/runtime/stringtable/StringTableCleaningTest.java
@@ -58,7 +58,7 @@ public static void main(String[] args) throws Exception {
subargs.addAll(List.of("-Xlog:gc,gc+start,stringtable*=trace", "-Xmx1g"));
subargs.add(Tester.class.getName());
subargs.addAll(Arrays.asList(args));
- OutputAnalyzer output = ProcessTools.executeTestJvm(subargs);
+ OutputAnalyzer output = ProcessTools.executeTestJava(subargs);
output.shouldHaveExitValue(0);
checkOutput(output);
}
diff --git a/test/hotspot/jtreg/sanity/BasicVMTest.java b/test/hotspot/jtreg/sanity/BasicVMTest.java
index a128cdfea379b..47773d63df42e 100644
--- a/test/hotspot/jtreg/sanity/BasicVMTest.java
+++ b/test/hotspot/jtreg/sanity/BasicVMTest.java
@@ -42,7 +42,7 @@ public static void main(String[] args) throws Exception {
"-X",
"-help");
for (String flag : flags) {
- ProcessTools.executeTestJvm(flag)
+ ProcessTools.executeTestJava(flag)
.shouldHaveExitValue(0);
}
}
diff --git a/test/hotspot/jtreg/serviceability/HeapDump/FullGCHeapDumpLimitTest.java b/test/hotspot/jtreg/serviceability/HeapDump/FullGCHeapDumpLimitTest.java
new file mode 100644
index 0000000000000..cf5481ddf2b93
--- /dev/null
+++ b/test/hotspot/jtreg/serviceability/HeapDump/FullGCHeapDumpLimitTest.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2023, Alibaba Group Holding Limited. 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
+ * @summary Test of option -XX:FullGCHeapDumpLimit
+ * @library /test/lib
+ * @run main/othervm -XX:+UseSerialGC -XX:+HeapDumpBeforeFullGC -XX:+HeapDumpAfterFullGC -XX:HeapDumpPath=test.hprof -XX:FullGCHeapDumpLimit=1 FullGCHeapDumpLimitTest
+ */
+
+import java.io.File;
+
+import jdk.test.lib.Asserts;
+
+public class FullGCHeapDumpLimitTest {
+
+ public static void main(String[] args) throws Exception {
+ System.gc();
+ Asserts.assertTrue(new File("test.hprof").exists());
+ Asserts.assertFalse(new File("test.hprof.1").exists());
+ }
+}
diff --git a/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/TestLambdaFormRetransformation.java b/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/TestLambdaFormRetransformation.java
index feacea07aab25..48c9ad1328e17 100644
--- a/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/TestLambdaFormRetransformation.java
+++ b/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/TestLambdaFormRetransformation.java
@@ -60,7 +60,7 @@ public class TestLambdaFormRetransformation {
public static void main(String args[]) throws Throwable {
Path agent = TestLambdaFormRetransformation.buildAgent();
- OutputAnalyzer oa = ProcessTools.executeTestJvm("-javaagent:" +
+ OutputAnalyzer oa = ProcessTools.executeTestJava("-javaagent:" +
agent.toAbsolutePath().toString(), "-version");
oa.shouldHaveExitValue(ExitCode.OK.value);
}
diff --git a/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/TestRedefineWithUnresolvedClass.java b/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/TestRedefineWithUnresolvedClass.java
index 2e36e33ce837b..4bcd2a4458872 100644
--- a/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/TestRedefineWithUnresolvedClass.java
+++ b/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/TestRedefineWithUnresolvedClass.java
@@ -79,7 +79,7 @@ private static void buildJar(String jarName) throws Throwable {
}
private static void launchTest() throws Throwable {
- OutputAnalyzer output = ProcessTools.executeTestJvm(
+ OutputAnalyzer output = ProcessTools.executeTestJava(
"-javaagent:" + testClasses + "UnresolvedClassAgent.jar",
"-Dtest.classes=" + testClasses,
"UnresolvedClassAgent");
diff --git a/test/hotspot/jtreg/serviceability/jvmti/vthread/GetThreadState/GetThreadStateTest.java b/test/hotspot/jtreg/serviceability/jvmti/vthread/GetThreadState/GetThreadStateTest.java
index 17c17b9b1f5c5..4ee1d1a0bfcae 100644
--- a/test/hotspot/jtreg/serviceability/jvmti/vthread/GetThreadState/GetThreadStateTest.java
+++ b/test/hotspot/jtreg/serviceability/jvmti/vthread/GetThreadState/GetThreadStateTest.java
@@ -25,20 +25,22 @@
* @test id=default
* @bug 8312498
* @summary Basic test for JVMTI GetThreadState with virtual threads
+ * @library /test/lib
* @run junit/othervm/native GetThreadStateTest
*/
/*
* @test id=no-vmcontinuations
* @requires vm.continuations
+ * @library /test/lib
* @run junit/othervm/native -XX:+UnlockExperimentalVMOptions -XX:-VMContinuations GetThreadStateTest
*/
import java.util.StringJoiner;
-import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.LockSupport;
+import jdk.test.lib.thread.VThreadPinner;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
@@ -75,10 +77,10 @@ void testTerminated() throws Exception {
*/
@Test
void testRunnable() throws Exception {
- var latch = new CountDownLatch(1);
+ var started = new AtomicBoolean();
var done = new AtomicBoolean();
var thread = Thread.ofVirtual().start(() -> {
- latch.countDown();
+ started.set(true);
// spin until done
while (!done.get()) {
@@ -87,7 +89,7 @@ void testRunnable() throws Exception {
});
try {
// wait for thread to start execution
- latch.await();
+ awaitTrue(started);
// thread should be runnable
int expected = JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_RUNNABLE;
@@ -107,17 +109,17 @@ void testRunnable() throws Exception {
*/
@Test
void testMonitorEnter() throws Exception {
- var latch = new CountDownLatch(1);
+ var started = new AtomicBoolean();
Object lock = new Object();
var thread = Thread.ofVirtual().unstarted(() -> {
- latch.countDown();
+ started.set(true);
synchronized (lock) { }
});
try {
synchronized (lock) {
// start thread and wait for it to start execution
thread.start();
- latch.await();
+ awaitTrue(started);
// thread should block on monitor enter
int expected = JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER;
@@ -137,19 +139,19 @@ void testMonitorEnter() throws Exception {
*/
@Test
void testObjectWait() throws Exception {
- var latch = new CountDownLatch(1);
+ var started = new AtomicBoolean();
Object lock = new Object();
var thread = Thread.ofVirtual().start(() -> {
synchronized (lock) {
- latch.countDown();
+ started.set(true);
try {
lock.wait();
} catch (InterruptedException e) { }
}
});
try {
- // wait for thread to own monitor
- latch.await();
+ // wait for thread to start execution
+ awaitTrue(started);
// thread should wait
int expected = JVMTI_THREAD_STATE_ALIVE |
@@ -179,19 +181,19 @@ void testObjectWait() throws Exception {
*/
@Test
void testObjectWaitMillis() throws Exception {
- var latch = new CountDownLatch(1);
+ var started = new AtomicBoolean();
Object lock = new Object();
var thread = Thread.ofVirtual().start(() -> {
synchronized (lock) {
- latch.countDown();
+ started.set(true);
try {
lock.wait(Long.MAX_VALUE);
} catch (InterruptedException e) { }
}
});
try {
- // wait for thread to own monitor
- latch.await();
+ // wait for thread to start execution
+ awaitTrue(started);
// thread should wait
int expected = JVMTI_THREAD_STATE_ALIVE |
@@ -221,17 +223,17 @@ void testObjectWaitMillis() throws Exception {
*/
@Test
void testPark() throws Exception {
- var latch = new CountDownLatch(1);
+ var started = new AtomicBoolean();
var done = new AtomicBoolean();
var thread = Thread.ofVirtual().start(() -> {
- latch.countDown();
+ started.set(true);
while (!done.get()) {
LockSupport.park();
}
});
try {
// wait for thread to start execution
- latch.await();
+ awaitTrue(started);
// thread should park
int expected = JVMTI_THREAD_STATE_ALIVE |
@@ -251,17 +253,17 @@ void testPark() throws Exception {
*/
@Test
void testParkNanos() throws Exception {
- var latch = new CountDownLatch(1);
+ var started = new AtomicBoolean();
var done = new AtomicBoolean();
var thread = Thread.ofVirtual().start(() -> {
- latch.countDown();
+ started.set(true);
while (!done.get()) {
LockSupport.parkNanos(Long.MAX_VALUE);
}
});
try {
// wait for thread to start execution
- latch.await();
+ awaitTrue(started);
// thread should park
int expected = JVMTI_THREAD_STATE_ALIVE |
@@ -281,20 +283,19 @@ void testParkNanos() throws Exception {
*/
@Test
void testParkWhenPinned() throws Exception {
- var latch = new CountDownLatch(1);
- Object lock = new Object();
+ var started = new AtomicBoolean();
var done = new AtomicBoolean();
var thread = Thread.ofVirtual().start(() -> {
- synchronized (lock) {
- latch.countDown();
+ VThreadPinner.runPinned(() -> {
+ started.set(true);
while (!done.get()) {
LockSupport.park();
}
- }
+ });
});
try {
- // wait for thread to own monitor
- latch.await();
+ // wait for thread to start execution
+ awaitTrue(started);
// thread should park
int expected = JVMTI_THREAD_STATE_ALIVE |
@@ -314,20 +315,19 @@ void testParkWhenPinned() throws Exception {
*/
@Test
void testParkNanosWhenPinned() throws Exception {
- var latch = new CountDownLatch(1);
- Object lock = new Object();
+ var started = new AtomicBoolean();
var done = new AtomicBoolean();
var thread = Thread.ofVirtual().start(() -> {
- synchronized (lock) {
- latch.countDown();
+ VThreadPinner.runPinned(() -> {
+ started.set(true);
while (!done.get()) {
LockSupport.parkNanos(Long.MAX_VALUE);
}
- }
+ });
});
try {
- // wait for thread to own monitor
- latch.await();
+ // wait for thread to start execution
+ awaitTrue(started);
// thread should park
int expected = JVMTI_THREAD_STATE_ALIVE |
@@ -342,6 +342,15 @@ void testParkNanosWhenPinned() throws Exception {
}
}
+ /**
+ * Waits for the boolean value to become true.
+ */
+ private static void awaitTrue(AtomicBoolean ref) throws Exception {
+ while (!ref.get()) {
+ Thread.sleep(20);
+ }
+ }
+
/**
* Asserts that the given thread has the expected JVMTI state.
*/
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/Agent_OnUnload/agentonunload001/TestDriver.java b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/Agent_OnUnload/agentonunload001/TestDriver.java
index 9d8bb71cbc503..4824569871230 100644
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/Agent_OnUnload/agentonunload001/TestDriver.java
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/Agent_OnUnload/agentonunload001/TestDriver.java
@@ -53,7 +53,7 @@
public class TestDriver {
public static void main(String[] args) throws Exception {
- OutputAnalyzer oa = ProcessTools.executeTestJvm(
+ OutputAnalyzer oa = ProcessTools.executeTestJava(
"-agentlib:agentonunload001=-waittime=5",
nsk.jvmti.Agent_OnUnload.agentonunload001.class.getName());
oa.shouldHaveExitValue(95);
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/general_functions/GF08/gf08t.java b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/general_functions/GF08/gf08t.java
index 9f0281533421a..964283d2b013f 100644
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/general_functions/GF08/gf08t.java
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/general_functions/GF08/gf08t.java
@@ -38,13 +38,13 @@ public static void main(String[] args) throws Exception {
.skip(3)
.collect(Collectors.joining(" "));
- OutputAnalyzer oa = ProcessTools.executeTestJvm(
+ OutputAnalyzer oa = ProcessTools.executeTestJava(
"-agentlib:" + libName + "=-waittime=5 setVerboseMode=yes",
className);
oa.shouldHaveExitValue(95);
oa.stdoutShouldContain(phrase);
- oa = ProcessTools.executeTestJvm(
+ oa = ProcessTools.executeTestJava(
"-agentlib:" + libName + "=-waittime=5 setVerboseMode=no",
"-verbose:" + verboseType,
className);
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/multienv/MA02/ma02t001/TestDriver.java b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/multienv/MA02/ma02t001/TestDriver.java
index 2aae25104fece..3d474c4e14913 100644
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/multienv/MA02/ma02t001/TestDriver.java
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/multienv/MA02/ma02t001/TestDriver.java
@@ -47,7 +47,7 @@
public class TestDriver {
public static void main(String[] args) throws Exception {
- OutputAnalyzer oa = ProcessTools.executeTestJvm(
+ OutputAnalyzer oa = ProcessTools.executeTestJava(
"-agentlib:ma02t001=-waittime=5",
"-agentlib:ma02t001a=-waittime=5",
nsk.jvmti.scenarios.multienv.MA02.ma02t001.class.getName());
diff --git a/test/jaxp/javax/xml/jaxp/unittest/common/dtd/DTDPropertiesTest.java b/test/jaxp/javax/xml/jaxp/unittest/common/dtd/DTDPropertiesTest.java
new file mode 100644
index 0000000000000..14215004937c3
--- /dev/null
+++ b/test/jaxp/javax/xml/jaxp/unittest/common/dtd/DTDPropertiesTest.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package common.dtd;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.stream.XMLInputFactory;
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import org.xml.sax.XMLReader;
+
+/*
+ * @test
+ * @bug 8322214
+ * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
+ * @run testng common.dtd.DTDPropertiesTest
+ * @summary Verifies the getProperty function on DTD properties works the same
+ * as before the property 'jdk.xml.dtd.support' was introduced.
+ */
+public class DTDPropertiesTest {
+ // Xerces Property
+ public static final String DISALLOW_DTD = "http://apache.org/xml/features/disallow-doctype-decl";
+
+ /*
+ * DataProvider for verifying Xerces' disallow-DTD feature
+ * Fields: property name, setting (null indicates not specified), expected
+ */
+ @DataProvider(name = "XercesProperty")
+ public Object[][] getXercesProperty() throws Exception {
+ return new Object[][] {
+ { DISALLOW_DTD, null, false},
+ { DISALLOW_DTD, true, true},
+ { DISALLOW_DTD, false, false},
+ };
+ }
+
+ /*
+ * DataProvider for verifying StAX's supportDTD feature
+ * Fields: property name, setting (null indicates not specified), expected
+ */
+ @DataProvider(name = "StAXProperty")
+ public Object[][] getStAXProperty() throws Exception {
+ return new Object[][] {
+ { XMLInputFactory.SUPPORT_DTD, null, true},
+ { XMLInputFactory.SUPPORT_DTD, true, true},
+ { XMLInputFactory.SUPPORT_DTD, false, false},
+ };
+ }
+
+ /**
+ * Verifies the disallow DTD feature with SAX.
+ *
+ * @param name the name of the property
+ * @param setting the setting of the property, null means not specified
+ * @param expected the expected value
+ * @throws Exception if the test fails
+ */
+ @Test(dataProvider = "XercesProperty")
+ public void testSAX(String name, Boolean setting, Boolean expected) throws Exception {
+ SAXParserFactory spf = SAXParserFactory.newDefaultInstance();
+ if (setting != null) {
+ spf.setFeature(name, setting);
+ }
+ Assert.assertEquals((Boolean)spf.getFeature(name), expected);
+ System.out.println(spf.getFeature(name));
+
+
+ SAXParser saxParser = spf.newSAXParser();
+ XMLReader reader = saxParser.getXMLReader();
+ Assert.assertEquals((Boolean)reader.getFeature(name), expected);
+ System.out.println(reader.getFeature(name));
+ }
+
+ /**
+ * Verifies the disallow DTD feature with DOM.
+ *
+ * @param name the name of the property
+ * @param setting the setting of the property, null means not specified
+ * @param expected the expected value
+ * @throws Exception if the test fails
+ */
+ @Test(dataProvider = "XercesProperty")
+ public void testDOM(String name, Boolean setting, Boolean expected) throws Exception {
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newDefaultInstance();
+ if (setting != null) {
+ dbf.setFeature(name, setting);
+ }
+ Assert.assertEquals((Boolean)dbf.getFeature(name), expected);
+ System.out.println(dbf.getFeature(name));
+ }
+
+ /**
+ * Verifies the StAX's supportDTD feature.
+ *
+ * @param name the name of the property
+ * @param setting the setting of the property, null means not specified
+ * @param expected the expected value
+ * @throws Exception if the test fails
+ */
+ @Test(dataProvider = "StAXProperty")
+ public void testStAX(String name, Boolean setting, Boolean expected) throws Exception {
+ XMLInputFactory xif = XMLInputFactory.newInstance();
+ if (setting != null) {
+ xif.setProperty(name, setting);
+ }
+ Assert.assertEquals((Boolean)xif.getProperty(name), expected);
+ System.out.println((Boolean)xif.getProperty(name));
+ }
+}
diff --git a/test/jaxp/javax/xml/jaxp/unittest/stream/XMLStreamExceptionTest/ExceptionCauseTest.java b/test/jaxp/javax/xml/jaxp/unittest/stream/XMLStreamExceptionTest/ExceptionCauseTest.java
new file mode 100644
index 0000000000000..e32527621f83c
--- /dev/null
+++ b/test/jaxp/javax/xml/jaxp/unittest/stream/XMLStreamExceptionTest/ExceptionCauseTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package stream.XMLStreamExceptionTest;
+
+import java.io.IOException;
+
+import javax.xml.stream.Location;
+import javax.xml.stream.XMLStreamException;
+
+import org.testng.Assert;
+import org.testng.annotations.Listeners;
+import org.testng.annotations.Test;
+
+/*
+ * @test
+ * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
+ * @run testng/othervm -DrunSecMngr=true -Djava.security.manager=allow stream.XMLStreamExceptionTest.ExceptionCauseTest
+ * @run testng/othervm stream.XMLStreamExceptionTest.ExceptionCauseTest
+ * @summary Test XMLStreamException constructor initializes chained exception
+ */
+@Listeners({jaxp.library.BasePolicy.class})
+public class ExceptionCauseTest {
+
+ @Test
+ public void testExceptionCause() {
+
+ // Create exception with cause
+ Throwable cause = new Throwable("cause");
+ Location location = new Location() {
+ public int getLineNumber() { return 0; }
+ public int getColumnNumber() { return 0; }
+ public int getCharacterOffset() { return 0; }
+ public String getPublicId() { return null; }
+ public String getSystemId() { return null; }
+ };
+ XMLStreamException e = new XMLStreamException("message", location, cause);
+
+ // Verify cause
+ Assert.assertSame(e.getCause(), cause, "XMLStreamException has the wrong cause");
+ }
+}
diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt
index 94a020585e475..b2354126c06bd 100644
--- a/test/jdk/ProblemList.txt
+++ b/test/jdk/ProblemList.txt
@@ -1,6 +1,6 @@
###########################################################################
#
-# Copyright (c) 2009, 2023, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2024, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
diff --git a/test/jdk/com/sun/jdi/BadAgentPath.java b/test/jdk/com/sun/jdi/BadAgentPath.java
index 68f28701cdc83..3ef0adadc84cf 100644
--- a/test/jdk/com/sun/jdi/BadAgentPath.java
+++ b/test/jdk/com/sun/jdi/BadAgentPath.java
@@ -38,7 +38,7 @@
public class BadAgentPath {
public static void main(String[] args) throws Throwable {
- OutputAnalyzer output = ProcessTools.executeTestJvm("-agentpath:/badAgent/agent", "-version");
+ OutputAnalyzer output = ProcessTools.executeTestJava("-agentpath:/badAgent/agent", "-version");
output.shouldContain("Could not find agent library /badAgent/agent");
}
}
diff --git a/test/jdk/com/sun/jdi/DoubleAgentTest.java b/test/jdk/com/sun/jdi/DoubleAgentTest.java
index 99ec6091aafea..ea2a109ed9b5f 100644
--- a/test/jdk/com/sun/jdi/DoubleAgentTest.java
+++ b/test/jdk/com/sun/jdi/DoubleAgentTest.java
@@ -44,7 +44,7 @@ public static void main(String[] args) throws Throwable {
String jdwpOption = "-agentlib:jdwp=transport=dt_socket"
+ ",server=y" + ",suspend=n" + ",address=*:0";
- OutputAnalyzer output = ProcessTools.executeTestJvm("-classpath",
+ OutputAnalyzer output = ProcessTools.executeTestJava("-classpath",
TEST_CLASSES,
jdwpOption, // Notice jdwpOption specified twice
jdwpOption,
diff --git a/test/jdk/com/sun/jdi/OnJcmdTest.java b/test/jdk/com/sun/jdi/OnJcmdTest.java
index 6cc417497c676..c7f93e6fb3167 100644
--- a/test/jdk/com/sun/jdi/OnJcmdTest.java
+++ b/test/jdk/com/sun/jdi/OnJcmdTest.java
@@ -51,12 +51,12 @@ private static String getListenerAddress() throws Exception {
public static void main(String[] args) throws Throwable {
// First check if we get the expected errors.
- OutputAnalyzer output = ProcessTools.executeTestJvm(
+ OutputAnalyzer output = ProcessTools.executeTestJava(
"-agentlib:jdwp=transport=dt_socket,address=any,onjcmd=y");
output.shouldContain("Can only use onjcmd with server=y");
output.shouldHaveExitValue(1);
- output = ProcessTools.executeTestJvm(
+ output = ProcessTools.executeTestJava(
"-agentlib:jdwp=transport=dt_socket,address=any,onjcmd=y,onthrow=a,launch=a");
output.shouldContain("Cannot combine onjcmd and launch suboptions");
output.shouldHaveExitValue(1);
diff --git a/test/jdk/com/sun/jdi/SuspendNoFlagTest.java b/test/jdk/com/sun/jdi/SuspendNoFlagTest.java
index 98b32063c74b2..31e717a63d0d3 100644
--- a/test/jdk/com/sun/jdi/SuspendNoFlagTest.java
+++ b/test/jdk/com/sun/jdi/SuspendNoFlagTest.java
@@ -38,7 +38,7 @@ public class SuspendNoFlagTest {
"test.classes", ".");
public static void main(String[] args) throws Throwable {
- OutputAnalyzer output = ProcessTools.executeTestJvm("-classpath",
+ OutputAnalyzer output = ProcessTools.executeTestJava("-classpath",
TEST_CLASSES,
"-agentlib:jdwp=transport=dt_socket,server=y,suspend=n",
"HelloWorld");
diff --git a/test/jdk/com/sun/tools/attach/BasicTests.java b/test/jdk/com/sun/tools/attach/BasicTests.java
index ff1849984d4db..833d7022ce893 100644
--- a/test/jdk/com/sun/tools/attach/BasicTests.java
+++ b/test/jdk/com/sun/tools/attach/BasicTests.java
@@ -101,7 +101,7 @@ private static void runTests(long pid) throws Throwable {
testClassDir + "Agent.jar",
testClassDir + "BadAgent.jar",
testClassDir + "RedefineAgent.jar" };
- OutputAnalyzer output = ProcessTools.executeTestJvm(args);
+ OutputAnalyzer output = ProcessTools.executeTestJava(args);
output.shouldHaveExitValue(0);
}
diff --git a/test/jdk/com/sun/tools/attach/PermissionTest.java b/test/jdk/com/sun/tools/attach/PermissionTest.java
index 3a4128a94724d..bf9473b0c8c3b 100644
--- a/test/jdk/com/sun/tools/attach/PermissionTest.java
+++ b/test/jdk/com/sun/tools/attach/PermissionTest.java
@@ -86,7 +86,7 @@ private static void runTests(long pid) throws Throwable {
"PermissionTest$TestMain",
Long.toString(pid),
"true" };
- OutputAnalyzer output = ProcessTools.executeTestJvm(args);
+ OutputAnalyzer output = ProcessTools.executeTestJava(args);
output.shouldHaveExitValue(0);
// Use a policy that will allow attach.
@@ -98,7 +98,7 @@ private static void runTests(long pid) throws Throwable {
"PermissionTest$TestMain",
Long.toString(pid),
"false" };
- output = ProcessTools.executeTestJvm(args);
+ output = ProcessTools.executeTestJava(args);
output.shouldHaveExitValue(0);
}
diff --git a/test/jdk/com/sun/tools/attach/ProviderTest.java b/test/jdk/com/sun/tools/attach/ProviderTest.java
index 5359d4241db03..e006bfd6b6d57 100644
--- a/test/jdk/com/sun/tools/attach/ProviderTest.java
+++ b/test/jdk/com/sun/tools/attach/ProviderTest.java
@@ -79,7 +79,7 @@ private static void runTests() throws Throwable {
"-classpath",
classpath,
"ProviderTest$TestMain" };
- OutputAnalyzer output = ProcessTools.executeTestJvm(args);
+ OutputAnalyzer output = ProcessTools.executeTestJava(args);
output.shouldHaveExitValue(0);
}
diff --git a/test/jdk/com/sun/tools/attach/TempDirTest.java b/test/jdk/com/sun/tools/attach/TempDirTest.java
index 2d932ffcf0e87..b9ce4acb14155 100644
--- a/test/jdk/com/sun/tools/attach/TempDirTest.java
+++ b/test/jdk/com/sun/tools/attach/TempDirTest.java
@@ -140,7 +140,7 @@ private static void launchTests(long pid, Path clientTmpDir) throws Throwable {
classpath,
"TempDirTest$TestMain",
Long.toString(pid) });
- OutputAnalyzer output = ProcessTools.executeTestJvm(args);
+ OutputAnalyzer output = ProcessTools.executeTestJava(args);
output.shouldHaveExitValue(0);
}
diff --git a/test/jdk/java/io/BufferedInputStream/TransferToTrusted.java b/test/jdk/java/io/BufferedInputStream/TransferToTrusted.java
new file mode 100644
index 0000000000000..c0bd7b53af819
--- /dev/null
+++ b/test/jdk/java/io/BufferedInputStream/TransferToTrusted.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.*;
+import java.util.Arrays;
+import java.util.Objects;
+import java.util.Random;
+
+/*
+ * @test
+ * @bug 8320971
+ * @summary Verify BufferedInputStream.buf is used directly by
+ * BufferedInputStream.implTransferTo() only when its OutputStream
+ * parameter is trusted
+ * @key randomness
+ * @run main/othervm --add-opens=java.base/java.io=ALL-UNNAMED TransferToTrusted
+ */
+public class TransferToTrusted {
+
+ private static final Random RND = new Random(System.nanoTime());
+
+ private static final class UntrustedOutputStream extends OutputStream {
+
+ UntrustedOutputStream() {
+ super();
+ }
+
+ @Override
+ public void write(byte[] b, int off, int len) {
+ Objects.checkFromIndexSize(off, len, b.length);
+ byte[] tmp = new byte[len];
+ RND.nextBytes(tmp);
+ System.arraycopy(tmp, 0, b, off, len);
+ }
+
+ @Override
+ public void write(int b) throws IOException {
+ write(new byte[]{(byte) b});
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ final int length = 128;
+ byte[] buf = new byte[length];
+ RND.nextBytes(buf);
+
+ var outputStreams = new OutputStream[]{
+ new ByteArrayOutputStream(),
+ new FileOutputStream(File.createTempFile(TransferToTrusted.class.getName(), null)),
+ new PipedOutputStream(new PipedInputStream(length)),
+ new UntrustedOutputStream()
+ };
+
+ for (var out : outputStreams) {
+ System.err.println("out: " + out.getClass().getName());
+
+ var bis = new BufferedInputStream(new ByteArrayInputStream(buf.clone()));
+ try (out; bis) {
+ bis.read();//need this to fill the BIS.buf in
+ bis.transferTo(out);
+ var internalBuffer = bis.getClass().getDeclaredField("buf");
+ internalBuffer.setAccessible(true);
+ if (!Arrays.equals(buf, Arrays.copyOf((byte[]) internalBuffer.get(bis), length))) {
+ throw new RuntimeException("Internal buffer was modified");
+ }
+ }
+ }
+ }
+}
diff --git a/test/jdk/java/io/File/TempDirDoesNotExist.java b/test/jdk/java/io/File/TempDirDoesNotExist.java
index bb59f6f9aeb72..f1c69f5865468 100644
--- a/test/jdk/java/io/File/TempDirDoesNotExist.java
+++ b/test/jdk/java/io/File/TempDirDoesNotExist.java
@@ -124,21 +124,21 @@ public static Stream counterSource() {
@ParameterizedTest
@MethodSource("tempDirSource")
public void existingMessage(List options) throws Exception {
- ProcessTools.executeTestJvm(options).shouldContain(WARNING)
+ ProcessTools.executeTestJava(options).shouldContain(WARNING)
.shouldHaveExitValue(0);
}
@ParameterizedTest
@MethodSource("noTempDirSource")
public void nonexistentMessage(List options) throws Exception {
- ProcessTools.executeTestJvm(options).shouldNotContain(WARNING)
+ ProcessTools.executeTestJava(options).shouldNotContain(WARNING)
.shouldHaveExitValue(0);
}
@ParameterizedTest
@MethodSource("counterSource")
public void messageCounter(List options) throws Exception {
- OutputAnalyzer originalOutput = ProcessTools.executeTestJvm(options);
+ OutputAnalyzer originalOutput = ProcessTools.executeTestJava(options);
long count = originalOutput.asLines().stream().filter(
line -> line.equalsIgnoreCase(WARNING)).count();
assertEquals(1, count,
diff --git a/test/jdk/java/io/FilePermission/MergeName.java b/test/jdk/java/io/FilePermission/MergeName.java
index c2eff765f2d1e..715b98512097d 100644
--- a/test/jdk/java/io/FilePermission/MergeName.java
+++ b/test/jdk/java/io/FilePermission/MergeName.java
@@ -81,7 +81,7 @@ private static void test(String file, String... actions) throws Exception {
}
content.add("};");
Files.write(Paths.get(file), content);
- ProcessTools.executeTestJvm("-Djava.security.manager",
+ ProcessTools.executeTestJava("-Djava.security.manager",
"-Djava.security.policy=" + file,
"MergeName",
"x",
diff --git a/test/jdk/java/io/FilePermission/ReadFileOnPath.java b/test/jdk/java/io/FilePermission/ReadFileOnPath.java
index acc66dac6abda..06e2c6c435ae0 100644
--- a/test/jdk/java/io/FilePermission/ReadFileOnPath.java
+++ b/test/jdk/java/io/FilePermission/ReadFileOnPath.java
@@ -87,7 +87,7 @@ static void test(String... args) throws Exception {
cmds.addAll(List.of(
"x", "modules/m", "modules/m/base", "modules/m/p/child",
"-", "child", "/base", "../base"));
- ProcessTools.executeTestJvm(cmds.toArray(new String[cmds.size()]))
+ ProcessTools.executeTestJava(cmds.toArray(new String[cmds.size()]))
.shouldHaveExitValue(0);
}
}
diff --git a/test/jdk/java/io/SequenceInputStream/TransferTo.java b/test/jdk/java/io/SequenceInputStream/TransferTo.java
index a39d2c1e0136b..4c8ff71a4f3cc 100644
--- a/test/jdk/java/io/SequenceInputStream/TransferTo.java
+++ b/test/jdk/java/io/SequenceInputStream/TransferTo.java
@@ -24,6 +24,7 @@
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
+import java.io.IOException;
import java.io.OutputStream;
import java.io.SequenceInputStream;
import java.util.Arrays;
@@ -39,6 +40,7 @@
import static java.lang.String.format;
import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotEquals;
import static org.testng.Assert.assertThrows;
import static org.testng.Assert.assertTrue;
@@ -126,6 +128,49 @@ public void testStreamContents() throws Exception {
outputStreamProvider, createRandomBytes(4096, 0), 0, 4096);
}
+ /*
+ * Special case: Assert subsequent input stream is read when preceding stream already was MAX_VALUE long.
+ * Note: Not testing actual content as it requires multiple GBs of memory and long time.
+ */
+ @Test
+ public void testHugeStream() throws Exception {
+ InputStream is1 = repeat(0, Long.MAX_VALUE);
+ InputStream is2 = repeat(0, 1);
+ assertNotEquals(is1.available(), 0);
+ assertNotEquals(is2.available(), 0);
+ SequenceInputStream sis = new SequenceInputStream(is1, is2);
+ OutputStream nos = OutputStream.nullOutputStream();
+ sis.transferTo(nos);
+ assertEquals(is1.available(), 0);
+ assertEquals(is2.available(), 0);
+ }
+
+ /*
+ * Produces an input stream that returns b count times.
+ * Builds a dysfunctional mock that solely implements
+ * available() and transferTo() particually,
+ * but fails with any other operation.
+ */
+ private static InputStream repeat(int b, long count) {
+ return new InputStream() {
+ private long pos;
+ @Override
+ public int available() throws IOException {
+ return (int) Math.min(count - pos, Integer.MAX_VALUE);
+ }
+ @Override
+ public int read() throws IOException {
+ throw new UnsupportedOperationException();
+ }
+ @Override
+ public long transferTo(OutputStream os) throws IOException {
+ // skipping actual writing to os to spare time
+ pos += count;
+ return count;
+ }
+ };
+ }
+
/*
* Asserts that the transferred content is correct, i.e., compares the bytes
* actually transferred to those expected. The position of the input and
diff --git a/test/jdk/java/lang/ClassLoader/securityManager/ClassLoaderTest.java b/test/jdk/java/lang/ClassLoader/securityManager/ClassLoaderTest.java
index 08342caeb75d1..b25dcda7841a2 100644
--- a/test/jdk/java/lang/ClassLoader/securityManager/ClassLoaderTest.java
+++ b/test/jdk/java/lang/ClassLoader/securityManager/ClassLoaderTest.java
@@ -239,7 +239,7 @@ private void execute(String[] args, String status, String msg) throws Exception
if (s.contains(" ")) { throw new RuntimeException("No spaces in args");}
return !s.isEmpty();
}).toArray(String[]::new);
- String out = ProcessTools.executeTestJvm(safeArgs).getOutput();
+ String out = ProcessTools.executeTestJava(safeArgs).getOutput();
// Handle response.
if ("PASS".equals(status) && out.contains(msg)) {
System.out.println("PASS: Expected Result: " + msg);
diff --git a/test/jdk/java/lang/RuntimeTests/shutdown/ShutdownHooks.java b/test/jdk/java/lang/RuntimeTests/shutdown/ShutdownHooks.java
index 6b2dc7b4dbfe7..36d3878fb41d5 100644
--- a/test/jdk/java/lang/RuntimeTests/shutdown/ShutdownHooks.java
+++ b/test/jdk/java/lang/RuntimeTests/shutdown/ShutdownHooks.java
@@ -61,7 +61,7 @@ public void testShutdownHooks() throws Exception {
// Run in a new process in order to evaluate shutdown hook results
String[] testCommand = new String[] {"-classpath", TEST_CLASSES,
ShutdownHooksProcess.class.getName()};
- ProcessTools.executeTestJvm(testCommand).shouldHaveExitValue(0);
+ ProcessTools.executeTestJava(testCommand).shouldHaveExitValue(0);
String errorMsg = "File exists despite shutdown hook has been run";
assertFalse(Files.exists(TEST_FILE.toPath()), errorMsg);
diff --git a/test/jdk/java/lang/ScopedValue/StressStackOverflow.java b/test/jdk/java/lang/ScopedValue/StressStackOverflow.java
index a1254c7fef792..863ad189c3577 100644
--- a/test/jdk/java/lang/ScopedValue/StressStackOverflow.java
+++ b/test/jdk/java/lang/ScopedValue/StressStackOverflow.java
@@ -66,7 +66,7 @@ static class TestFailureException extends RuntimeException {
TestFailureException(String s) { super(s); }
}
- static final long DURATION_IN_NANOS = Duration.ofMinutes(2).toNanos();
+ static final long DURATION_IN_NANOS = Duration.ofMinutes(1).toNanos();
// Test the ScopedValue recovery mechanism for stack overflows. We implement both Callable
// and Runnable interfaces. Which one gets tested depends on the constructor argument.
diff --git a/test/jdk/java/lang/StringBuilder/StringBufferRepeat.java b/test/jdk/java/lang/StringBuilder/StringBufferRepeat.java
index 2d1f3c64f60cc..d78066fb4170e 100644
--- a/test/jdk/java/lang/StringBuilder/StringBufferRepeat.java
+++ b/test/jdk/java/lang/StringBuilder/StringBufferRepeat.java
@@ -29,7 +29,7 @@
/**
* @test
- * @bug 8302323
+ * @bug 8302323 8322512
* @summary Test StringBuffer.repeat sanity tests
* @run testng/othervm -XX:-CompactStrings StringBufferRepeat
* @run testng/othervm -XX:+CompactStrings StringBufferRepeat
@@ -129,6 +129,19 @@ public void sanity() {
expected = "\u0000\u0000\u0000\u0000\u0000\u0000\u0020\u0020\u0020\u0020\u0020\u0020\u2461\u2462\u2462\u2462\u2462\u2462\udbff\udfff\udbff\udfff\udbff\udfff\udbff\udfff\udbff\udfff\udbff\udfff";
assertEquals(expected, sb.toString());
+ // toStringCache
+
+ sb.setLength(0);
+ sb.toString();
+ sb.repeat('*', 5);
+ expected = "*****";
+ assertEquals(sb.toString(), expected);
+ sb.setLength(0);
+ sb.toString();
+ sb.repeat("*", 5);
+ assertEquals(sb.toString(), expected);
+
+
}
public void exceptions() {
diff --git a/test/jdk/java/lang/Thread/virtual/CarrierThreadWaits.java b/test/jdk/java/lang/Thread/virtual/CarrierThreadWaits.java
index a94a5de3ce0d6..d1d5e72204f0f 100644
--- a/test/jdk/java/lang/Thread/virtual/CarrierThreadWaits.java
+++ b/test/jdk/java/lang/Thread/virtual/CarrierThreadWaits.java
@@ -40,7 +40,6 @@
import java.lang.management.LockInfo;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
-import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -55,38 +54,53 @@ class CarrierThreadWaits {
void testCarrierThreadWaiting() throws Exception {
try (ForkJoinPool pool = new ForkJoinPool(1)) {
var carrierRef = new AtomicReference();
+ var vthreadRef = new AtomicReference();
+
Executor scheduler = task -> {
pool.submit(() -> {
- carrierRef.set(Thread.currentThread());
+ Thread carrier = Thread.currentThread();
+ carrierRef.set(carrier);
+ Thread vthread = vthreadRef.get();
+
+ System.err.format("%s run task (%s) ...%n", carrier, vthread);
task.run();
+ System.err.format("%s task done (%s)%n", carrier, vthread);
});
};
// start a virtual thread that spins and remains mounted until "done"
- var latch = new CountDownLatch(1);
+ var started = new AtomicBoolean();
var done = new AtomicBoolean();
Thread.Builder builder = ThreadBuilders.virtualThreadBuilder(scheduler);
- Thread vthread = builder.start(() -> {
- latch.countDown();
+ Thread vthread = builder.unstarted(() -> {
+ started.set(true);
while (!done.get()) {
Thread.onSpinWait();
}
});
-
- // wait for virtual thread to execute
- latch.await();
+ vthreadRef.set(vthread);
+ vthread.start();
try {
- long carrierId = carrierRef.get().threadId();
+ // wait for virtual thread to start
+ while (!started.get()) {
+ Thread.sleep(10);
+ }
+
+ Thread carrier = carrierRef.get();
+
+ long carrierId = carrier.threadId();
long vthreadId = vthread.threadId();
// carrier thread should be on WAITING on virtual thread
ThreadInfo ti = ManagementFactory.getThreadMXBean().getThreadInfo(carrierId);
- assertTrue(ti.getThreadState() == Thread.State.WAITING);
- assertEquals(vthread.getClass().getName(), ti.getLockInfo().getClassName());
- assertTrue(ti.getLockInfo().getIdentityHashCode() == System.identityHashCode(vthread));
- assertTrue(ti.getLockOwnerId() == vthreadId);
-
+ Thread.State state = ti.getThreadState();
+ LockInfo lockInfo = ti.getLockInfo();
+ assertEquals(Thread.State.WAITING, state);
+ assertNotNull(lockInfo);
+ assertEquals(vthread.getClass().getName(), lockInfo.getClassName());
+ assertEquals(System.identityHashCode(vthread), lockInfo.getIdentityHashCode());
+ assertEquals(vthreadId, ti.getLockOwnerId());
} finally {
done.set(true);
}
diff --git a/test/jdk/java/lang/Thread/virtual/GetStackTraceWhenRunnable.java b/test/jdk/java/lang/Thread/virtual/GetStackTraceWhenRunnable.java
index 4cf7deecb3607..38760eb52a8f0 100644
--- a/test/jdk/java/lang/Thread/virtual/GetStackTraceWhenRunnable.java
+++ b/test/jdk/java/lang/Thread/virtual/GetStackTraceWhenRunnable.java
@@ -29,35 +29,34 @@
*/
import java.io.IOException;
-import java.nio.channels.ClosedSelectorException;
-import java.nio.channels.Selector;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.LockSupport;
public class GetStackTraceWhenRunnable {
public static void main(String[] args) throws Exception {
- try (Selector sel = Selector.open()) {
- // start thread1 and wait for it to park
- Thread thread1 = Thread.startVirtualThread(LockSupport::park);
- while (thread1.getState() != Thread.State.WAITING) {
- Thread.sleep(20);
- }
+ // start thread1 and wait for it to park
+ Thread thread1 = Thread.startVirtualThread(LockSupport::park);
+ while (thread1.getState() != Thread.State.WAITING) {
+ Thread.sleep(20);
+ }
- // start thread2 to pin the carrier thread
- CountDownLatch latch = new CountDownLatch(1);
- Thread thread2 = Thread.startVirtualThread(() -> {
- latch.countDown();
- try {
- sel.select();
- } catch (ClosedSelectorException e) {
- // expected
- } catch (IOException ioe) {
- ioe.printStackTrace();
- }
- });
- latch.await(); // wait for thread2 to run
+ // start thread2 to pin the carrier thread
+ var started = new AtomicBoolean();
+ var done = new AtomicBoolean();
+ Thread thread2 = Thread.startVirtualThread(() -> {
+ started.set(true);
+ while (!done.get()) {
+ Thread.onSpinWait();
+ }
+ });
+ try {
+ // wait for thread2 to start
+ while (!started.get()) {
+ Thread.sleep(10);
+ }
// unpark thread1 and check that it is "stuck" in the runnable state
// (the carrier thread is pinned, no other virtual thread can run)
@@ -73,6 +72,10 @@ public static void main(String[] args) throws Exception {
for (StackTraceElement e : stack) {
System.out.println(e);
}
+ } finally {
+ done.set(true);
+ thread2.join();
+ thread1.join();
}
}
diff --git a/test/jdk/java/lang/Thread/virtual/JfrEvents.java b/test/jdk/java/lang/Thread/virtual/JfrEvents.java
index 0cdd6a529d135..282a8959fe879 100644
--- a/test/jdk/java/lang/Thread/virtual/JfrEvents.java
+++ b/test/jdk/java/lang/Thread/virtual/JfrEvents.java
@@ -26,12 +26,12 @@
* @summary Basic test for JFR jdk.VirtualThreadXXX events
* @requires vm.continuations
* @modules jdk.jfr java.base/java.lang:+open
- * @run junit/othervm JfrEvents
+ * @library /test/lib
+ * @run junit/othervm --enable-native-access=ALL-UNNAMED JfrEvents
*/
import java.io.IOException;
import java.nio.file.Path;
-import java.time.Duration;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;
@@ -39,20 +39,27 @@
import java.util.concurrent.Executors;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.LockSupport;
+import java.util.function.Consumer;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
import jdk.jfr.EventType;
import jdk.jfr.Recording;
import jdk.jfr.consumer.RecordedEvent;
import jdk.jfr.consumer.RecordingFile;
+import jdk.test.lib.thread.VThreadPinner;
+import jdk.test.lib.thread.VThreadRunner.ThrowingRunnable;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
import static org.junit.jupiter.api.Assertions.*;
class JfrEvents {
- private static final Object lock = new Object();
/**
* Test jdk.VirtualThreadStart and jdk.VirtualThreadEnd events.
@@ -85,45 +92,90 @@ void testVirtualThreadStartAndEnd() throws Exception {
}
}
+ /**
+ * Arguments for testVirtualThreadPinned to test jdk.VirtualThreadPinned event.
+ * [0] label/description
+ * [1] the operation to park/wait
+ * [2] the Thread.State when parked/waiting
+ * [3] the action to unpark/notify the thread
+ */
+ static Stream pinnedCases() {
+ Object lock = new Object();
+
+ // park with native frame on stack
+ var finish1 = new AtomicBoolean();
+ var parkWhenPinned = Arguments.of(
+ "LockSupport.park when pinned",
+ (ThrowingRunnable) () -> {
+ VThreadPinner.runPinned(() -> {
+ while (!finish1.get()) {
+ LockSupport.park();
+ }
+ });
+ },
+ Thread.State.WAITING,
+ (Consumer) t -> {
+ finish1.set(true);
+ LockSupport.unpark(t);
+ }
+ );
+
+ // timed park with native frame on stack
+ var finish2 = new AtomicBoolean();
+ var timedParkWhenPinned = Arguments.of(
+ "LockSupport.parkNanos when pinned",
+ (ThrowingRunnable) () -> {
+ VThreadPinner.runPinned(() -> {
+ while (!finish2.get()) {
+ LockSupport.parkNanos(Long.MAX_VALUE);
+ }
+ });
+ },
+ Thread.State.TIMED_WAITING,
+ (Consumer) t -> {
+ finish2.set(true);
+ LockSupport.unpark(t);
+ }
+ );
+
+ return Stream.of(parkWhenPinned, timedParkWhenPinned);
+ }
+
/**
* Test jdk.VirtualThreadPinned event.
*/
- @Test
- void testVirtualThreadPinned() throws Exception {
- Runnable[] parkers = new Runnable[] {
- () -> LockSupport.park(),
- () -> LockSupport.parkNanos(Duration.ofDays(1).toNanos())
- };
+ @ParameterizedTest
+ @MethodSource("pinnedCases")
+ void testVirtualThreadPinned(String label,
+ ThrowingRunnable parker,
+ Thread.State expectedState,
+ Consumer unparker) throws Exception {
try (Recording recording = new Recording()) {
recording.enable("jdk.VirtualThreadPinned");
recording.start();
- try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
- for (Runnable parker : parkers) {
- // execute parking task in virtual thread
- var threadRef = new AtomicReference();
- executor.submit(() -> {
- threadRef.set(Thread.currentThread());
- synchronized (lock) {
- parker.run(); // should pin carrier
- }
- });
-
- // wait for the task to start and the virtual thread to park
- Thread thread;
- while ((thread = threadRef.get()) == null) {
- Thread.sleep(10);
- }
+ try {
+ var exception = new AtomicReference();
+ var thread = Thread.ofVirtual().start(() -> {
try {
- Thread.State state = thread.getState();
- while (state != Thread.State.WAITING && state != Thread.State.TIMED_WAITING) {
- Thread.sleep(10);
- state = thread.getState();
- }
- } finally {
- LockSupport.unpark(thread);
+ parker.run();
+ } catch (Throwable e) {
+ exception.set(e);
+ }
+ });
+ try {
+ // wait for thread to park/wait
+ Thread.State state = thread.getState();
+ while (state != expectedState) {
+ assertTrue(state != Thread.State.TERMINATED, thread.toString());
+ Thread.sleep(10);
+ state = thread.getState();
}
+ } finally {
+ unparker.accept(thread);
+ thread.join();
+ assertNull(exception.get());
}
} finally {
recording.stop();
@@ -132,9 +184,9 @@ void testVirtualThreadPinned() throws Exception {
Map events = sumEvents(recording);
System.err.println(events);
- // should have a pinned event for each park
+ // should have at least one pinned event
int pinnedCount = events.getOrDefault("jdk.VirtualThreadPinned", 0);
- assertEquals(parkers.length, pinnedCount);
+ assertTrue(pinnedCount >= 1, "Expected one or more events");
}
}
diff --git a/test/jdk/java/lang/Thread/virtual/WaitNotify.java b/test/jdk/java/lang/Thread/virtual/MonitorWaitNotify.java
similarity index 81%
rename from test/jdk/java/lang/Thread/virtual/WaitNotify.java
rename to test/jdk/java/lang/Thread/virtual/MonitorWaitNotify.java
index bc7b36b39bec6..1320cc8f15f3f 100644
--- a/test/jdk/java/lang/Thread/virtual/WaitNotify.java
+++ b/test/jdk/java/lang/Thread/virtual/MonitorWaitNotify.java
@@ -24,8 +24,9 @@
/**
* @test
* @summary Test virtual threads using Object.wait/notifyAll
+ * @modules java.base/java.lang:+open
* @library /test/lib
- * @run junit WaitNotify
+ * @run junit MonitorWaitNotify
*/
import java.util.concurrent.Semaphore;
@@ -34,7 +35,7 @@
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
-class WaitNotify {
+class MonitorWaitNotify {
/**
* Test virtual thread waits, notified by platform thread.
@@ -84,24 +85,31 @@ void testWaitNotify2() throws Exception {
*/
@Test
void testWaitNotify3() throws Exception {
- var lock = new Object();
- var ready = new Semaphore(0);
- var thread1 = Thread.ofVirtual().start(() -> {
- synchronized (lock) {
- ready.release();
- try {
- lock.wait();
- } catch (InterruptedException e) { }
- }
- });
- var thread2 = Thread.ofVirtual().start(() -> {
- ready.acquireUninterruptibly();
- synchronized (lock) {
- lock.notifyAll();
- }
- });
- thread1.join();
- thread2.join();
+ // need at least two carrier threads due to pinning
+ int previousParallelism = VThreadRunner.ensureParallelism(2);
+ try {
+ var lock = new Object();
+ var ready = new Semaphore(0);
+ var thread1 = Thread.ofVirtual().start(() -> {
+ synchronized (lock) {
+ ready.release();
+ try {
+ lock.wait();
+ } catch (InterruptedException e) { }
+ }
+ });
+ var thread2 = Thread.ofVirtual().start(() -> {
+ ready.acquireUninterruptibly();
+ synchronized (lock) {
+ lock.notifyAll();
+ }
+ });
+ thread1.join();
+ thread2.join();
+ } finally {
+ // restore
+ VThreadRunner.setParallelism(previousParallelism);
+ }
}
/**
diff --git a/test/jdk/java/lang/Thread/virtual/StackTraces.java b/test/jdk/java/lang/Thread/virtual/StackTraces.java
index fb5c40dc4e9b4..cb1877090fecd 100644
--- a/test/jdk/java/lang/Thread/virtual/StackTraces.java
+++ b/test/jdk/java/lang/Thread/virtual/StackTraces.java
@@ -23,7 +23,7 @@
/**
* @test
- * @summary Test stack traces in exceptions and stack frames waslked by the StackWalker
+ * @summary Test stack traces in exceptions and stack frames walked by the StackWalker
* API do not include the carrier stack frames
* @requires vm.continuations
* @modules java.management
diff --git a/test/jdk/java/lang/Thread/virtual/ThreadAPI.java b/test/jdk/java/lang/Thread/virtual/ThreadAPI.java
index 3371b5bc9e755..b1ccb21910acf 100644
--- a/test/jdk/java/lang/Thread/virtual/ThreadAPI.java
+++ b/test/jdk/java/lang/Thread/virtual/ThreadAPI.java
@@ -27,7 +27,7 @@
* @summary Test Thread API with virtual threads
* @modules java.base/java.lang:+open
* @library /test/lib
- * @run junit ThreadAPI
+ * @run junit/othervm --enable-native-access=ALL-UNNAMED ThreadAPI
*/
/*
@@ -35,7 +35,8 @@
* @requires vm.continuations
* @modules java.base/java.lang:+open
* @library /test/lib
- * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:-VMContinuations ThreadAPI
+ * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:-VMContinuations
+ * --enable-native-access=ALL-UNNAMED ThreadAPI
*/
import java.time.Duration;
@@ -61,6 +62,7 @@
import java.nio.channels.Selector;
import jdk.test.lib.thread.VThreadRunner;
+import jdk.test.lib.thread.VThreadPinner;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.AfterAll;
@@ -697,11 +699,11 @@ void testJoin32() throws Exception {
void testJoin33() throws Exception {
AtomicBoolean done = new AtomicBoolean();
Thread thread = Thread.ofVirtual().start(() -> {
- synchronized (lock) {
+ VThreadPinner.runPinned(() -> {
while (!done.get()) {
LockSupport.parkNanos(Duration.ofMillis(20).toNanos());
}
- }
+ });
});
try {
assertFalse(thread.join(Duration.ofMillis(100)));
@@ -1078,7 +1080,7 @@ void testSetDaemon2() throws Exception {
}
/**
- * Test Thread.yield releases thread when not pinned.
+ * Test Thread.yield releases carrier thread.
*/
@Test
void testYield1() throws Exception {
@@ -1106,7 +1108,7 @@ void testYield1() throws Exception {
}
/**
- * Test Thread.yield when thread is pinned.
+ * Test Thread.yield when thread is pinned by native frame.
*/
@Test
void testYield2() throws Exception {
@@ -1121,10 +1123,10 @@ void testYield2() throws Exception {
list.add("B");
});
child.start();
- synchronized (lock) {
+ VThreadPinner.runPinned(() -> {
Thread.yield(); // pinned so will be a no-op
list.add("A");
- }
+ });
try { child.join(); } catch (InterruptedException e) { }
});
thread.start();
@@ -1134,7 +1136,7 @@ void testYield2() throws Exception {
}
/**
- * Test that Thread.yield does not consume the thread's parking permit.
+ * Test Thread.yield does not consume the thread's parking permit.
*/
@Test
void testYield3() throws Exception {
@@ -1147,7 +1149,7 @@ void testYield3() throws Exception {
}
/**
- * Test that Thread.yield does not make available the thread's parking permit.
+ * Test Thread.yield does not make available the thread's parking permit.
*/
@Test
void testYield4() throws Exception {
@@ -1348,11 +1350,9 @@ void testSleep7() throws Exception {
*/
@Test
void testSleep8() throws Exception {
- VThreadRunner.run(() -> {
+ VThreadPinner.runPinned(() -> {
long start = millisTime();
- synchronized (lock) {
- Thread.sleep(1000);
- }
+ Thread.sleep(1000);
expectDuration(start, /*min*/900, /*max*/20_000);
});
}
@@ -1366,9 +1366,9 @@ void testSleep9() throws Exception {
Thread me = Thread.currentThread();
me.interrupt();
try {
- synchronized (lock) {
+ VThreadPinner.runPinned(() -> {
Thread.sleep(2000);
- }
+ });
fail("sleep not interrupted");
} catch (InterruptedException e) {
// expected
@@ -1386,9 +1386,9 @@ void testSleep10() throws Exception {
Thread t = Thread.currentThread();
scheduleInterrupt(t, 100);
try {
- synchronized (lock) {
+ VThreadPinner.runPinned(() -> {
Thread.sleep(20 * 1000);
- }
+ });
fail("sleep not interrupted");
} catch (InterruptedException e) {
// interrupt status should be cleared
@@ -1521,8 +1521,7 @@ void testContextClassLoader5() throws Exception {
@Test
void testUncaughtExceptionHandler1() throws Exception {
class FooException extends RuntimeException { }
- var exception = new AtomicReference();
- Thread.UncaughtExceptionHandler handler = (thread, exc) -> exception.set(exc);
+ var handler = new CapturingUHE();
Thread thread = Thread.ofVirtual().start(() -> {
Thread me = Thread.currentThread();
assertTrue(me.getUncaughtExceptionHandler() == me.getThreadGroup());
@@ -1531,7 +1530,8 @@ class FooException extends RuntimeException { }
throw new FooException();
});
thread.join();
- assertTrue(exception.get() instanceof FooException);
+ assertInstanceOf(FooException.class, handler.exception());
+ assertEquals(thread, handler.thread());
assertNull(thread.getUncaughtExceptionHandler());
}
@@ -1541,8 +1541,7 @@ class FooException extends RuntimeException { }
@Test
void testUncaughtExceptionHandler2() throws Exception {
class FooException extends RuntimeException { }
- var exception = new AtomicReference();
- Thread.UncaughtExceptionHandler handler = (thread, exc) -> exception.set(exc);
+ var handler = new CapturingUHE();
Thread.UncaughtExceptionHandler savedHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(handler);
Thread thread;
@@ -1553,25 +1552,61 @@ class FooException extends RuntimeException { }
});
thread.join();
} finally {
- Thread.setDefaultUncaughtExceptionHandler(savedHandler);
+ Thread.setDefaultUncaughtExceptionHandler(savedHandler); // restore
}
- assertTrue(exception.get() instanceof FooException);
+ assertInstanceOf(FooException.class, handler.exception());
+ assertEquals(thread, handler.thread());
assertNull(thread.getUncaughtExceptionHandler());
}
/**
- * Test no UncaughtExceptionHandler set.
+ * Test Thread and default UncaughtExceptionHandler set.
*/
@Test
void testUncaughtExceptionHandler3() throws Exception {
class FooException extends RuntimeException { }
- Thread thread = Thread.ofVirtual().start(() -> {
- throw new FooException();
- });
- thread.join();
+ var defaultHandler = new CapturingUHE();
+ var threadHandler = new CapturingUHE();
+ Thread.UncaughtExceptionHandler savedHandler = Thread.getDefaultUncaughtExceptionHandler();
+ Thread.setDefaultUncaughtExceptionHandler(defaultHandler);
+ Thread thread;
+ try {
+ thread = Thread.ofVirtual().start(() -> {
+ Thread me = Thread.currentThread();
+ assertTrue(me.getUncaughtExceptionHandler() == me.getThreadGroup());
+ me.setUncaughtExceptionHandler(threadHandler);
+ assertTrue(me.getUncaughtExceptionHandler() == threadHandler);
+ throw new FooException();
+ });
+ thread.join();
+ } finally {
+ Thread.setDefaultUncaughtExceptionHandler(savedHandler); // restore
+ }
+ assertInstanceOf(FooException.class, threadHandler.exception());
+ assertNull(defaultHandler.exception());
+ assertEquals(thread, threadHandler.thread());
assertNull(thread.getUncaughtExceptionHandler());
}
+ /**
+ * Test no Thread or default UncaughtExceptionHandler set.
+ */
+ @Test
+ void testUncaughtExceptionHandler4() throws Exception {
+ Thread.UncaughtExceptionHandler savedHandler = Thread.getDefaultUncaughtExceptionHandler();
+ Thread.setDefaultUncaughtExceptionHandler(null);
+ try {
+ class FooException extends RuntimeException { }
+ Thread thread = Thread.ofVirtual().start(() -> {
+ throw new FooException();
+ });
+ thread.join();
+ assertNull(thread.getUncaughtExceptionHandler());
+ } finally {
+ Thread.setDefaultUncaughtExceptionHandler(savedHandler);
+ }
+ }
+
/**
* Test Thread::threadId and getId.
*/
@@ -2006,10 +2041,76 @@ void testGetStackTrace5() throws Exception {
}
/**
- * Test Thread::getStackTrace on terminated thread.
+ * Test Thread::getStackTrace on timed-parked thread.
*/
@Test
void testGetStackTrace6() throws Exception {
+ var thread = Thread.ofVirtual().start(() -> {
+ LockSupport.parkNanos(Long.MAX_VALUE);
+ });
+ await(thread, Thread.State.TIMED_WAITING);
+ try {
+ StackTraceElement[] stack = thread.getStackTrace();
+ assertTrue(contains(stack, "LockSupport.parkNanos"));
+ } finally {
+ LockSupport.unpark(thread);
+ thread.join();
+ }
+ }
+
+ /**
+ * Test Thread::getStackTrace on parked thread that is pinned.
+ */
+ @Test
+ void testGetStackTrace7() throws Exception {
+ AtomicBoolean done = new AtomicBoolean();
+ var thread = Thread.ofVirtual().start(() -> {
+ VThreadPinner.runPinned(() -> {
+ while (!done.get()) {
+ LockSupport.park();
+ }
+ });
+ });
+ await(thread, Thread.State.WAITING);
+ try {
+ StackTraceElement[] stack = thread.getStackTrace();
+ assertTrue(contains(stack, "LockSupport.park"));
+ } finally {
+ done.set(true);
+ LockSupport.unpark(thread);
+ thread.join();
+ }
+ }
+
+ /**
+ * Test Thread::getStackTrace on timed-parked thread that is pinned.
+ */
+ @Test
+ void testGetStackTrace8() throws Exception {
+ AtomicBoolean done = new AtomicBoolean();
+ var thread = Thread.ofVirtual().start(() -> {
+ VThreadPinner.runPinned(() -> {
+ while (!done.get()) {
+ LockSupport.parkNanos(Long.MAX_VALUE);
+ }
+ });
+ });
+ await(thread, Thread.State.TIMED_WAITING);
+ try {
+ StackTraceElement[] stack = thread.getStackTrace();
+ assertTrue(contains(stack, "LockSupport.parkNanos"));
+ } finally {
+ done.set(true);
+ LockSupport.unpark(thread);
+ thread.join();
+ }
+ }
+
+ /**
+ * Test Thread::getStackTrace on terminated thread.
+ */
+ @Test
+ void testGetStackTrace9() throws Exception {
var thread = Thread.ofVirtual().start(() -> { });
thread.join();
StackTraceElement[] stack = thread.getStackTrace();
@@ -2176,7 +2277,7 @@ void testEnumerate1() throws Exception {
ThreadGroup vgroup = Thread.currentThread().getThreadGroup();
Thread[] threads = new Thread[100];
int n = vgroup.enumerate(threads, /*recurse*/false);
- assertTrue(n == 0);
+ assertFalse(Arrays.stream(threads, 0, n).anyMatch(Thread::isVirtual));
});
}
@@ -2289,6 +2390,33 @@ void testToString4() throws Exception {
assertTrue(thread.toString().contains("fred"));
}
+ /**
+ * Thread.UncaughtExceptionHandler that captures the first exception thrown.
+ */
+ private static class CapturingUHE implements Thread.UncaughtExceptionHandler {
+ Thread thread;
+ Throwable exception;
+ @Override
+ public void uncaughtException(Thread t, Throwable e) {
+ synchronized (this) {
+ if (thread == null) {
+ this.thread = t;
+ this.exception = e;
+ }
+ }
+ }
+ Thread thread() {
+ synchronized (this) {
+ return thread;
+ }
+ }
+ Throwable exception() {
+ synchronized (this) {
+ return exception;
+ }
+ }
+ }
+
/**
* Waits for the given thread to reach a given state.
*/
diff --git a/test/jdk/java/lang/Thread/virtual/VirtualThreadPinnedEventThrows.java b/test/jdk/java/lang/Thread/virtual/VirtualThreadPinnedEventThrows.java
index a4bccd47265ed..1ae73b280cb13 100644
--- a/test/jdk/java/lang/Thread/virtual/VirtualThreadPinnedEventThrows.java
+++ b/test/jdk/java/lang/Thread/virtual/VirtualThreadPinnedEventThrows.java
@@ -25,15 +25,18 @@
* @test
* @summary Test parking when pinned and emitting the JFR VirtualThreadPinnedEvent throws
* @modules java.base/jdk.internal.event
+ * @library /test/lib
* @compile/module=java.base jdk/internal/event/VirtualThreadPinnedEvent.java
- * @run junit VirtualThreadPinnedEventThrows
+ * @run junit/othervm --enable-native-access=ALL-UNNAMED VirtualThreadPinnedEventThrows
*/
import java.lang.ref.Reference;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.LockSupport;
import jdk.internal.event.VirtualThreadPinnedEvent;
+import jdk.test.lib.thread.VThreadPinner;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
@@ -82,29 +85,31 @@ void testVirtualThreadPinnedEventCommitThrows() throws Exception {
* Test parking a virtual thread when pinned.
*/
private void testParkWhenPinned() throws Exception {
- Object lock = new Object();
+ var exception = new AtomicReference();
+ var done = new AtomicBoolean();
+ Thread thread = Thread.startVirtualThread(() -> {
+ try {
+ VThreadPinner.runPinned(() -> {
+ while (!done.get()) {
+ LockSupport.park();
+ }
+ });
+ } catch (Throwable e) {
+ exception.set(e);
+ }
+ });
try {
- var completed = new AtomicBoolean();
- Thread thread = Thread.startVirtualThread(() -> {
- synchronized (lock) {
- LockSupport.park();
- completed.set(true);
- }
- });
-
// wait for thread to park
Thread.State state;
while ((state = thread.getState()) != Thread.State.WAITING) {
assertTrue(state != Thread.State.TERMINATED);
Thread.sleep(10);
}
-
- // unpark and check that thread completed without exception
+ } finally {
+ done.set(true);
LockSupport.unpark(thread);
thread.join();
- assertTrue(completed.get());
- } finally {
- Reference.reachabilityFence(lock);
}
+ assertNull(exception.get());
}
}
diff --git a/test/jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWhenPinned.java b/test/jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWhenPinned.java
new file mode 100644
index 0000000000000..1790ef5eeac5b
--- /dev/null
+++ b/test/jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWhenPinned.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8322818
+ * @summary Stress test Thread.getStackTrace on a virtual thread that is pinned
+ * @requires vm.debug != true
+ * @run main GetStackTraceALotWhenPinned 25000
+ */
+
+/*
+ * @test
+ * @requires vm.debug == true
+ * @run main/timeout=300 GetStackTraceALotWhenPinned 10000
+ */
+
+import java.time.Instant;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.locks.LockSupport;
+
+public class GetStackTraceALotWhenPinned {
+
+ public static void main(String[] args) throws Exception {
+ var counter = new AtomicInteger(Integer.parseInt(args[0]));
+
+ // Start a virtual thread that loops doing Thread.yield and parking while pinned.
+ // This loop creates the conditions for the main thread to sample the stack trace
+ // as it transitions from being unmounted to parking while pinned.
+ var thread = Thread.startVirtualThread(() -> {
+ boolean timed = false;
+ while (counter.decrementAndGet() > 0) {
+ Thread.yield();
+ synchronized (GetStackTraceALotWhenPinned.class) {
+ if (timed) {
+ LockSupport.parkNanos(Long.MAX_VALUE);
+ } else {
+ LockSupport.park();
+ }
+ }
+ timed = !timed;
+ }
+ });
+
+ long lastTimestamp = System.currentTimeMillis();
+ while (thread.isAlive()) {
+ thread.getStackTrace();
+ LockSupport.unpark(thread);
+ long currentTime = System.currentTimeMillis();
+ if ((currentTime - lastTimestamp) > 500) {
+ System.out.format("%s %d remaining ...%n", Instant.now(), counter.get());
+ lastTimestamp = currentTime;
+ }
+ }
+ }
+}
diff --git a/test/jdk/java/lang/Thread/virtual/stress/PinALot.java b/test/jdk/java/lang/Thread/virtual/stress/PinALot.java
index 7bfce95b5c20a..a420ebb330e7b 100644
--- a/test/jdk/java/lang/Thread/virtual/stress/PinALot.java
+++ b/test/jdk/java/lang/Thread/virtual/stress/PinALot.java
@@ -25,13 +25,15 @@
* @test
* @summary Stress test timed park when pinned
* @requires vm.debug != true
- * @run main PinALot 500000
+ * @library /test/lib
+ * @run main/othervm --enable-native-access=ALL-UNNAMED PinALot 500000
*/
/*
* @test
* @requires vm.debug == true
- * @run main/othervm/timeout=300 PinALot 200000
+ * @library /test/lib
+ * @run main/othervm/timeout=300 --enable-native-access=ALL-UNNAMED PinALot 200000
*/
import java.time.Duration;
@@ -39,9 +41,9 @@
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.LockSupport;
-public class PinALot {
+import jdk.test.lib.thread.VThreadPinner;
- static final Object lock = new Object();
+public class PinALot {
public static void main(String[] args) throws Exception {
int iterations = 1_000_000;
@@ -53,11 +55,11 @@ public static void main(String[] args) throws Exception {
AtomicInteger count = new AtomicInteger();
Thread thread = Thread.ofVirtual().start(() -> {
- synchronized (lock) {
+ VThreadPinner.runPinned(() -> {
while (count.incrementAndGet() < ITERATIONS) {
LockSupport.parkNanos(1);
}
- }
+ });
});
boolean terminated;
diff --git a/test/jdk/java/lang/Thread/virtual/stress/Skynet.java b/test/jdk/java/lang/Thread/virtual/stress/Skynet.java
index fb4adbb25f234..ee45fc827b005 100644
--- a/test/jdk/java/lang/Thread/virtual/stress/Skynet.java
+++ b/test/jdk/java/lang/Thread/virtual/stress/Skynet.java
@@ -26,7 +26,7 @@
* @summary Stress test virtual threads with a variation of the Skynet 1M benchmark
* @requires vm.continuations
* @requires !vm.debug | vm.gc != "Z"
- * @run main/othervm/timeout=300 -Xmx1g Skynet
+ * @run main/othervm/timeout=300 -Xmx1500m Skynet
*/
/*
@@ -35,7 +35,7 @@
* @requires vm.gc.ZSinglegen
* @run main/othervm/timeout=300 -XX:+UnlockDiagnosticVMOptions
* -XX:+UseZGC -XX:-ZGenerational
- * -XX:+ZVerifyOops -XX:ZCollectionInterval=0.01 -Xmx1g Skynet
+ * -XX:+ZVerifyOops -XX:ZCollectionInterval=0.01 -Xmx1500m Skynet
*/
/*
@@ -44,7 +44,7 @@
* @requires vm.gc.ZGenerational
* @run main/othervm/timeout=300 -XX:+UnlockDiagnosticVMOptions
* -XX:+UseZGC -XX:+ZGenerational
- * -XX:+ZVerifyOops -XX:ZCollectionInterval=0.01 -Xmx1g Skynet
+ * -XX:+ZVerifyOops -XX:ZCollectionInterval=0.01 -Xmx1500m Skynet
*/
import java.util.concurrent.BlockingQueue;
diff --git a/test/jdk/java/nio/channels/Selector/SelectWithConsumer.java b/test/jdk/java/nio/channels/Selector/SelectWithConsumer.java
index 630a1ef88b813..de8b48ec22d98 100644
--- a/test/jdk/java/nio/channels/Selector/SelectWithConsumer.java
+++ b/test/jdk/java/nio/channels/Selector/SelectWithConsumer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2023, 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
@@ -411,9 +411,7 @@ public void testInterruptDuringSelect() throws Exception {
// select(Consumer, timeout)
try (Selector sel = Selector.open()) {
scheduleInterrupt(Thread.currentThread(), 1, SECONDS);
- long start = System.currentTimeMillis();
int n = sel.select(k -> assertTrue(false), 60*1000);
- long duration = System.currentTimeMillis() - start;
assertTrue(n == 0);
assertTrue(Thread.currentThread().isInterrupted());
assertTrue(sel.isOpen());
diff --git a/test/jdk/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyWithJarTest.java b/test/jdk/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyWithJarTest.java
index 8fdd787863927..fdbe44fb03c58 100644
--- a/test/jdk/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyWithJarTest.java
+++ b/test/jdk/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyWithJarTest.java
@@ -94,7 +94,7 @@ public static void main(String args[]) throws Throwable {
"-Djava.security.manager",
"-Djava.security.policy=" + POL,
"ExtensiblePolicyTest_orig$TestMain"};
- ProcessTools.executeTestJvm(cmd).shouldHaveExitValue(0);
+ ProcessTools.executeTestJava(cmd).shouldHaveExitValue(0);
} catch (Exception ex) {
System.out.println("ExtensiblePolicyWithJarTest Failed");
}
diff --git a/test/jdk/java/security/Policy/SignedJar/SignedJarTest.java b/test/jdk/java/security/Policy/SignedJar/SignedJarTest.java
index c93337d73d0c3..cd06cc15691b0 100644
--- a/test/jdk/java/security/Policy/SignedJar/SignedJarTest.java
+++ b/test/jdk/java/security/Policy/SignedJar/SignedJarTest.java
@@ -121,7 +121,7 @@ public static void main(String args[]) throws Throwable {
System.out.println("Test Case 1");
//copy policy file into current directory
String[] cmd = constructCMD("first.jar", POLICY1, "false", "true");
- ProcessTools.executeTestJvm(cmd).shouldHaveExitValue(0);
+ ProcessTools.executeTestJava(cmd).shouldHaveExitValue(0);
//test case 2, test with both.jar
//setIO permission granted to code that was signed by first signer
@@ -131,7 +131,7 @@ public static void main(String args[]) throws Throwable {
//Expect no AccessControlException
System.out.println("Test Case 2");
cmd = constructCMD("both.jar", POLICY1, "false", "false");
- ProcessTools.executeTestJvm(cmd).shouldHaveExitValue(0);
+ ProcessTools.executeTestJava(cmd).shouldHaveExitValue(0);
//test case 3
//setIO permission granted to code that was signed by first signer
@@ -141,7 +141,7 @@ public static void main(String args[]) throws Throwable {
//Expect AccessControlException for setFactory permission
System.out.println("Test Case 3");
cmd = constructCMD("both.jar", POLICY2, "false", "true");
- ProcessTools.executeTestJvm(cmd).shouldHaveExitValue(0);
+ ProcessTools.executeTestJava(cmd).shouldHaveExitValue(0);
}
diff --git a/test/jdk/java/security/Provider/SecurityProviderModularTest.java b/test/jdk/java/security/Provider/SecurityProviderModularTest.java
index c475d59337057..5bcf9a73301a7 100644
--- a/test/jdk/java/security/Provider/SecurityProviderModularTest.java
+++ b/test/jdk/java/security/Provider/SecurityProviderModularTest.java
@@ -255,7 +255,7 @@ private void execute(String args, String msgKey) throws Exception {
}
return !s.isEmpty();
}).toArray(String[]::new);
- String out = ProcessTools.executeTestJvm(safeArgs).getOutput();
+ String out = ProcessTools.executeTestJava(safeArgs).getOutput();
// Handle response.
if ((msgKey != null && out.contains(MSG_MAP.get(msgKey)))) {
System.out.printf("PASS: Expected Result: %s.%n",
diff --git a/test/jdk/java/security/Security/signedfirst/DynStatic.java b/test/jdk/java/security/Security/signedfirst/DynStatic.java
index 5256564064b34..59e30de54623f 100644
--- a/test/jdk/java/security/Security/signedfirst/DynStatic.java
+++ b/test/jdk/java/security/Security/signedfirst/DynStatic.java
@@ -78,7 +78,7 @@ public static void main(String[] args) throws Exception {
CompilerUtils.compile(DYN_SRC, TEST_CLASSES, "-classpath", "exp.jar");
// Run the DynSignedProvFirst test program
- ProcessTools.executeTestJvm("-classpath",
+ ProcessTools.executeTestJava("-classpath",
TEST_CLASSES.toString() + File.pathSeparator + "exp.jar",
"DynSignedProvFirst")
.shouldContain("test passed");
@@ -87,7 +87,7 @@ public static void main(String[] args) throws Exception {
CompilerUtils.compile(STATIC_SRC, TEST_CLASSES, "-classpath", "exp.jar");
// Run the StaticSignedProvFirst test program
- ProcessTools.executeTestJvm("-classpath",
+ ProcessTools.executeTestJava("-classpath",
TEST_CLASSES.toString() + File.pathSeparator + "exp.jar",
"-Djava.security.properties=file:" + STATIC_PROPS,
"StaticSignedProvFirst")
diff --git a/test/jdk/java/security/SignedJar/spi-calendar-provider/TestSPISigned.java b/test/jdk/java/security/SignedJar/spi-calendar-provider/TestSPISigned.java
index 69fe8effe70aa..83c2d85f6e444 100644
--- a/test/jdk/java/security/SignedJar/spi-calendar-provider/TestSPISigned.java
+++ b/test/jdk/java/security/SignedJar/spi-calendar-provider/TestSPISigned.java
@@ -100,7 +100,7 @@ public static void main(String[] args) throws Throwable {
testRun.add(classPath);
testRun.add(TestSPISigned.class.getSimpleName());
testRun.add("run-test");
- OutputAnalyzer out = ProcessTools.executeTestJvm(testRun);
+ OutputAnalyzer out = ProcessTools.executeTestJava(testRun);
out.shouldHaveExitValue(0);
out.shouldContain("DEBUG: Getting xx language");
}
diff --git a/test/jdk/java/sql/testng/test/sql/TimestampTests.java b/test/jdk/java/sql/testng/test/sql/TimestampTests.java
index 7766b5a2b4c69..fefe3276d47a1 100644
--- a/test/jdk/java/sql/testng/test/sql/TimestampTests.java
+++ b/test/jdk/java/sql/testng/test/sql/TimestampTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2023, 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
@@ -642,6 +642,31 @@ public void test52(long value, String ts) {
assertEquals(ts1.toString(), ts, "ts1.toString() != ts");
}
+ @Test
+ public void test53() {
+ // The latest Instant that can be converted to a Timestamp.
+ Instant instant1 = Instant.ofEpochSecond(Long.MAX_VALUE / 1000, 999_999_999);
+ assertEquals(Timestamp.from(instant1).toInstant(), instant1);
+
+ // One nanosecond more, and converting it gets an overflow.
+ Instant instant2 = instant1.plusNanos(1);
+ expectThrows(IllegalArgumentException.class, () -> Timestamp.from(instant2));
+
+ // The earliest Instant that can be converted to a Timestamp.
+ Instant instant3 = Instant.ofEpochSecond(Long.MIN_VALUE / 1000, 0);
+ assertEquals(Timestamp.from(instant3).toInstant(), instant3);
+
+ // One nanosecond less, and converting it gets an overflow.
+ Instant instant4 = instant3.minusNanos(1);
+ expectThrows(IllegalArgumentException.class, () -> Timestamp.from(instant4));
+
+ // The latest possible Instant will certainly overflow.
+ expectThrows(IllegalArgumentException.class, () -> Timestamp.from(Instant.MAX));
+
+ // The earliest possible Instant will certainly overflow.
+ expectThrows(IllegalArgumentException.class, () -> Timestamp.from(Instant.MIN));
+ }
+
/*
* DataProvider used to provide Timestamps which are not valid and are used
* to validate that an IllegalArgumentException will be thrown from the
diff --git a/test/jdk/java/time/test/java/time/format/TestUTCParse.java b/test/jdk/java/time/test/java/time/format/TestUTCParse.java
index 6da94f04f0413..c1766b4703070 100644
--- a/test/jdk/java/time/test/java/time/format/TestUTCParse.java
+++ b/test/jdk/java/time/test/java/time/format/TestUTCParse.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
/*
* @test
* @modules jdk.localedata
- * @bug 8303440 8317979
+ * @bug 8303440 8317979 8322647
* @summary Test parsing "UTC-XX:XX" text works correctly
*/
package test.java.time.format;
@@ -43,8 +43,8 @@
public class TestUTCParse {
static {
- // Assuming CLDR's SHORT name for "America/Juneau"
- // produces "UTC\u212209:00"
+ // Assuming CLDR's SHORT name for "America/Manaus"
+ // produces "UTC\u221204:00"
System.setProperty("java.locale.providers", "CLDR");
}
@@ -60,9 +60,9 @@ public Object[][] utcZoneIdStrings() {
@Test
public void testUTCShortNameRoundTrip() {
var fmt = DateTimeFormatter.ofPattern("z", Locale.FRANCE);
- var zdt = ZonedDateTime.of(2023, 3, 3, 0, 0, 0, 0, ZoneId.of("America/Juneau"));
+ var zdt = ZonedDateTime.of(2023, 3, 3, 0, 0, 0, 0, ZoneId.of("America/Manaus"));
var formatted = fmt.format(zdt);
- assertEquals(formatted, "UTC\u221209:00");
+ assertEquals(formatted, "UTC\u221204:00");
assertEquals(fmt.parse(formatted).query(TemporalQueries.zoneId()), zdt.getZone());
}
diff --git a/test/jdk/java/util/Currency/PropertiesTestRun.java b/test/jdk/java/util/Currency/PropertiesTestRun.java
index 6f2ea28a90d3a..baec22f3e86f6 100644
--- a/test/jdk/java/util/Currency/PropertiesTestRun.java
+++ b/test/jdk/java/util/Currency/PropertiesTestRun.java
@@ -116,7 +116,7 @@ private static Stream PropertiesTestMethods() {
// Launch a PropertiesTest method using the TEST JDK
private static void executeTestJDKMethod(String... params) throws Throwable {
- int exitStatus = ProcessTools.executeTestJvm(params).getExitValue();
+ int exitStatus = ProcessTools.executeTestJava(params).getExitValue();
if (exitStatus != 0) {
fail("Process started with: " + Arrays.toString(params) + " failed");
}
@@ -126,7 +126,7 @@ private static void executeTestJDKMethod(String... params) throws Throwable {
private static void executeWritableJDKMethod(String... params) throws Throwable {
// Need to include WritableJDK javapath, TEST JDK classpath
String[] allParams = new String[3+params.length+Utils.getTestJavaOpts().length];
- // We don't use executeTestJvm() because we want to point to separate JDK java path
+ // We don't use executeTestJava() because we want to point to separate JDK java path
allParams[0] = WRITABLE_JDK_JAVA_PATH;
allParams[1] = "-cp";
allParams[2] = System.getProperty("java.class.path");
diff --git a/test/jdk/java/util/Locale/UseOldISOCodesTest.java b/test/jdk/java/util/Locale/UseOldISOCodesTest.java
index b38537bceca3c..01f997a743d7d 100644
--- a/test/jdk/java/util/Locale/UseOldISOCodesTest.java
+++ b/test/jdk/java/util/Locale/UseOldISOCodesTest.java
@@ -41,7 +41,7 @@ public class UseOldISOCodesTest {
// Ensure java.locale.useOldISOCodes is only interpreted at runtime startup
@Test
public void staticInitializationTest() throws Exception {
- ProcessTools.executeTestJvm("-Djava.locale.useOldISOCodes=true", "UseOldISOCodesTest$Runner")
+ ProcessTools.executeTestJava("-Djava.locale.useOldISOCodes=true", "UseOldISOCodesTest$Runner")
.outputTo(System.out)
.errorTo(System.err)
.shouldHaveExitValue(0);
diff --git a/test/jdk/java/util/TimeZone/TimeZoneData/VERSION b/test/jdk/java/util/TimeZone/TimeZoneData/VERSION
index c5483b485120a..f92096d49aafd 100644
--- a/test/jdk/java/util/TimeZone/TimeZoneData/VERSION
+++ b/test/jdk/java/util/TimeZone/TimeZoneData/VERSION
@@ -1 +1 @@
-tzdata2023c
+tzdata2023d
diff --git a/test/jdk/java/util/TimeZone/TimeZoneData/aliases.txt b/test/jdk/java/util/TimeZone/TimeZoneData/aliases.txt
index 07c5edbafee70..82bad17c55320 100644
--- a/test/jdk/java/util/TimeZone/TimeZoneData/aliases.txt
+++ b/test/jdk/java/util/TimeZone/TimeZoneData/aliases.txt
@@ -148,7 +148,6 @@ Link America/Puerto_Rico America/Tortola
Link Pacific/Port_Moresby Antarctica/DumontDUrville
Link Pacific/Auckland Antarctica/McMurdo
Link Asia/Riyadh Antarctica/Syowa
-Link Asia/Urumqi Antarctica/Vostok
Link Europe/Berlin Arctic/Longyearbyen
Link Asia/Riyadh Asia/Aden
Link Asia/Qatar Asia/Bahrain
diff --git a/test/jdk/java/util/prefs/CheckUserPrefsStorage.java b/test/jdk/java/util/prefs/CheckUserPrefsStorage.java
index 51ecae932d17b..1f772f4811aaa 100644
--- a/test/jdk/java/util/prefs/CheckUserPrefsStorage.java
+++ b/test/jdk/java/util/prefs/CheckUserPrefsStorage.java
@@ -42,7 +42,7 @@ public static void main(String[] args) throws Throwable {
}
public static void run(String testName) throws Exception {
- ProcessTools.executeTestJvm("-Djava.util.prefs.userRoot=.", testName)
+ ProcessTools.executeTestJava("-Djava.util.prefs.userRoot=.", testName)
.outputTo(System.out)
.errorTo(System.out)
.shouldHaveExitValue(0);
diff --git a/test/jdk/java/util/zip/EntryCount64k.java b/test/jdk/java/util/zip/EntryCount64k.java
index 08d896a124a2a..2dac7643de2a7 100644
--- a/test/jdk/java/util/zip/EntryCount64k.java
+++ b/test/jdk/java/util/zip/EntryCount64k.java
@@ -160,7 +160,7 @@ static void checkCanRead(File zipFile, int entryCount) throws Throwable {
}
// Check java -jar
- OutputAnalyzer a = ProcessTools.executeTestJvm("-jar", zipFile.getName());
+ OutputAnalyzer a = ProcessTools.executeTestJava("-jar", zipFile.getName());
a.shouldHaveExitValue(0);
a.stdoutShouldMatch("\\AMain\\Z");
a.stderrShouldMatch("\\A\\Z");
diff --git a/test/jdk/java/util/zip/ZipCoding.java b/test/jdk/java/util/zip/ZipCoding.java
index 852522b9a6a58..14a0e96f17440 100644
--- a/test/jdk/java/util/zip/ZipCoding.java
+++ b/test/jdk/java/util/zip/ZipCoding.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,111 +23,185 @@
/**
* @test
- * @bug 4244499 4532049 4700978 4820807 4980042
+ * @bug 4244499 4532049 4700978 4820807 4980042 7009069 8322802
* @summary Test ZipInputStream, ZipOutputStream and ZipFile with non-UTF8 encoding
* @modules jdk.charsets
+ * @run junit ZipCoding
*/
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
import java.io.*;
import java.nio.charset.*;
+import java.nio.file.Files;
+import java.nio.file.Path;
import java.util.*;
+import java.util.stream.Stream;
import java.util.zip.*;
+import static org.junit.jupiter.api.Assertions.*;
+
public class ZipCoding {
- public static void main(String[] args) throws Exception {
+ // The data to write to ZIP entries in this test
+ private static byte[] ENTRY_DATA = "German Umlaut \u00fc in entry data"
+ .getBytes(StandardCharsets.ISO_8859_1);
+
+ /**
+ * Provide arguments used for parameterized tests
+ * @return a stream of argument lists
+ */
+ public static Stream charsetsAndNames() {
+ // Arguments are: Write charset, read charset, entry name, comment
+ return Stream.of(
+ // MS code page 932 for the Japanese language
+ Arguments.of("MS932", "MS932",
+ "\u4e00\u4e01",
+ "\uff67\uff68\uff69\uff6a\uff6b\uff6c"),
- test("MS932",
- "\u4e00\u4e01", "\uff67\uff68\uff69\uff6a\uff6b\uff6c");
+ // Code page for the IBM PC
+ Arguments.of("ibm437", "ibm437",
+ "\u00e4\u00fc",
+ "German Umlaut \u00fc in comment"),
- test("ibm437",
- "\u00e4\u00fc", "German Umlaut \u00fc in comment");
+ // UTF-8 with Japanese characters
+ Arguments.of("utf-8", "utf-8",
+ "\u4e00\u4e01",
+ "\uff67\uff68\uff69\uff6a\uff6b\uff6c"),
- test("utf-8",
- "\u4e00\u4e01", "\uff67\uff68\uff69\uff6a\uff6b\uff6c");
+ // UTF-8 with characters in the Latin1 range
+ Arguments.of("utf-8", "utf-8",
+ "\u00e4\u00fc",
+ "German Umlaut \u00fc in comment"),
- test("utf-8",
- "\u00e4\u00fc", "German Umlaut \u00fc in comment");
+ // UTF-8 with surrogate pairs
+ Arguments.of("utf-8", "utf-8",
+ "Surrogate\ud801\udc01",
+ "Surrogates \ud800\udc00 in comment"),
- test("utf-8",
- "Surrogate\ud801\udc01", "Surrogates \ud800\udc00 in comment");
+ // ZipOutputStream sets the 'Language encoding flag' when writing using UTF-8
+ // UTF-8 should be used for decoding, regardless of the opening charset
+ // UTF-8 with Japanese characters, opened with MS932
+ Arguments.of("utf-8", "MS932",
+ "\u4e00\u4e01",
+ "\uff67\uff68\uff69\uff6a\uff6b\uff6c"),
+
+ // UTF-8 with characters in latin1 range, opened with iso-8859-1
+ Arguments.of("utf-8", "iso-8859-1",
+ "\u00e4\u00fc",
+ "German Umlaut \u00fc in comment"),
+ // UTF-8 with surrogate pairs, opened with MS932
+ Arguments.of("utf-8", "MS932",
+ "Surrogate\ud801\udc01",
+ "Surrogates \ud800\udc00 in comment")
+ );
}
- static void testZipInputStream(InputStream is, Charset cs,
- String name, String comment, byte[] bb)
- throws Exception
- {
- try (ZipInputStream zis = new ZipInputStream(is, cs)) {
+ /**
+ * Verify that ZipInputStream decodes entry names and comments
+ * using the charset provided to its constructor, or that it decodes
+ * using UTF-8 when the 'Language encoding flag' is set
+ *
+ * @param writeCharset the charset to use for ZipOutputStream when producing the ZIP
+ * @param readCharset the charset to use when opening the ZipInputStream
+ * @param name the entry name
+ * @param comment the entry comment (not read by ZipInputStream)
+ *
+ * @throws IOException if an unexpected IOException occurs
+ */
+ @ParameterizedTest
+ @MethodSource("charsetsAndNames")
+ public void testZipInputStream(String writeCharset,
+ String readCharset,
+ String name,
+ String comment) throws IOException {
+
+ byte[] zip = createZIP(writeCharset, name, comment);
+
+ try (InputStream in = new ByteArrayInputStream(zip);
+ ZipInputStream zis = new ZipInputStream(in, Charset.forName(readCharset))) {
ZipEntry e = zis.getNextEntry();
- if (e == null || ! name.equals(e.getName()))
- throw new RuntimeException("ZipIS name doesn't match!");
- byte[] bBuf = new byte[bb.length << 1];
- int n = zis.read(bBuf, 0, bBuf.length);
- if (n != bb.length ||
- !Arrays.equals(bb, Arrays.copyOf(bBuf, n))) {
- throw new RuntimeException("ZipIS content doesn't match!");
- }
+ assertNotNull(e);
+ assertEquals(name, e.getName(),
+ "ZipInputStream.getNextEntry() returned unexpected entry name");
+ assertNull(e.getComment()); // No comment in the LOC header
+ assertArrayEquals(ENTRY_DATA, zis.readAllBytes(), "Unexpected ZIP entry data");
}
}
- static void testZipFile(File f, Charset cs,
- String name, String comment, byte[] bb)
- throws Exception
- {
- try (ZipFile zf = new ZipFile(f, cs)) {
+ /**
+ * Verify that ZipFile decodes entry names and comments
+ * using the charset provided to its constructor, or that it decodes
+ * using UTF-8 when the 'Language encoding flag' is set
+ *
+ * @param writeCharset the charset to use for ZipOutputStream when producing the ZIP
+ * @param readCharset the charset to use when opening the ZipFile
+ * @param name the name of the entry
+ * @param comment the comment of the entry
+ *
+ * @throws IOException if an unexpected IOException occurs
+ */
+ @ParameterizedTest
+ @MethodSource("charsetsAndNames")
+ public void testZipFile(String writeCharset,
+ String readCharset,
+ String name,
+ String comment) throws IOException {
+
+ byte[] zip = createZIP(writeCharset, name, comment);
+
+ Path f = Path.of("zfcoding.zip");
+ Files.write(f, zip);
+
+ try (ZipFile zf = new ZipFile(f.toFile(), Charset.forName(readCharset))) {
+ // Test using ZipFile.entries
Enumeration extends ZipEntry> zes = zf.entries();
ZipEntry e = (ZipEntry)zes.nextElement();
- if (! name.equals(e.getName()) ||
- ! comment.equals(e.getComment()))
- throw new RuntimeException("ZipFile: name/comment doesn't match!");
- InputStream is = zf.getInputStream(e);
- if (is == null)
- throw new RuntimeException("ZipFile: getIS failed!");
- byte[] bBuf = new byte[bb.length << 1];
- int n = 0;
- int nn =0;
- while ((nn = is.read(bBuf, n, bBuf.length-n)) != -1) {
- n += nn;
- }
- if (n != bb.length ||
- !Arrays.equals(bb, Arrays.copyOf(bBuf, n))) {
- throw new RuntimeException("ZipFile content doesn't match!");
+ assertNotNull(e);
+ assertEquals(name, e.getName(), "ZipFile.entries() returned unexpected entry name");
+ assertEquals(comment, e.getComment(), "ZipFile.entries() returned unexpected entry comment");
+
+ // Test using ZipFile.getEntry
+ e = zf.getEntry(name);
+ assertNotNull(e,
+ String.format("Entry lookup failed on ZIP encoded with %s and opened with %s",
+ writeCharset, readCharset));
+ assertEquals(name, e.getName(), "ZipFile.getEntry() returned unexpected entry name");
+ assertEquals(comment, e.getComment(), "ZipFile.getEntry() returned unexpected entry comment");
+ try (InputStream is = zf.getInputStream(e)) {
+ assertNotNull(is);
+ assertArrayEquals(ENTRY_DATA, is.readAllBytes(), "Unexpected ZIP entry data");
}
}
+
+ Files.deleteIfExists(f);
}
- static void test(String csn, String name, String comment)
- throws Exception
- {
- byte[] bb = "This is the content of the zipfile".getBytes("ISO-8859-1");
- Charset cs = Charset.forName(csn);
+ /**
+ * Create a ZIP file containing an entry with the given name
+ * and comment, encoded using the given charset.
+ * Note that if the charset is UTF-8, ZipOutputStream will
+ * set the 'Language encoding flag' for the entry.
+ *
+ * @param charset the charset passed to the ZipOutputStream constructor
+ * @param name the name of the entry to add
+ * @param comment the comment of the entry to add
+ * @return a byte array containing the ZIP file
+ *
+ * @throws IOException if an unexpected IOException occurs
+ */
+ private byte[] createZIP(String charset, String name, String comment) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
- try (ZipOutputStream zos = new ZipOutputStream(baos, cs)) {
+ try (ZipOutputStream zos = new ZipOutputStream(baos, Charset.forName(charset))) {
ZipEntry e = new ZipEntry(name);
e.setComment(comment);
zos.putNextEntry(e);
- zos.write(bb, 0, bb.length);
+ zos.write(ENTRY_DATA);
zos.closeEntry();
}
- ByteArrayInputStream bis = new ByteArrayInputStream(baos.toByteArray());
- testZipInputStream(bis, cs, name, comment, bb);
-
- if ("utf-8".equals(csn)) {
- // USE_UTF8 should be set
- bis.reset();
- testZipInputStream(bis, Charset.forName("MS932"), name, comment, bb);
- }
-
- File f = new File(new File(System.getProperty("test.dir", ".")),
- "zfcoding.zip");
- try (FileOutputStream fos = new FileOutputStream(f)) {
- baos.writeTo(fos);
- }
- testZipFile(f, cs, name, comment, bb);
- if ("utf-8".equals(csn)) {
- testZipFile(f, Charset.forName("MS932"), name, comment, bb);
- }
- f.delete();
+ return baos.toByteArray();
}
}
diff --git a/test/jdk/java/util/zip/ZipFile/DeleteTempJarTest.java b/test/jdk/java/util/zip/ZipFile/DeleteTempJarTest.java
index e0a987f8bdc31..cafc17accf8d4 100644
--- a/test/jdk/java/util/zip/ZipFile/DeleteTempJarTest.java
+++ b/test/jdk/java/util/zip/ZipFile/DeleteTempJarTest.java
@@ -42,7 +42,7 @@
public class DeleteTempJarTest {
public static void main(String[] args) throws Exception {
- String tmpFile = ProcessTools.executeTestJvm(DeleteTempJar.class.getName())
+ String tmpFile = ProcessTools.executeTestJava(DeleteTempJar.class.getName())
.shouldHaveExitValue(0)
.getStdout();
diff --git a/test/jdk/java/util/zip/ZipFile/ZipSourceCache.java b/test/jdk/java/util/zip/ZipFile/ZipSourceCache.java
index 8cb1051a87c77..0f0b0725b7d43 100644
--- a/test/jdk/java/util/zip/ZipFile/ZipSourceCache.java
+++ b/test/jdk/java/util/zip/ZipFile/ZipSourceCache.java
@@ -25,6 +25,7 @@
* @bug 8317678
* @modules java.base/java.util.zip:open
* @summary Fix up hashCode() for ZipFile.Source.Key
+ * @library /test/lib
* @run junit/othervm ZipSourceCache
*/
@@ -34,6 +35,7 @@
import java.nio.file.attribute.BasicFileAttributes;
import java.util.*;
import java.util.zip.*;
+import jdk.test.lib.util.FileUtils;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.BeforeAll;
@@ -62,7 +64,7 @@ public static void setup() throws Exception {
@AfterAll
public static void cleanup() throws IOException {
- Files.deleteIfExists(Path.of(ZIPFILE_NAME));
+ FileUtils.deleteFileIfExistsWithRetry(Path.of(ZIPFILE_NAME));
}
/*
diff --git a/test/jdk/javax/security/auth/login/modules/JaasModularClientTest.java b/test/jdk/javax/security/auth/login/modules/JaasModularClientTest.java
index 2b6bc0519bcc8..7869c10282a23 100644
--- a/test/jdk/javax/security/auth/login/modules/JaasModularClientTest.java
+++ b/test/jdk/javax/security/auth/login/modules/JaasModularClientTest.java
@@ -184,7 +184,7 @@ private void execute(String args) throws Exception {
}
return !s.isEmpty();
}).toArray(String[]::new);
- OutputAnalyzer out = ProcessTools.executeTestJvm(safeArgs);
+ OutputAnalyzer out = ProcessTools.executeTestJava(safeArgs);
// Handle response.
if (out.getExitValue() != 0) {
System.out.printf("OUTPUT: %s", out.getOutput());
diff --git a/test/jdk/javax/security/auth/login/modules/JaasModularDefaultHandlerTest.java b/test/jdk/javax/security/auth/login/modules/JaasModularDefaultHandlerTest.java
index 2f2c43d03c585..95d2541a190dc 100644
--- a/test/jdk/javax/security/auth/login/modules/JaasModularDefaultHandlerTest.java
+++ b/test/jdk/javax/security/auth/login/modules/JaasModularDefaultHandlerTest.java
@@ -168,7 +168,7 @@ private void execute(String args) throws Exception {
}
return !s.isEmpty();
}).toArray(String[]::new);
- OutputAnalyzer out = ProcessTools.executeTestJvm(safeArgs);
+ OutputAnalyzer out = ProcessTools.executeTestJava(safeArgs);
// Handle response.
if (out.getExitValue() != 0) {
System.out.printf("OUTPUT: %s", out.getOutput());
diff --git a/test/jdk/javax/swing/AbstractButton/5049549/DE1.gif b/test/jdk/javax/swing/AbstractButton/5049549/DE1.gif
deleted file mode 100644
index 3c12953f9a5f1..0000000000000
Binary files a/test/jdk/javax/swing/AbstractButton/5049549/DE1.gif and /dev/null differ
diff --git a/test/jdk/javax/swing/AbstractButton/5049549/DI1.gif b/test/jdk/javax/swing/AbstractButton/5049549/DI1.gif
deleted file mode 100644
index a812a358b9d39..0000000000000
Binary files a/test/jdk/javax/swing/AbstractButton/5049549/DI1.gif and /dev/null differ
diff --git a/test/jdk/javax/swing/AbstractButton/5049549/DS1.gif b/test/jdk/javax/swing/AbstractButton/5049549/DS1.gif
deleted file mode 100644
index 5559452e839af..0000000000000
Binary files a/test/jdk/javax/swing/AbstractButton/5049549/DS1.gif and /dev/null differ
diff --git a/test/jdk/javax/swing/AbstractButton/5049549/PR1.gif b/test/jdk/javax/swing/AbstractButton/5049549/PR1.gif
deleted file mode 100644
index adefa4459d837..0000000000000
Binary files a/test/jdk/javax/swing/AbstractButton/5049549/PR1.gif and /dev/null differ
diff --git a/test/jdk/javax/swing/AbstractButton/5049549/RO1.gif b/test/jdk/javax/swing/AbstractButton/5049549/RO1.gif
deleted file mode 100644
index 68bcf8bed1fa6..0000000000000
Binary files a/test/jdk/javax/swing/AbstractButton/5049549/RO1.gif and /dev/null differ
diff --git a/test/jdk/javax/swing/AbstractButton/5049549/RS1.gif b/test/jdk/javax/swing/AbstractButton/5049549/RS1.gif
deleted file mode 100644
index 09e183eb531cd..0000000000000
Binary files a/test/jdk/javax/swing/AbstractButton/5049549/RS1.gif and /dev/null differ
diff --git a/test/jdk/javax/swing/AbstractButton/5049549/SE1.gif b/test/jdk/javax/swing/AbstractButton/5049549/SE1.gif
deleted file mode 100644
index d408843b33719..0000000000000
Binary files a/test/jdk/javax/swing/AbstractButton/5049549/SE1.gif and /dev/null differ
diff --git a/test/jdk/javax/swing/AbstractButton/5049549/bug5049549.java b/test/jdk/javax/swing/AbstractButton/5049549/bug5049549.java
index fd03f6e918d32..c24435eb18c38 100644
--- a/test/jdk/javax/swing/AbstractButton/5049549/bug5049549.java
+++ b/test/jdk/javax/swing/AbstractButton/5049549/bug5049549.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2023, 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
@@ -21,14 +21,10 @@
* questions.
*/
-/* @test
- @bug 5049549 7132413
- @summary Tests that the proper icon is used for different states.
- @library ../../regtesthelpers
- @build Blocker
- @run main/manual bug5049549
-*/
-
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Graphics;
+import java.awt.image.BufferedImage;
import javax.swing.BoxLayout;
import javax.swing.Icon;
import javax.swing.ImageIcon;
@@ -39,17 +35,39 @@
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
+/*
+ * @test
+ * @bug 5049549 7132413
+ * @summary Tests that the proper icon is used for different states.
+ * @library ../../regtesthelpers
+ * @build Blocker
+ * @run main/manual bug5049549
+ */
public class bug5049549 {
- private static ImageIcon DE = new ImageIcon(bug5049549.class.getResource("DE1.gif"));
- private static ImageIcon DI = new ImageIcon(bug5049549.class.getResource("DI1.gif"));
- private static ImageIcon DS = new ImageIcon(bug5049549.class.getResource("DS1.gif"));
- private static ImageIcon RO = new ImageIcon(bug5049549.class.getResource("RO1.gif"));
- private static ImageIcon RS = new ImageIcon(bug5049549.class.getResource("RS1.gif"));
- private static ImageIcon SE = new ImageIcon(bug5049549.class.getResource("SE1.gif"));
- private static ImageIcon PR = new ImageIcon(bug5049549.class.getResource("PR1.gif"));
-
- private static Blocker blocker = new Blocker();
+ private static final Icon DE = generateImage("DE");
+ private static final Icon DI = generateImage("DI");
+ private static final Icon DS = generateImage("DS");
+ private static final Icon RO = generateImage("RO");
+ private static final Icon RS = generateImage("RS");
+ private static final Icon SE = generateImage("SE");
+ private static final Icon PR = generateImage("PR");
+
+ private static final Blocker blocker = new Blocker();
+
+ private static Icon generateImage(String str) {
+ BufferedImage img = new BufferedImage(40, 30,
+ BufferedImage.TYPE_INT_RGB);
+ Graphics g = img.createGraphics();
+ g.setColor(Color.WHITE);
+ g.fillRect(0, 0, img.getWidth(), img.getHeight());
+ g.setColor(Color.RED);
+ Font font = new Font(Font.SANS_SERIF, Font.BOLD, 22);
+ g.setFont(font);
+ g.drawString(str, 5, 25);
+ g.dispose();
+ return new ImageIcon(img);
+ }
private static class KButton extends JButton {
diff --git a/test/jdk/jdk/classfile/LimitsTest.java b/test/jdk/jdk/classfile/LimitsTest.java
index b89a312a67fd9..d23a948fe9f80 100644
--- a/test/jdk/jdk/classfile/LimitsTest.java
+++ b/test/jdk/jdk/classfile/LimitsTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 8320360
* @summary Testing ClassFile limits.
* @run junit LimitsTest
*/
@@ -85,4 +86,10 @@ void testSupportedClassVersion() {
var cf = ClassFile.of();
assertThrows(IllegalArgumentException.class, () -> cf.parse(cf.build(ClassDesc.of("ClassFromFuture"), cb -> cb.withVersion(ClassFile.latestMajorVersion() + 1, 0))));
}
+
+ @Test
+ void testReadingOutOfBounds() {
+ assertThrows(IllegalArgumentException.class, () -> ClassFile.of().parse(new byte[]{(byte)0xCA, (byte)0xFE, (byte)0xBA, (byte)0xBE}), "reading magic only");
+ assertThrows(IllegalArgumentException.class, () -> ClassFile.of().parse(new byte[]{(byte)0xCA, (byte)0xFE, (byte)0xBA, (byte)0xBE, 0, 0, 0, 0, 0, 2}), "reading invalid CP size");
+ }
}
diff --git a/test/jdk/jdk/classfile/SignaturesTest.java b/test/jdk/jdk/classfile/SignaturesTest.java
index 9f5fbe8adcae2..2c64bacee41ee 100644
--- a/test/jdk/jdk/classfile/SignaturesTest.java
+++ b/test/jdk/jdk/classfile/SignaturesTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
/*
* @test
* @summary Testing Signatures.
+ * @bug 8321540
* @run junit SignaturesTest
*/
import java.io.IOException;
@@ -46,8 +47,11 @@
import java.lang.classfile.Attributes;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import org.junit.jupiter.api.Assertions;
import static helpers.ClassRecord.assertEqualsDeep;
import static java.lang.constant.ConstantDescs.*;
+import java.util.function.Consumer;
+import java.util.function.Function;
class SignaturesTest {
@@ -186,4 +190,79 @@ void testClassSignatureClassDesc() throws IOException {
assertEquals(Outer.Inner.class.describeConstable().orElseThrow(), innerSig.classDesc(),
"ClassDesc derived from signature");
}
+
+ @Test
+ void testBadTypeSignatures() {
+ """
+ LObject
+ LObject;B
+ LIterable
+ LIterable<<
+ TBar
+ TBar
+ B
+ B;V
+ X
+ [LObject
+ [LIterable
+ [LIterable<<
+ [TBar
+ [TBar
+ [B
+ [X
+ LSet<+Kind<**>;>;
+ LSet;>;
+ ()V
+ """.lines().forEach(assertThrows(Signature::parseFrom));
+ }
+
+ @Test
+ void testBadClassSignatures() {
+ """
+ Ljava/lang/Object;Ljava/lang/Iterable
+ LObject
+ LObject;B
+ LIterable
+ LIterable<<
+ TBar
+ TBar
+ B
+ B;V
+ X
+ LFoo.It;L
+ LFoo;LFoo;LBar;
+ >LFoo;
+ LFoo<+>;
+ ()V
+ """.lines().forEach(assertThrows(ClassSignature::parseFrom));
+ }
+
+ @Test
+ void testBadMethodSignatures() {
+ """
+ LObject;
+ B
+ ()V^
+ ()V^B
+ ()V^X
+ (LObject;)
+ (LObject)V
+ ()LIterable
+ ()LIterable<<
+ ()TBar
+ ()TBar;B
+ (TBar)V
+ (B)V
+ (X)
+ ()X
+ ()VB
+ ()LSet<+Kind<**>;>;
+ (LSet;>;)V
+ ()V
+ """.lines().forEach(assertThrows(MethodSignature::parseFrom));
+ }
+
+ private Consumer assertThrows(Function parser) {
+ return s -> Assertions.assertThrows(IllegalArgumentException.class, () -> parser.apply(s), s);
+ }
}
diff --git a/test/jdk/jdk/internal/ref/Cleaner/ExitOnThrow.java b/test/jdk/jdk/internal/ref/Cleaner/ExitOnThrow.java
index 02346414cd3f4..7651c92bf77b2 100644
--- a/test/jdk/jdk/internal/ref/Cleaner/ExitOnThrow.java
+++ b/test/jdk/jdk/internal/ref/Cleaner/ExitOnThrow.java
@@ -44,9 +44,9 @@ public class ExitOnThrow {
public static void main(String[] args) throws Exception {
if (args.length == 0) {
- ProcessTools.executeTestJvm("--add-exports", "java.base/jdk.internal.ref=ALL-UNNAMED",
- "ExitOnThrow",
- "-executeCleaner")
+ ProcessTools.executeTestJava("--add-exports", "java.base/jdk.internal.ref=ALL-UNNAMED",
+ "ExitOnThrow",
+ "-executeCleaner")
.outputTo(System.out)
.errorTo(System.out)
.shouldHaveExitValue(1)
diff --git a/test/jdk/jdk/jfr/api/consumer/security/TestStreamingRemote.java b/test/jdk/jdk/jfr/api/consumer/security/TestStreamingRemote.java
index 6b97613f4ab36..f5a32e0b45a6d 100644
--- a/test/jdk/jdk/jfr/api/consumer/security/TestStreamingRemote.java
+++ b/test/jdk/jdk/jfr/api/consumer/security/TestStreamingRemote.java
@@ -81,7 +81,7 @@ public static void main(String... args) throws Exception {
c[1] = "-Djava.security.policy=" + escapeBackslashes(policy.toString());
c[2] = Test.class.getName();
c[3] = repository;
- OutputAnalyzer oa = ProcessTools.executeTestJvm(c);
+ OutputAnalyzer oa = ProcessTools.executeTestJava(c);
oa.shouldContain(SUCCESS);
}
}
diff --git a/test/jdk/jdk/jfr/event/io/TestInstrumentation.java b/test/jdk/jdk/jfr/event/io/TestInstrumentation.java
index 5e08f45cb5550..ddbc120649762 100644
--- a/test/jdk/jdk/jfr/event/io/TestInstrumentation.java
+++ b/test/jdk/jdk/jfr/event/io/TestInstrumentation.java
@@ -283,7 +283,7 @@ private static void launchTest() throws Throwable {
"-classpath", classpath,
"-javaagent:" + testClassDir + "TestInstrumentation.jar",
"jdk.jfr.event.io.TestInstrumentation$TestMain" };
- OutputAnalyzer output = ProcessTools.executeTestJvm(args);
+ OutputAnalyzer output = ProcessTools.executeTestJava(args);
output.shouldHaveExitValue(0);
}
diff --git a/test/jdk/jdk/jfr/jcmd/TestJcmdPreserveRepository.java b/test/jdk/jdk/jfr/jcmd/TestJcmdPreserveRepository.java
index f1550e633eb4e..2ab6bad625982 100644
--- a/test/jdk/jdk/jfr/jcmd/TestJcmdPreserveRepository.java
+++ b/test/jdk/jdk/jfr/jcmd/TestJcmdPreserveRepository.java
@@ -57,7 +57,7 @@ public static void main(String[] args) throws Throwable {
"-Dtest.jdk=" + System.getProperty("test.jdk"),
TestProcess.class.getName()
};
- OutputAnalyzer output = ProcessTools.executeTestJvm(arguments);
+ OutputAnalyzer output = ProcessTools.executeTestJava(arguments);
output.shouldHaveExitValue(0);
Optional p = Files.find(path, 99, (a,b) -> a.getFileName().toString().endsWith(".jfr")).findAny();
if (p.isEmpty()) {
diff --git a/test/jdk/jdk/nio/zipfs/CorruptedZipFilesTest.java b/test/jdk/jdk/nio/zipfs/CorruptedZipFilesTest.java
index 57287c6d8ee05..39701d073ab3f 100644
--- a/test/jdk/jdk/nio/zipfs/CorruptedZipFilesTest.java
+++ b/test/jdk/jdk/nio/zipfs/CorruptedZipFilesTest.java
@@ -22,7 +22,7 @@
*/
/* @test
- * @bug 8316141
+ * @bug 8316141 8321802
* @summary test for correct detection and reporting of corrupted zip files
* @run junit CorruptedZipFilesTest
*/
@@ -287,6 +287,16 @@ public void unsupportedCompressionMethod() throws IOException {
assertZipException(".*unsupported compression method.*");
}
+ /*
+ * A ZipException is thrown when a LOC header has an unexpected signature
+ */
+ @Test
+ public void invalidLOCSignature() throws IOException {
+ int existingSignature = buffer.getInt(locpos);
+ buffer.putInt(locpos, existingSignature +1);
+ assertZipException(".*bad signature.*");
+ }
+
/*
* Assert that opening a ZIP file and consuming the entry's
* InputStream using the ZipFile API fails with a ZipException
diff --git a/test/jdk/sun/security/mscapi/DupAlias.java b/test/jdk/sun/security/mscapi/DupAlias.java
new file mode 100644
index 0000000000000..84c70cbbee232
--- /dev/null
+++ b/test/jdk/sun/security/mscapi/DupAlias.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2023, 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 jdk.test.lib.Asserts;
+import sun.security.tools.keytool.CertAndKeyGen;
+import sun.security.x509.X500Name;
+
+import java.security.KeyStore;
+import java.security.MessageDigest;
+import java.security.cert.X509Certificate;
+import java.util.HexFormat;
+
+/**
+ * @test
+ * @bug 8187634
+ * @requires os.family == "windows"
+ * @library /test/lib
+ * @modules java.base/sun.security.tools.keytool
+ * java.base/sun.security.x509
+ * @summary getCertificateAlias should return correct alias
+ */
+public class DupAlias {
+ public static void main(String[] args) throws Exception {
+
+ String nn = "8187634";
+ String na = nn + "a";
+ String nb = nn + "b";
+ String n1 = nn + " (1)";
+
+ CertAndKeyGen g = new CertAndKeyGen("EC", "SHA256withECDSA");
+ g.generate(-1);
+ X509Certificate a = g.getSelfCertificate(new X500Name("CN=" + na), 1000);
+ g.generate(-1);
+ X509Certificate b = g.getSelfCertificate(new X500Name("CN=" + nb), 1000);
+
+ KeyStore ks = KeyStore.getInstance("Windows-MY-CURRENTUSER");
+ try {
+ ks.load(null, null);
+ ks.deleteEntry(na);
+ ks.deleteEntry(nb);
+ ks.deleteEntry(nn);
+ ks.deleteEntry(n1);
+ ks.setCertificateEntry(na, a);
+ ks.setCertificateEntry(nb, b);
+
+ ps(String.format("""
+ $cert = Get-Item Cert:/CurrentUser/My/%s;
+ $cert.FriendlyName = %s;
+ $cert = Get-Item Cert:/CurrentUser/My/%s;
+ $cert.FriendlyName = %s;
+ """, thumbprint(a), nn, thumbprint(b), nn));
+
+ ks.load(null, null);
+ Asserts.assertFalse(ks.containsAlias(na));
+ Asserts.assertFalse(ks.containsAlias(nb));
+ Asserts.assertEquals(ks.getCertificateAlias(ks.getCertificate(nn)), nn);
+ Asserts.assertEquals(ks.getCertificateAlias(ks.getCertificate(n1)), n1);
+ } finally {
+ ks.deleteEntry(na);
+ ks.deleteEntry(nb);
+ ks.deleteEntry(nn);
+ ks.deleteEntry(n1);
+ }
+ }
+
+ static void ps(String f) throws Exception {
+ ProcessBuilder pb = new ProcessBuilder("powershell", "-Command", f);
+ pb.inheritIO();
+ if (pb.start().waitFor() != 0) {
+ throw new RuntimeException("Failed");
+ }
+ }
+
+ static String thumbprint(X509Certificate c) throws Exception {
+ return HexFormat.of().formatHex(
+ MessageDigest.getInstance("SHA-1").digest(c.getEncoded()));
+ }
+}
diff --git a/test/jdk/sun/security/pkcs11/Config/ReadConfInUTF16Env.java b/test/jdk/sun/security/pkcs11/Config/ReadConfInUTF16Env.java
index b5ca601c011d6..11a6a781e01d3 100644
--- a/test/jdk/sun/security/pkcs11/Config/ReadConfInUTF16Env.java
+++ b/test/jdk/sun/security/pkcs11/Config/ReadConfInUTF16Env.java
@@ -40,7 +40,7 @@ public class ReadConfInUTF16Env {
public void testReadConfInUTF16Env() throws Exception {
String[] testCommand = new String[] { "-Dfile.encoding=UTF-16",
TestSunPKCS11Provider.class.getName()};
- ProcessTools.executeTestJvm(testCommand).shouldHaveExitValue(0);
+ ProcessTools.executeTestJava(testCommand).shouldHaveExitValue(0);
}
static class TestSunPKCS11Provider {
diff --git a/test/jdk/sun/security/ssl/CertPathRestrictions/TLSRestrictions.java b/test/jdk/sun/security/ssl/CertPathRestrictions/TLSRestrictions.java
index b9fb72b8faf0e..476dc95488495 100644
--- a/test/jdk/sun/security/ssl/CertPathRestrictions/TLSRestrictions.java
+++ b/test/jdk/sun/security/ssl/CertPathRestrictions/TLSRestrictions.java
@@ -231,7 +231,7 @@ static void testConstraint(String[] trustNames, String[] certNames,
// Run client on another JVM so that its properties cannot be in conflict
// with server's.
- OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJvm(
+ OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava(
"-Dcert.dir=" + CERT_DIR,
"-Djava.security.debug=certpath",
"-classpath",
diff --git a/test/jdk/sun/security/ssl/EngineArgs/DebugReportsOneExtraByte.java b/test/jdk/sun/security/ssl/EngineArgs/DebugReportsOneExtraByte.java
index 1ce50662f4647..7632fcf462f9a 100644
--- a/test/jdk/sun/security/ssl/EngineArgs/DebugReportsOneExtraByte.java
+++ b/test/jdk/sun/security/ssl/EngineArgs/DebugReportsOneExtraByte.java
@@ -93,7 +93,7 @@ public class DebugReportsOneExtraByte extends SSLEngineTemplate {
public static void main(String args[]) throws Exception {
if (args.length == 0) {
- OutputAnalyzer output = ProcessTools.executeTestJvm(
+ OutputAnalyzer output = ProcessTools.executeTestJava(
"-Dtest.src=" + System.getProperty("test.src"),
"-Djavax.net.debug=all", "DebugReportsOneExtraByte", "p");
output.shouldContain("WRITE: TLSv1 application_data, length = 8");
diff --git a/test/jdk/sun/security/ssl/SSLLogger/LoggingFormatConsistency.java b/test/jdk/sun/security/ssl/SSLLogger/LoggingFormatConsistency.java
index c614ca62f29a9..5cfa9c9a68008 100644
--- a/test/jdk/sun/security/ssl/SSLLogger/LoggingFormatConsistency.java
+++ b/test/jdk/sun/security/ssl/SSLLogger/LoggingFormatConsistency.java
@@ -50,7 +50,7 @@ public class LoggingFormatConsistency extends SSLSocketTemplate {
public static void main(String[] args) throws Exception {
if (args.length != 0) {
// A non-empty set of arguments occurs when the "runTest" argument
- // is passed to the test via ProcessTools::executeTestJvm.
+ // is passed to the test via ProcessTools::executeTestJava.
//
// This is done because an OutputAnalyzer is unable to read
// the output of the current running JVM, and must therefore create
@@ -71,7 +71,7 @@ public static void main(String[] args) throws Exception {
System.out.println("TESTING " + expectedTLSVersion);
var activeTLSProtocol = "-Djdk.tls.client.protocols=" + expectedTLSVersion;
- var output = ProcessTools.executeTestJvm(
+ var output = ProcessTools.executeTestJava(
testSrc,
activeTLSProtocol,
javaxNetDebug,
diff --git a/test/jdk/sun/security/ssl/SSLSocketImpl/IgnorableExceptionMessages.java b/test/jdk/sun/security/ssl/SSLSocketImpl/IgnorableExceptionMessages.java
index 708b8f0d11bb8..a1c9cad22711a 100644
--- a/test/jdk/sun/security/ssl/SSLSocketImpl/IgnorableExceptionMessages.java
+++ b/test/jdk/sun/security/ssl/SSLSocketImpl/IgnorableExceptionMessages.java
@@ -49,7 +49,7 @@ public class IgnorableExceptionMessages extends SSLSocketTemplate {
public static void main(String[] args) throws Exception {
if (args.length > 0) {
// A non-empty set of arguments occurs when the "runTest" argument
- // is passed to the test via ProcessTools::executeTestJvm.
+ // is passed to the test via ProcessTools::executeTestJava.
//
// This is done because an OutputAnalyzer is unable to read
// the output of the current running JVM, and must therefore create
@@ -67,7 +67,7 @@ public static void main(String[] args) throws Exception {
className,
extraArgument);
- OutputAnalyzer output = ProcessTools.executeTestJvm(jvmArgs);
+ OutputAnalyzer output = ProcessTools.executeTestJava(jvmArgs);
if (output.getExitValue() != 0) {
output.asLines().forEach(System.out::println); // No need to dump the output unless the test fails
diff --git a/test/jdk/sun/security/tools/jarsigner/multiRelease/MVJarSigningTest.java b/test/jdk/sun/security/tools/jarsigner/multiRelease/MVJarSigningTest.java
index ccc4b4051470d..9c9a8590ac74c 100644
--- a/test/jdk/sun/security/tools/jarsigner/multiRelease/MVJarSigningTest.java
+++ b/test/jdk/sun/security/tools/jarsigner/multiRelease/MVJarSigningTest.java
@@ -120,7 +120,7 @@ public static void main(String[] args) throws Throwable {
"-Djava.security.policy=" +
TEST_SRC + File.separator + POLICY_FILE,
"version.Main"};
- ProcessTools.executeTestJvm(cmd)
+ ProcessTools.executeTestJava(cmd)
.shouldHaveExitValue(0)
.shouldContain(VERSION_MESSAGE);
}
diff --git a/test/jdk/sun/security/util/Resources/early/EarlyResources.java b/test/jdk/sun/security/util/Resources/early/EarlyResources.java
index 12da50e311f9e..3ee0a9f576c62 100644
--- a/test/jdk/sun/security/util/Resources/early/EarlyResources.java
+++ b/test/jdk/sun/security/util/Resources/early/EarlyResources.java
@@ -42,7 +42,7 @@ public static void main(String[] args) throws Exception {
String fs = File.separator;
String policyPath = testSrc + fs + "malformed.policy";
- OutputAnalyzer out = ProcessTools.executeTestJvm(
+ OutputAnalyzer out = ProcessTools.executeTestJava(
"-Djava.security.manager",
"-Djava.security.policy=" + policyPath,
"EarlyResources$TestMain");
diff --git a/test/jdk/sun/util/resources/cldr/TimeZoneNamesTest.java b/test/jdk/sun/util/resources/cldr/TimeZoneNamesTest.java
index eb56c087ad654..a468f6b1f1b03 100644
--- a/test/jdk/sun/util/resources/cldr/TimeZoneNamesTest.java
+++ b/test/jdk/sun/util/resources/cldr/TimeZoneNamesTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,9 +23,10 @@
/*
* @test
- * @bug 8181157 8202537 8234347 8236548 8261279
+ * @bug 8181157 8202537 8234347 8236548 8261279 8322647
* @modules jdk.localedata
- * @summary Checks CLDR time zone names are generated correctly at runtime
+ * @summary Checks CLDR time zone names are generated correctly at
+ * either build or runtime
* @run testng/othervm -Djava.locale.providers=CLDR TimeZoneNamesTest
*/
@@ -45,8 +46,8 @@
@Test
public class TimeZoneNamesTest {
- @DataProvider(name="noResourceTZs")
- Object[][] data() {
+ @DataProvider
+ Object[][] sampleTZs() {
return new Object[][] {
// tzid, locale, style, expected
@@ -174,11 +175,49 @@ Object[][] data() {
"UTC+03:00",
"heure : Istanbul",
"UTC+03:00"},
+
+ // Short names derived from TZDB at build time
+ {"Europe/Lisbon", Locale.US, "Western European Standard Time",
+ "WET",
+ "Western European Summer Time",
+ "WEST",
+ "Western European Time",
+ "WET"},
+ {"Atlantic/Azores", Locale.US, "Azores Standard Time",
+ "GMT-01:00",
+ "Azores Summer Time",
+ "GMT",
+ "Azores Time",
+ "GMT-01:00"},
+ {"Australia/Perth", Locale.US, "Australian Western Standard Time",
+ "AWST",
+ "Australian Western Daylight Time",
+ "AWDT",
+ "Western Australia Time",
+ "AWT"},
+ {"Africa/Harare", Locale.US, "Central Africa Time",
+ "CAT",
+ "Harare Daylight Time",
+ "CAT",
+ "Harare Time",
+ "CAT"},
+ {"Europe/Dublin", Locale.US, "Greenwich Mean Time",
+ "GMT",
+ "Irish Standard Time",
+ "IST",
+ "Dublin Time",
+ "GMT"},
+ {"Pacific/Gambier", Locale.US, "Gambier Time",
+ "GMT-09:00",
+ "Gambier Daylight Time",
+ "GMT-09:00",
+ "Gambier Time",
+ "GMT-09:00"},
};
}
- @Test(dataProvider="noResourceTZs")
+ @Test(dataProvider="sampleTZs")
public void test_tzNames(String tzid, Locale locale, String lstd, String sstd, String ldst, String sdst, String lgen, String sgen) {
// Standard time
assertEquals(TimeZone.getTimeZone(tzid).getDisplayName(false, TimeZone.LONG, locale), lstd);
@@ -197,16 +236,14 @@ public void test_tzNames(String tzid, Locale locale, String lstd, String sstd, S
@Test
public void test_getZoneStrings() {
assertFalse(
- Arrays.stream(Locale.getAvailableLocales())
+ Locale.availableLocales()
.limit(30)
.peek(l -> System.out.println("Locale: " + l))
.map(l -> DateFormatSymbols.getInstance(l).getZoneStrings())
- .flatMap(zs -> Arrays.stream(zs))
+ .flatMap(Arrays::stream)
.peek(names -> System.out.println(" tz: " + names[0]))
- .flatMap(names -> Arrays.stream(names))
- .filter(name -> Objects.isNull(name) || name.isEmpty())
- .findAny()
- .isPresent(),
+ .flatMap(Arrays::stream)
+ .anyMatch(name -> Objects.isNull(name) || name.isEmpty()),
"getZoneStrings() returned array containing non-empty string element(s)");
}
}
diff --git a/test/langtools/tools/javac/recovery/AttrRecovery.java b/test/langtools/tools/javac/recovery/AttrRecovery.java
index 607575b291fca..2ab92a625d0e1 100644
--- a/test/langtools/tools/javac/recovery/AttrRecovery.java
+++ b/test/langtools/tools/javac/recovery/AttrRecovery.java
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8301580
+ * @bug 8301580 8322159
* @summary Verify error recovery w.r.t. Attr
* @library /tools/lib
* @enablePreview
@@ -87,4 +87,41 @@ class C {
}
}
+ @Test
+ public void testX() throws Exception {
+ String code = """
+ public class C {
+ public C() {
+ Undefined.method();
+ undefined1();
+ Runnable r = this::undefined2;
+ overridable(this); //to verify ThisEscapeAnalyzer has been run
+ }
+ public void overridable(C c) {}
+ }
+ """;
+ Path curPath = Path.of(".");
+ List actual = new JavacTask(tb)
+ .options("-XDrawDiagnostics", "-XDdev",
+ "-XDshould-stop.at=FLOW", "-Xlint:this-escape")
+ .sources(code)
+ .outdir(curPath)
+ .run(Expect.FAIL)
+ .writeAll()
+ .getOutputLines(OutputKind.DIRECT);
+
+ List expected = List.of(
+ "C.java:3:9: compiler.err.cant.resolve.location: kindname.variable, Undefined, , , (compiler.misc.location: kindname.class, C, null)",
+ "C.java:4:9: compiler.err.cant.resolve.location.args: kindname.method, undefined1, , , (compiler.misc.location: kindname.class, C, null)",
+ "C.java:5:22: compiler.err.invalid.mref: kindname.method, (compiler.misc.cant.resolve.location.args: kindname.method, undefined2, , , (compiler.misc.location: kindname.class, C, null))",
+ "C.java:6:20: compiler.warn.possible.this.escape",
+ "3 errors",
+ "1 warning"
+ );
+
+ if (!Objects.equals(actual, expected)) {
+ error("Expected: " + expected + ", but got: " + actual);
+ }
+ }
+
}
diff --git a/test/lib-test/jdk/test/lib/RandomGeneratorTest.java b/test/lib-test/jdk/test/lib/RandomGeneratorTest.java
index ce57ebfe65f34..71e36bdc9c471 100644
--- a/test/lib-test/jdk/test/lib/RandomGeneratorTest.java
+++ b/test/lib-test/jdk/test/lib/RandomGeneratorTest.java
@@ -69,7 +69,7 @@ public static void main( String[] args) throws Throwable {
jvmArgs.add(origFileName);
int fileNameIndex = jvmArgs.size() - 1;
String[] cmdLineArgs = jvmArgs.toArray(new String[jvmArgs.size()]);
- ProcessTools.executeTestJvm(cmdLineArgs).shouldHaveExitValue(0);
+ ProcessTools.executeTestJava(cmdLineArgs).shouldHaveExitValue(0);
String etalon = Utils.fileAsString(origFileName).trim();
cmdLineArgs[fileNameIndex] = seedOpt.name();
seedOpt.verify(etalon, cmdLineArgs);
@@ -143,7 +143,7 @@ public void verify(String orig, String[] cmdLine) {
String output;
OutputAnalyzer oa;
try {
- oa = ProcessTools.executeTestJvm(cmdLine);
+ oa = ProcessTools.executeTestJava(cmdLine);
} catch (Throwable t) {
throw new Error("TESTBUG: Unexpedted exception during jvm execution.", t);
}
diff --git a/test/lib-test/jdk/test/lib/process/ProcessToolsExecuteLimitedTestJavaTest.java b/test/lib-test/jdk/test/lib/process/ProcessToolsExecuteLimitedTestJavaTest.java
new file mode 100644
index 0000000000000..4331f9ab374f7
--- /dev/null
+++ b/test/lib-test/jdk/test/lib/process/ProcessToolsExecuteLimitedTestJavaTest.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2023, 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
+ * @summary Unit test for ProcessTools.executeLimitedTestJava()
+ * @library /test/lib
+ * @run main/othervm -Dtest.java.opts=-XX:MaxMetaspaceSize=123456789 ProcessToolsExecuteLimitedTestJavaTest
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+public class ProcessToolsExecuteLimitedTestJavaTest {
+ public static void main(String[] args) throws Exception {
+ if (args.length > 0) {
+ // Do nothing. Just let the JVM log its output.
+ } else {
+ // In comparison to executeTestJava, executeLimitedTestJava should not add the
+ // -Dtest.java.opts flags. Check that it doesn't.
+ OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-XX:+PrintFlagsFinal", "-version");
+ output.stdoutShouldNotMatch(".*MaxMetaspaceSize.* = 123456789.*");
+ }
+ }
+}
diff --git a/test/lib/jdk/test/lib/process/OutputAnalyzer.java b/test/lib/jdk/test/lib/process/OutputAnalyzer.java
index e316248fe8ee5..48a0b098d488c 100644
--- a/test/lib/jdk/test/lib/process/OutputAnalyzer.java
+++ b/test/lib/jdk/test/lib/process/OutputAnalyzer.java
@@ -108,6 +108,14 @@ public OutputAnalyzer(String stdout, String stderr, int exitValue)
buffer = OutputBuffer.of(stdout, stderr, exitValue);
}
+ /**
+ * Delegate waitFor to the OutputBuffer. This ensures that
+ * the progress and timestamps are logged correctly.
+ */
+ public void waitFor() {
+ buffer.waitFor();
+ }
+
/**
* Verify that the stdout contents of output buffer is empty
*
diff --git a/test/lib/jdk/test/lib/process/OutputBuffer.java b/test/lib/jdk/test/lib/process/OutputBuffer.java
index fba2a5f6dcf3f..f032591f3584c 100644
--- a/test/lib/jdk/test/lib/process/OutputBuffer.java
+++ b/test/lib/jdk/test/lib/process/OutputBuffer.java
@@ -44,6 +44,12 @@ public OutputBufferException(Throwable cause) {
}
}
+ /**
+ * Waits for a process to finish, if there is one assocated with
+ * this OutputBuffer.
+ */
+ public void waitFor();
+
/**
* Returns the stdout result
*
@@ -67,6 +73,13 @@ default public List getStdoutAsList() {
* @return stderr result
*/
public String getStderr();
+
+
+ /**
+ * Returns the exit value
+ *
+ * @return exit value
+ */
public int getExitValue();
/**
@@ -136,20 +149,12 @@ private LazyOutputBuffer(Process p, Charset cs) {
}
@Override
- public String getStdout() {
- return outTask.get();
- }
-
- @Override
- public String getStderr() {
- return errTask.get();
- }
-
- @Override
- public int getExitValue() {
+ public void waitFor() {
if (exitValue != null) {
- return exitValue;
+ // Already waited for this process
+ return;
}
+
try {
logProgress("Waiting for completion");
boolean aborted = true;
@@ -157,7 +162,6 @@ public int getExitValue() {
exitValue = p.waitFor();
logProgress("Waiting for completion finished");
aborted = false;
- return exitValue;
} finally {
if (aborted) {
logProgress("Waiting for completion FAILED");
@@ -169,6 +173,22 @@ public int getExitValue() {
}
}
+ @Override
+ public String getStdout() {
+ return outTask.get();
+ }
+
+ @Override
+ public String getStderr() {
+ return errTask.get();
+ }
+
+ @Override
+ public int getExitValue() {
+ waitFor();
+ return exitValue;
+ }
+
@Override
public long pid() {
return p.pid();
@@ -186,6 +206,11 @@ private EagerOutputBuffer(String stdout, String stderr, int exitValue) {
this.exitValue = exitValue;
}
+ @Override
+ public void waitFor() {
+ // Nothing to do since this buffer is not associated with a Process.
+ }
+
@Override
public String getStdout() {
return stdout;
diff --git a/test/lib/jdk/test/lib/process/ProcessTools.java b/test/lib/jdk/test/lib/process/ProcessTools.java
index db80a439f2b25..774af8e150dd6 100644
--- a/test/lib/jdk/test/lib/process/ProcessTools.java
+++ b/test/lib/jdk/test/lib/process/ProcessTools.java
@@ -608,43 +608,69 @@ public static ProcessBuilder createLimitedTestJavaProcessBuilder(String... comma
}
/**
- * Executes a test jvm process, waits for it to finish and returns
+ * Executes a process using the java launcher from the jdk to
+ * be tested, waits for it to finish and returns
* the process output.
*
* The process is created using runtime flags set up by:
* {@link #createTestJavaProcessBuilder(String...)}. The
* jvm process will have exited before this method returns.
*
- * @param cmds User specified arguments.
+ * @param command User specified arguments.
* @return The output from the process.
*/
- public static OutputAnalyzer executeTestJvm(List cmds) throws Exception {
- return executeTestJvm(cmds.toArray(String[]::new));
+ public static OutputAnalyzer executeTestJava(List command) throws Exception {
+ return executeTestJava(command.toArray(String[]::new));
}
/**
- * Executes a test jvm process, waits for it to finish and returns
+ * Executes a process using the java launcher from the jdk to
+ * be tested, waits for it to finish and returns
* the process output.
*
* The process is created using runtime flags set up by:
* {@link #createTestJavaProcessBuilder(String...)}. The
* jvm process will have exited before this method returns.
*
- * @param cmds User specified arguments.
+ * @param command User specified arguments.
* @return The output from the process.
*/
- public static OutputAnalyzer executeTestJvm(String... cmds) throws Exception {
- ProcessBuilder pb = createTestJavaProcessBuilder(cmds);
+ public static OutputAnalyzer executeTestJava(String... command) throws Exception {
+ ProcessBuilder pb = createTestJavaProcessBuilder(command);
return executeProcess(pb);
}
/**
- * @param cmds User specified arguments.
+ * Executes a process using the java launcher from the jdk to
+ * be tested, waits for it to finish and returns
+ * the process output.
+ *
+ *
The process is created using runtime flags set up by:
+ * {@link #createLimitedTestJavaProcessBuilder(String...)}. The
+ * jvm process will have exited before this method returns.
+ *
+ * @param command User specified arguments.
* @return The output from the process.
- * @see #executeTestJvm(String...)
*/
- public static OutputAnalyzer executeTestJava(String... cmds) throws Exception {
- return executeTestJvm(cmds);
+ public static OutputAnalyzer executeLimitedTestJava(List command) throws Exception {
+ return executeLimitedTestJava(command.toArray(String[]::new));
+ }
+
+ /**
+ * Executes a process using the java launcher from the jdk to
+ * be tested, waits for it to finish and returns
+ * the process output.
+ *
+ * The process is created using runtime flags set up by:
+ * {@link #createLimitedTestJavaProcessBuilder(String...)}. The
+ * jvm process will have exited before this method returns.
+ *
+ * @param command User specified arguments.
+ * @return The output from the process.
+ */
+ public static OutputAnalyzer executeLimitedTestJava(String... command) throws Exception {
+ ProcessBuilder pb = createLimitedTestJavaProcessBuilder(command);
+ return executeProcess(pb);
}
/**
@@ -697,7 +723,10 @@ public static OutputAnalyzer executeProcess(ProcessBuilder pb, String input,
}
output = new OutputAnalyzer(p, cs);
- p.waitFor();
+
+ // Wait for the process to finish. Call through the output
+ // analyzer to get correct logging and timestamps.
+ output.waitFor();
{ // Dumping the process output to a separate file
var fileName = String.format("pid-%d-output.log", p.pid());
diff --git a/test/lib/jdk/test/lib/thread/VThreadPinner.java b/test/lib/jdk/test/lib/thread/VThreadPinner.java
new file mode 100644
index 0000000000000..25b06912fdf64
--- /dev/null
+++ b/test/lib/jdk/test/lib/thread/VThreadPinner.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.test.lib.thread;
+
+import java.lang.foreign.Arena;
+import java.lang.foreign.FunctionDescriptor;
+import java.lang.foreign.Linker;
+import java.lang.foreign.MemorySegment;
+import java.lang.foreign.SymbolLookup;
+import java.lang.foreign.ValueLayout;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.nio.file.Path;
+import java.time.Duration;
+import java.util.concurrent.atomic.AtomicReference;
+import jdk.test.lib.thread.VThreadRunner.ThrowingRunnable;
+
+/**
+ * Helper class to allow tests run a task in a virtual thread while pinning its carrier.
+ *
+ * It defines the {@code runPinned} method to run a task with a native frame on the stack.
+ */
+public class VThreadPinner {
+ private static final Path JAVA_LIBRARY_PATH = Path.of(System.getProperty("java.library.path"));
+ private static final Path LIB_PATH = JAVA_LIBRARY_PATH.resolve(System.mapLibraryName("VThreadPinner"));
+
+ // method handle to call the native function
+ private static final MethodHandle INVOKER = invoker();
+
+ // function pointer to call
+ private static final MemorySegment UPCALL_STUB = upcallStub();
+
+ /**
+ * Thread local with the task to run.
+ */
+ private static final ThreadLocal TASK_RUNNER = new ThreadLocal<>();
+
+ /**
+ * Runs a task, capturing any exception or error thrown.
+ */
+ private static class TaskRunner implements Runnable {
+ private final ThrowingRunnable> task;
+ private Throwable throwable;
+
+ TaskRunner(ThrowingRunnable> task) {
+ this.task = task;
+ }
+
+ @Override
+ public void run() {
+ try {
+ task.run();
+ } catch (Throwable ex) {
+ throwable = ex;
+ }
+ }
+
+ Throwable exception() {
+ return throwable;
+ }
+ }
+
+ /**
+ * Called by the native function to run the task stashed in the thread local. The
+ * task runs with the native frame on the stack.
+ */
+ private static void callback() {
+ TASK_RUNNER.get().run();
+ }
+
+ /**
+ * Runs the given task on a virtual thread pinned to its carrier. If called from a
+ * virtual thread then it invokes the task directly.
+ */
+ public static void runPinned(ThrowingRunnable task) throws X {
+ if (!Thread.currentThread().isVirtual()) {
+ VThreadRunner.run(() -> runPinned(task));
+ return;
+ }
+ var runner = new TaskRunner(task);
+ TASK_RUNNER.set(runner);
+ try {
+ INVOKER.invoke(UPCALL_STUB);
+ } catch (Throwable e) {
+ throw new RuntimeException(e);
+ } finally {
+ TASK_RUNNER.remove();
+ }
+ Throwable ex = runner.exception();
+ if (ex != null) {
+ if (ex instanceof RuntimeException e)
+ throw e;
+ if (ex instanceof Error e)
+ throw e;
+ throw (X) ex;
+ }
+ }
+
+ /**
+ * Returns a method handle to the native function void call(void *(*f)(void *)).
+ */
+ @SuppressWarnings("restricted")
+ private static MethodHandle invoker() {
+ Linker abi = Linker.nativeLinker();
+ try {
+ SymbolLookup lib = SymbolLookup.libraryLookup(LIB_PATH, Arena.global());
+ MemorySegment symbol = lib.find("call").orElseThrow();
+ FunctionDescriptor desc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS);
+ return abi.downcallHandle(symbol, desc);
+ } catch (Throwable e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Returns an upcall stub to use as a function pointer to invoke the callback method.
+ */
+ @SuppressWarnings("restricted")
+ private static MemorySegment upcallStub() {
+ Linker abi = Linker.nativeLinker();
+ try {
+ MethodHandle callback = MethodHandles.lookup()
+ .findStatic(VThreadPinner.class, "callback", MethodType.methodType(void.class));
+ return abi.upcallStub(callback, FunctionDescriptor.ofVoid(), Arena.global());
+ } catch (Throwable e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/test/lib/jdk/test/lib/thread/VThreadRunner.java b/test/lib/jdk/test/lib/thread/VThreadRunner.java
index 74158c89a1490..ba69496a0473b 100644
--- a/test/lib/jdk/test/lib/thread/VThreadRunner.java
+++ b/test/lib/jdk/test/lib/thread/VThreadRunner.java
@@ -29,7 +29,7 @@
import java.util.concurrent.atomic.AtomicReference;
/**
- * Helper class to support tests running tasks a in virtual thread.
+ * Helper class to support tests running tasks in a virtual thread.
*/
public class VThreadRunner {
private VThreadRunner() { }
@@ -41,38 +41,31 @@ private VThreadRunner() { }
public static final int NO_INHERIT_THREAD_LOCALS = 1 << 2;
/**
- * Represents a task that does not return a result but may throw
- * an exception.
+ * Represents a task that does not return a result but may throw an exception.
*/
@FunctionalInterface
- public interface ThrowingRunnable {
- /**
- * Runs this operation.
- */
- void run() throws Exception;
+ public interface ThrowingRunnable {
+ void run() throws X;
}
/**
* Run a task in a virtual thread and wait for it to terminate.
* If the task completes with an exception then it is thrown by this method.
- * If the task throws an Error then it is wrapped in an RuntimeException.
*
* @param name thread name, can be null
* @param characteristics thread characteristics
* @param task the task to run
- * @throws Exception the exception thrown by the task
+ * @throws X the exception thrown by the task
*/
- public static void run(String name,
- int characteristics,
- ThrowingRunnable task) throws Exception {
- AtomicReference exc = new AtomicReference<>();
- Runnable target = () -> {
+ public static void run(String name,
+ int characteristics,
+ ThrowingRunnable task) throws X {
+ var throwableRef = new AtomicReference();
+ Runnable target = () -> {
try {
task.run();
- } catch (Error e) {
- exc.set(new RuntimeException(e));
- } catch (Exception e) {
- exc.set(e);
+ } catch (Throwable ex) {
+ throwableRef.set(ex);
}
};
@@ -84,54 +77,59 @@ public static void run(String name,
Thread thread = builder.start(target);
// wait for thread to terminate
- while (thread.join(Duration.ofSeconds(10)) == false) {
- System.out.println("-- " + thread + " --");
- for (StackTraceElement e : thread.getStackTrace()) {
- System.out.println(" " + e);
+ try {
+ while (thread.join(Duration.ofSeconds(10)) == false) {
+ System.out.println("-- " + thread + " --");
+ for (StackTraceElement e : thread.getStackTrace()) {
+ System.out.println(" " + e);
+ }
}
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
}
- Exception e = exc.get();
- if (e != null) {
- throw e;
+ Throwable ex = throwableRef.get();
+ if (ex != null) {
+ if (ex instanceof RuntimeException e)
+ throw e;
+ if (ex instanceof Error e)
+ throw e;
+ throw (X) ex;
}
}
/**
* Run a task in a virtual thread and wait for it to terminate.
* If the task completes with an exception then it is thrown by this method.
- * If the task throws an Error then it is wrapped in an RuntimeException.
*
* @param name thread name, can be null
* @param task the task to run
- * @throws Exception the exception thrown by the task
+ * @throws X the exception thrown by the task
*/
- public static void run(String name, ThrowingRunnable task) throws Exception {
+ public static void run(String name, ThrowingRunnable task) throws X {
run(name, 0, task);
}
/**
* Run a task in a virtual thread and wait for it to terminate.
* If the task completes with an exception then it is thrown by this method.
- * If the task throws an Error then it is wrapped in an RuntimeException.
*
* @param characteristics thread characteristics
* @param task the task to run
- * @throws Exception the exception thrown by the task
+ * @throws X the exception thrown by the task
*/
- public static void run(int characteristics, ThrowingRunnable task) throws Exception {
+ public static void run(int characteristics, ThrowingRunnable task) throws X {
run(null, characteristics, task);
}
/**
* Run a task in a virtual thread and wait for it to terminate.
* If the task completes with an exception then it is thrown by this method.
- * If the task throws an Error then it is wrapped in an RuntimeException.
*
* @param task the task to run
- * @throws Exception the exception thrown by the task
+ * @throws X the exception thrown by the task
*/
- public static void run(ThrowingRunnable task) throws Exception {
+ public static void run(ThrowingRunnable task) throws X {
run(null, 0, task);
}
diff --git a/test/lib/jdk/test/lib/thread/libVThreadPinner.c b/test/lib/jdk/test/lib/thread/libVThreadPinner.c
new file mode 100644
index 0000000000000..958e636e3db80
--- /dev/null
+++ b/test/lib/jdk/test/lib/thread/libVThreadPinner.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include
+
+#ifdef _WIN64
+#define EXPORT __declspec(dllexport)
+#else
+#define EXPORT
+#endif
+
+/*
+ * Call a function with the given function pointer.
+ */
+EXPORT void call(void *(*f)(void)) {
+ (*f)();
+}
diff --git a/test/micro/org/openjdk/bench/java/security/SSLHandshake.java b/test/micro/org/openjdk/bench/java/security/SSLHandshake.java
index 67e51e9532d27..62c4504558518 100644
--- a/test/micro/org/openjdk/bench/java/security/SSLHandshake.java
+++ b/test/micro/org/openjdk/bench/java/security/SSLHandshake.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -80,11 +80,12 @@ public void init() throws Exception {
KeyStore ks = TestCertificates.getKeyStore();
KeyStore ts = TestCertificates.getTrustStore();
- KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance(
+ KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks, new char[0]);
- TrustManagerFactory tmf =
- TrustManagerFactory.getInstance("SunX509");
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance(
+ TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ts);
SSLContext sslCtx = SSLContext.getInstance(tlsVersion);
diff --git a/test/micro/org/openjdk/bench/java/security/TestCertificates.java b/test/micro/org/openjdk/bench/java/security/TestCertificates.java
index 50d8401c0708a..752f0442a9381 100644
--- a/test/micro/org/openjdk/bench/java/security/TestCertificates.java
+++ b/test/micro/org/openjdk/bench/java/security/TestCertificates.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -115,12 +115,12 @@ class TestCertificates {
private TestCertificates() {}
public static KeyStore getKeyStore() throws GeneralSecurityException, IOException {
- KeyStore result = KeyStore.getInstance("JKS");
+ KeyStore result = KeyStore.getInstance(KeyStore.getDefaultType());
result.load(null, null);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
Certificate serverCert = cf.generateCertificate(
new ByteArrayInputStream(
- TestCertificates.SERVER_CERT.getBytes(StandardCharsets.ISO_8859_1)));
+ SERVER_CERT.getBytes(StandardCharsets.ISO_8859_1)));
Certificate caCert = cf.generateCertificate(
new ByteArrayInputStream(
CA_CERT.getBytes(StandardCharsets.ISO_8859_1)));
@@ -135,7 +135,7 @@ public static KeyStore getKeyStore() throws GeneralSecurityException, IOExceptio
}
public static KeyStore getTrustStore() throws GeneralSecurityException, IOException {
- KeyStore result = KeyStore.getInstance("JKS");
+ KeyStore result = KeyStore.getInstance(KeyStore.getDefaultType());
result.load(null, null);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
Certificate rootcaCert = cf.generateCertificate(