59 Commits

Author SHA1 Message Date
Severin Gehwolf 3747153d91 8365389: Remove static color fields from SwingUtilities3 and WindowsMenuItemUI
OpenJDK GHA Sanity Checks / Prepare the run (push) Has been cancelled
OpenJDK GHA Sanity Checks / linux-x64 (push) Has been cancelled
OpenJDK GHA Sanity Checks / linux-x64-hs-nopch (push) Has been cancelled
OpenJDK GHA Sanity Checks / linux-x64-hs-zero (push) Has been cancelled
OpenJDK GHA Sanity Checks / linux-x64-hs-minimal (push) Has been cancelled
OpenJDK GHA Sanity Checks / linux-x64-hs-optimized (push) Has been cancelled
OpenJDK GHA Sanity Checks / linux-x64-static (push) Has been cancelled
OpenJDK GHA Sanity Checks / linux-x64-static-libs (push) Has been cancelled
OpenJDK GHA Sanity Checks / linux-cross-compile (push) Has been cancelled
OpenJDK GHA Sanity Checks / alpine-linux-x64 (push) Has been cancelled
OpenJDK GHA Sanity Checks / macos-x64 (push) Has been cancelled
OpenJDK GHA Sanity Checks / macos-aarch64 (push) Has been cancelled
OpenJDK GHA Sanity Checks / windows-x64 (push) Has been cancelled
OpenJDK GHA Sanity Checks / windows-aarch64 (push) Has been cancelled
OpenJDK GHA Sanity Checks / docs (push) Has been cancelled
Backport-of: 3468c6e5ef7e7592cf9484736ce333fbe0eaf34d
2025-09-29 08:45:14 +00:00
Aleksey Shipilev 789ead61bb 8364111: InstanceMirrorKlass iterators should handle CDS and hidden classes consistently
Backport-of: ebb7f5d39be8497fc89e25d0905335102e12c063
2025-09-29 06:51:05 +00:00
Aleksey Shipilev ab772dd2cc 8333783: java/nio/channels/FileChannel/directio/DirectIOTest.java is unstable with AV software
Backport-of: 8c6d12250b524c0f4ee25dbbc6fe959581b7617b
2025-09-29 06:47:45 +00:00
Aleksey Shipilev 6c751f29e4 8367333: C2: Vector math operation intrinsification failure
8367969: C2: compiler/vectorapi/TestVectorMathLib.java fails without UnlockDiagnosticVMOptions

Reviewed-by: eastigeevich, phh
Backport-of: aa36799acb5834d730400fb073a9a3a8ee3c28ef
2025-09-29 06:47:22 +00:00
Aleksey Shipilev 668808f8a3 8362530: VM crash with -XX:+PrintTieredEvents when collecting AOT profiling
Backport-of: 26ccb3cef17a7a2a4b09af1e1e29b96d54a418aa
2025-09-29 06:47:00 +00:00
Sergey Bylokhov ec0d44cf30 8367017: Remove legacy checks from WrappedToolkitTest and convert from bash
Backport-of: e1071797a4f0ab1a6af29824a777a7800d729b0e
2025-09-26 16:00:10 +00:00
Man Cao 9776e4dd74 8368071: Compilation throughput regressed 2X-8X after JDK-8355003
Reviewed-by: shade
Backport-of: bdfe05b595d86c62f7dad78549023a3426423679
2025-09-25 18:53:28 +00:00
Aleksey Shipilev 5861aa7803 8365726: Test crashed with assert in C1 thread: Possible safepoint reached by thread that does not allow it
Backport-of: 452b052fe343a70bc81bf299d08a9f06a1e30fe9
2025-09-25 16:26:10 +00:00
Jayashree S Kumar a8b394bdea 8360178: TestArguments.atojulong gtest has incorrect format string
Backport-of: 878497fb85b9f7d066829b745324028f9f8cdc60
2025-09-25 15:31:40 +00:00
Jayashree S Kumar 5ade8576ab 8361314: Test serviceability/jvmti/VMEvent/MyPackage/VMEventRecursionTest.java FATAL ERROR in native method: Failed during the GetClassSignature call
Backport-of: 8c00c374ec3e5ae2db3c35a970f6c7a691ae274e
2025-09-25 15:29:03 +00:00
Jayashree S Kumar 076de11535 8361253: CommandLineOptionTest library should report observed values on failure
Backport-of: f153e415d740f4ede272929171e9bb3e73ddbe1c
2025-09-25 15:26:54 +00:00
Jayashree S Kumar 00318ca3eb 8361897: gc/z/TestUncommit.java fails with Uncommitted too slow
Backport-of: 3f21c8bd1f0cd7f27df940505b249ba7798940cf
2025-09-25 15:26:20 +00:00
Igor Veresov 17c9b9f9bf 8366948: AOT cache creation crashes when iterating training data
Backport-of: 2aafda1968f3fc8902f7d146a1cba72998aeb976
2025-09-25 15:13:53 +00:00
Matthias Baesken 1fa7ec84db 8362516: Support of GCC static analyzer (-fanalyzer)
Backport-of: ba90ccc6a8ca7b0b728568ea614470c85a5f7f8a
2025-09-25 11:30:38 +00:00
Manukumar V S 40a6020568 8346839: [TESTBUG] "java/awt/textfield/setechochartest4/setechochartest4.java" failed because the test frame disappears on clicking "Click Several Times" button
Backport-of: 58270b757c0bdf82bf753fa304b829e3b64196e4
2025-09-25 11:14:44 +00:00
Aleksey Shipilev 503ba0a93f 8361520: Stabilize SystemGC benchmarks
Backport-of: a9bd1ad40cb4e275d83b2e8b15e3c4be1551f7fc
2025-09-25 11:14:14 +00:00
SendaoYan 147c08cc3a 8366893: java/lang/Thread/virtual/stress/GetStackTraceALotWhenPinned.java timed out on macos-aarch64
Backport-of: 0dad3f1ae8d0c35c4b7a8188ad7854d01c7cd6b4
2025-09-25 09:57:02 +00:00
Fei Yang 74c0684839 8368366: RISC-V: AlignVector is mistakenly set to AvoidUnalignedAccesses
Backport-of: 2313f8e4ebe5b6d7542fa8a33fd08673cc0caf10
2025-09-25 09:38:17 +00:00
Kieran Farrell 3f9c665586 8368308: ISO 4217 Amendment 180 Update
Reviewed-by: naoto, jlu
Backport-of: 85f5bf3f415cc3d44d1618ec574e73f846bb91c4
2025-09-24 19:39:50 +00:00
Ramesh Bhagavatam Gangadhar e90d54198d 8368192: Test java/lang/ProcessBuilder/Basic.java#id0 fails with Exception: Stack trace
Reviewed-by: coffeys
Backport-of: 218e82c875237f82a649a214c72d925a5ebf188c
2025-09-24 11:27:20 +00:00
Fei Yang 1482b6a0db 8362972: C2 fails with unexpected node in SuperWord truncation: IsFiniteF, IsFiniteD
Backport-of: 9f796da3774b2e2f92dca178fdccd93989919256
2025-09-23 00:29:14 +00:00
Sergey Bylokhov 3c07c11d16 8367131: Test com/sun/jdi/ThreadMemoryLeakTest.java fails on 32 bits
Backport-of: fdc11a1569248c9b671b66d547b4616aeb953ecf
2025-09-22 19:33:40 +00:00
Francisco Ferrari Bihurriet c2d79609d8 8367782: VerifyJarEntryName.java: Fix modifyJarEntryName to operate on bytes and re-introduce verifySignatureEntryName
Backport-of: 1b9a11682d5f73885213822423bfce8dfc17febd
2025-09-22 17:26:28 +00:00
Roger Riggs 00be643fa3 8367031: [backout] Change java.time month/day field types to 'byte'
Reviewed-by: lancea, shade, alanb
Backport-of: 0756ecb214b8ab76cb69f354063d153b72f978c2
2025-09-22 15:13:27 +00:00
Tejal Wakchaure cefd94515e 8365919: Replace currentTimeMillis with nanoTime in Stresser.java
Backport-of: 0ca38bdc4d503158fda57bbc8bc9adc420628079
2025-09-22 07:26:28 +00:00
Calvin Cheung 147ed00b20 8357064: cds/appcds/ArchiveRelocationTest.java failed with missing expected output
Backport-of: 534d2b33dc23d0171fdce3cb89d679d5088b4667
2025-09-22 07:25:50 +00:00
Erik Gahlin 304f253df0 8362836: JFR: Broken pipe in jdk/jfr/event/io/TestIOTopFrame.java
Backport-of: 1b94a3466e7bb3815c0caeeeebff6018b6440455
2025-09-22 07:25:19 +00:00
Chad Rakoczy 81493188d6 8277444: Data race between JvmtiClassFileReconstituter::copy_bytecodes and class linking
Backport-of: 46ae1ee87152742082e6047d0556944d7ae4567d
2025-09-19 22:09:20 +00:00
Manukumar V S 4bc1dc3260 8023263: [TESTBUG] Test closed/java/awt/Focus/InactiveWindowTest/InactiveFocusRace fails due to not enough time to initialize graphic components
Backport-of: 5271448b3a013b2e3edcd619a4a3b975b292dae1
2025-09-19 22:05:33 +00:00
Fei Gao c357a2f7db 8364184: [REDO] AArch64: [VectorAPI] sve vector math operations are not supported after JDK-8353217
Backport-of: 51d710e3cc8ee185a0a305e8efcfd03dda41570b
2025-09-19 22:02:53 +00:00
Manukumar V S d930cc5895 8162380: [TEST_BUG] MouseEvent/.../AltGraphModifierTest.java has only "Fail" button
Backport-of: 34c3ac0316dbd29ae670db51bd9230a1e77382d9
2025-09-19 18:54:47 +00:00
Alexey Semenyuk 8b686d9ee4 8365790: Shutdown hook for application image does not work on Windows
Reviewed-by: almatvee, aivanov
Backport-of: f7ce3a1b5f38143f17b5015ca5b714ec0e708f54
2025-09-19 18:43:23 +00:00
Alexey Ivanov 1a69c6b56a 8358532: JFileChooser in GTK L&F still displays HTML filename
Backport-of: 6fe9143bbbe269af62d2084834fc0c9afc51b5f3
2025-09-19 17:00:43 +00:00
Francesco Andreuzzi 9f2d753643 8367689: Revert removal of several compilation-related vmStructs fields
Reviewed-by: aturbanov, shade
Backport-of: 4c5e901c96dee3885e1b29a53d3400174f9bba09
2025-09-19 15:58:56 +00:00
William Kemper d9981960c5 8367378: GenShen: Missing timing stats when old mark buffers are flushed during final update refs
Backport-of: 11df28916af4c2bfd69b2829c74e046ad953ee6c
2025-09-19 07:35:02 +00:00
Alexey Ivanov d8b2de8154 8367348: Enhance PassFailJFrame to support links in HTML
Backport-of: 7a3025e3d7d33ed02db34c1485aa3c7b44b2d8ee
2025-09-18 19:11:29 +00:00
Stefan Johansson 9373d2786c 8366980: TestTransparentHugePagesHeap.java fails when run with -UseCompressedOops
Backport-of: 703d930e4d52a6f9741cf9affee8caade550e67b
2025-09-18 13:03:47 +00:00
Stefan Johansson a66fe2a876 8366434: THP not working properly with G1 after JDK-8345655
Backport-of: a03302d41bb9971736d4d56381ca0cad1eb3e34b
2025-09-18 10:27:59 +00:00
Richard Reingruber 9a0e2ef7f0 8360219: [AIX] assert(locals_base >= l2) failed: bad placement
Backport-of: bea2b029a77e126171d17c3a44baec6d5cafed4a
2025-09-18 07:58:17 +00:00
Aleksey Shipilev fbfcb14383 8364212: Shenandoah: Rework archived objects loading
Backport-of: 68a35511ebd3fd77716242db973104657bc7b541
2025-09-18 07:49:56 +00:00
Matthias Baesken 76798c4739 8364352: Some tests fail when using a limited number of pregenerated .jsa CDS archives
Backport-of: 3ca44c8dea035588070644e5c1f8f25559f66e53
2025-09-18 06:52:58 +00:00
Fei Yang b2484b5e2d 8365926: RISC-V: Performance regression in renaissance (chi-square)
Reviewed-by: rehn
Backport-of: 5c1865a4fcd5da80ddcc506f4e41aada0fb93970
2025-09-18 01:05:07 +00:00
Fei Gao c1c5c95496 8365312: GCC 12 cannot compile SVE on aarch64 with auto-var-init pattern
Backport-of: 999761d0f6d37c9cd6ec482620800b694c5fb9ad
2025-09-17 16:21:52 +00:00
Dingli Zhang b3bd1ec2f7 8367616: RISC-V: Auto-enable Zicboz extension for debug builds
Backport-of: 90e81c2bee86f404250fb9b833d43b18190b5272
2025-09-17 00:55:15 +00:00
Axel Boldt-Christmas 43d9fcc879 8366147: ZGC: ZPageAllocator::cleanup_failed_commit_single_partition may leak memory
Backport-of: 86d6a2e05eb52ea2c603a06bce838a56d5ae507b
2025-09-16 17:21:58 +00:00
Aleksey Shipilev f542b8f0cc 8363966: GHA: Switch cross-compiling sysroots to Debian trixie
Backport-of: 2a5f149bb8e26277778465fff670591c929842de
2025-09-16 16:41:05 +00:00
Anass Baya f80b3a08d7 8346952: GetGraphicsStressTest.java fails: Native resources unavailable
8361839: Problemlist BogusFocusableWindowState due to failures in the CI pipeline

Reviewed-by: aivanov
Backport-of: 44cff9d6abab5df086e89df16f8b63c48cd33c7b
2025-09-16 13:33:46 +00:00
Disha 211e9435d2 8366764: Deproblemlist java/awt/ScrollPane/ScrollPositionTest.java
Backport-of: 9f697c8b1ced41c256bd33f52bdcb2cede2adbf9
2025-09-16 09:46:02 +00:00
Tejal Wakchaure 2a46b6b439 8366029: Do not add -XX:VerifyArchivedFields by default to CDS tests
Backport-of: 15601b4718ed26de6f57e633c4f41f6b0cd90cb0
2025-09-16 09:45:32 +00:00
Matthias Baesken 27c9af8e2f 8365442: [asan] runtime/ErrorHandling/CreateCoredumpOnCrash.java fails
Backport-of: e5ec464120bec50ab111ee32dfb930f26150b109
2025-09-16 09:08:36 +00:00
Matthias Baesken d241152fb1 8366092: [GCC static analyzer] UnixOperatingSystem.c warning: use of uninitialized value 'systemTicks'
Backport-of: a6e2a329a07c71582ac696809fb5349c6a0b681c
2025-09-16 09:06:00 +00:00
Matthias Baesken 07fb86296c 8365700: Jar --validate without any --file option leaves around a temporary file /tmp/tmpJar<number>.jar
Backport-of: 320235ccb88b4b554cd5756b7e6a34ce97aabd53
2025-09-16 08:52:36 +00:00
Dingli Zhang 2ec608f487 8367098: RISC-V: sync CPU features with related JVM flags for dependant ones
Backport-of: f51e442b0e26d0e9ebb6ec0da9584ba4f548322c
2025-09-16 01:08:14 +00:00
Rui Li 569b97fa16 8364296: Set IntelJccErratumMitigation flag ergonomically
Backport-of: 6c5804722b5b2064e0d6ade2180c3126d8f2dabc
2025-09-15 23:09:08 +00:00
Hamlin Li 156fdbe911 8360090: [TEST] RISC-V: disable some cds tests on qemu
Backport-of: c50370599e40bfaeccba9aa6b28da661129f9450
2025-09-15 12:22:20 +00:00
skishor 520ded534d 8361367: AOT ExcludedClasses.java test failed with missing constant pool logs
Backport-of: 92712ef45dd81fa9f03fbd6427f8c1507f28e62b
2025-09-15 11:20:13 +00:00
Hari Prasad Kummari 1173f8ee7c 8364263: HttpClient: Improve encapsulation of ProxyServer
Backport-of: 190e113031bc6ece781fdf0d9f3c853ce324f170
2025-09-15 11:19:31 +00:00
Dingli Zhang 96698162e6 8367137: RISC-V: Detect Zicboz block size via hwprobe
Backport-of: 5abd18426d64f878ca45f9d36ca270be17a7760f
2025-09-13 02:26:49 +00:00
Dingli Zhang 4ad231aa5d 8367066: RISC-V: refine register selection in MacroAssembler:: decode_klass_not_null
Backport-of: 0b3a303053d0eb5a98ed3d9df42c659db148b470
2025-09-13 00:49:59 +00:00
122 changed files with 2117 additions and 1095 deletions
+6 -6
View File
@@ -64,33 +64,33 @@ jobs:
gnu-arch: aarch64
debian-arch: arm64
debian-repository: https://httpredir.debian.org/debian/
debian-version: bookworm
debian-version: trixie
tolerate-sysroot-errors: false
- target-cpu: arm
gnu-arch: arm
debian-arch: armhf
debian-repository: https://httpredir.debian.org/debian/
debian-version: bookworm
debian-version: trixie
tolerate-sysroot-errors: false
gnu-abi: eabihf
- target-cpu: s390x
gnu-arch: s390x
debian-arch: s390x
debian-repository: https://httpredir.debian.org/debian/
debian-version: bookworm
debian-version: trixie
tolerate-sysroot-errors: false
- target-cpu: ppc64le
gnu-arch: powerpc64le
debian-arch: ppc64el
debian-repository: https://httpredir.debian.org/debian/
debian-version: bookworm
debian-version: trixie
tolerate-sysroot-errors: false
- target-cpu: riscv64
gnu-arch: riscv64
debian-arch: riscv64
debian-repository: https://httpredir.debian.org/debian/
debian-version: sid
tolerate-sysroot-errors: true
debian-version: trixie
tolerate-sysroot-errors: false
steps:
- name: 'Checkout the JDK source'
+3
View File
@@ -221,6 +221,9 @@ JDKOPT_SETUP_UNDEFINED_BEHAVIOR_SANITIZER
# LeakSanitizer
JDKOPT_SETUP_LEAK_SANITIZER
# Setup static analyzer
JDKOPT_SETUP_STATIC_ANALYZER
# Fallback linker
# This needs to go before 'LIB_DETERMINE_DEPENDENCIES'
JDKOPT_SETUP_FALLBACK_LINKER
+12 -1
View File
@@ -940,7 +940,7 @@ AC_DEFUN([FLAGS_SETUP_CFLAGS_CPU_DEP],
# ACLE and this flag are required to build the aarch64 SVE related functions in
# libvectormath. Apple Silicon does not support SVE; use macOS as a proxy for
# that check.
if test "x$OPENJDK_TARGET_CPU" = "xaarch64" && test "x$OPENJDK_TARGET_CPU" = "xlinux"; then
if test "x$OPENJDK_TARGET_CPU" = "xaarch64" && test "x$OPENJDK_TARGET_OS" = "xlinux"; then
if test "x$TOOLCHAIN_TYPE" = xgcc || test "x$TOOLCHAIN_TYPE" = xclang; then
AC_LANG_PUSH(C)
OLD_CFLAGS="$CFLAGS"
@@ -954,6 +954,17 @@ AC_DEFUN([FLAGS_SETUP_CFLAGS_CPU_DEP],
[
AC_MSG_RESULT([yes])
$2SVE_CFLAGS="-march=armv8-a+sve"
# Switching the initialization mode with gcc from 'pattern' to 'zero'
# avoids the use of unsupported `__builtin_clear_padding` for variable
# length aggregates
if test "x$DEBUG_LEVEL" != xrelease && test "x$TOOLCHAIN_TYPE" = xgcc ; then
INIT_ZERO_FLAG="-ftrivial-auto-var-init=zero"
FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [$INIT_ZERO_FLAG],
IF_TRUE: [
$2SVE_CFLAGS="${$2SVE_CFLAGS} $INIT_ZERO_FLAG"
]
)
fi
],
[
AC_MSG_RESULT([no])
+25
View File
@@ -479,6 +479,31 @@ AC_DEFUN_ONCE([JDKOPT_SETUP_ADDRESS_SANITIZER],
AC_SUBST(ASAN_ENABLED)
])
################################################################################
#
# Static analyzer
#
AC_DEFUN_ONCE([JDKOPT_SETUP_STATIC_ANALYZER],
[
UTIL_ARG_ENABLE(NAME: static-analyzer, DEFAULT: false, RESULT: STATIC_ANALYZER_ENABLED,
DESC: [enable the GCC static analyzer],
CHECK_AVAILABLE: [
AC_MSG_CHECKING([if static analyzer is available])
if test "x$TOOLCHAIN_TYPE" = "xgcc"; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
AVAILABLE=false
fi
],
IF_ENABLED: [
STATIC_ANALYZER_CFLAGS="-fanalyzer -Wno-analyzer-fd-leak"
CFLAGS_JDKLIB="$CFLAGS_JDKLIB $STATIC_ANALYZER_CFLAGS"
CFLAGS_JDKEXE="$CFLAGS_JDKEXE $STATIC_ANALYZER_CFLAGS"
])
AC_SUBST(STATIC_ANALYZER_ENABLED)
])
################################################################################
#
# LeakSanitizer
@@ -100,7 +100,7 @@ int AbstractInterpreter::size_activation(int max_stack,
// It is also guaranteed to be walkable even though it is in a skeletal state
//
// is_top_frame == true:
// We're processing the *oldest* interpreter frame!
// We're processing the *youngest* interpreter frame on top of stack!
//
// pop_frame_extra_args:
// If this is != 0 we are returning to a deoptimized frame by popping
@@ -131,8 +131,9 @@ void AbstractInterpreter::layout_activation(Method* method,
#ifdef ASSERT
if (caller->is_interpreted_frame()) {
assert(locals_base <= caller->interpreter_frame_expression_stack(), "bad placement");
const int caller_abi_bytesize = (is_bottom_frame ? frame::top_ijava_frame_abi_size : frame::parent_ijava_frame_abi_size);
intptr_t* l2 = caller->sp() + method->max_locals() - 1 + (caller_abi_bytesize / Interpreter::stackElementSize);
// If the bottom frame's caller was thawed then it has frame::java_abi (aka parent_ijava_frame_abi).
// With an ordinary i2c call it would keep the larger frame::top_ijava_frame_abi
intptr_t* l2 = caller->sp() + method->max_locals() - 1 + (frame::parent_ijava_frame_abi_size / Interpreter::stackElementSize);
assert(locals_base >= l2, "bad placement");
}
#endif
+26
View File
@@ -912,6 +912,32 @@ protected:
emit(insn);
}
public:
static uint32_t encode_jal(Register Rd, const int32_t offset) {
guarantee(is_simm21(offset) && ((offset % 2) == 0), "offset is invalid.");
uint32_t insn = 0;
patch((address)&insn, 6, 0, 0b1101111);
patch_reg((address)&insn, 7, Rd);
patch((address)&insn, 19, 12, (uint32_t)((offset >> 12) & 0xff));
patch((address)&insn, 20, (uint32_t)((offset >> 11) & 0x1));
patch((address)&insn, 30, 21, (uint32_t)((offset >> 1) & 0x3ff));
patch((address)&insn, 31, (uint32_t)((offset >> 20) & 0x1));
return insn;
}
static uint32_t encode_jalr(Register Rd, Register Rs, const int32_t offset) {
guarantee(is_simm12(offset), "offset is invalid.");
uint32_t insn = 0;
patch((address)&insn, 6, 0, 0b1100111);
patch_reg((address)&insn, 7, Rd);
patch((address)&insn, 14, 12, 0b000);
patch_reg((address)&insn, 15, Rs);
int32_t val = offset & 0xfff;
patch((address)&insn, 31, 20, val);
return insn;
}
protected:
enum barrier {
+11 -13
View File
@@ -3402,6 +3402,8 @@ void MacroAssembler::decode_klass_not_null(Register r, Register tmp) {
void MacroAssembler::decode_klass_not_null(Register dst, Register src, Register tmp) {
assert(UseCompressedClassPointers, "should only be used for compressed headers");
assert_different_registers(dst, tmp);
assert_different_registers(src, tmp);
if (CompressedKlassPointers::base() == nullptr) {
if (CompressedKlassPointers::shift() != 0) {
@@ -3412,18 +3414,13 @@ void MacroAssembler::decode_klass_not_null(Register dst, Register src, Register
return;
}
Register xbase = dst;
if (dst == src) {
xbase = tmp;
}
Register xbase = tmp;
assert_different_registers(src, xbase);
mv(xbase, (uintptr_t)CompressedKlassPointers::base());
if (CompressedKlassPointers::shift() != 0) {
Register t = src == dst ? dst : t0;
assert_different_registers(t, xbase);
shadd(dst, src, xbase, t, CompressedKlassPointers::shift());
// dst = (src << shift) + xbase
shadd(dst, src, xbase, dst /* temporary, dst != xbase */, CompressedKlassPointers::shift());
} else {
add(dst, xbase, src);
}
@@ -5874,13 +5871,14 @@ void MacroAssembler::fill_words(Register base, Register cnt, Register value) {
// in cnt.
//
// NOTE: This is intended to be used in the zero_blocks() stub. If
// you want to use it elsewhere, note that cnt must be >= CacheLineSize.
// you want to use it elsewhere, note that cnt must be >= zicboz_block_size.
void MacroAssembler::zero_dcache_blocks(Register base, Register cnt, Register tmp1, Register tmp2) {
int zicboz_block_size = VM_Version::zicboz_block_size.value();
Label initial_table_end, loop;
// Align base with cache line size.
neg(tmp1, base);
andi(tmp1, tmp1, CacheLineSize - 1);
andi(tmp1, tmp1, zicboz_block_size - 1);
// tmp1: the number of bytes to be filled to align the base with cache line size.
add(base, base, tmp1);
@@ -5890,16 +5888,16 @@ void MacroAssembler::zero_dcache_blocks(Register base, Register cnt, Register tm
la(tmp1, initial_table_end);
sub(tmp2, tmp1, tmp2);
jr(tmp2);
for (int i = -CacheLineSize + wordSize; i < 0; i += wordSize) {
for (int i = -zicboz_block_size + wordSize; i < 0; i += wordSize) {
sd(zr, Address(base, i));
}
bind(initial_table_end);
mv(tmp1, CacheLineSize / wordSize);
mv(tmp1, zicboz_block_size / wordSize);
bind(loop);
cbo_zero(base);
sub(cnt, cnt, tmp1);
addi(base, base, CacheLineSize);
addi(base, base, zicboz_block_size);
bge(cnt, tmp1, loop);
}
+56 -18
View File
@@ -33,6 +33,7 @@
#include "runtime/safepoint.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
#include "utilities/align.hpp"
#include "utilities/ostream.hpp"
#ifdef COMPILER1
#include "c1/c1_Runtime1.hpp"
@@ -52,15 +53,15 @@ address NativeCall::destination() const {
address addr = instruction_address();
assert(NativeCall::is_at(addr), "unexpected code at call site");
address destination = MacroAssembler::target_addr_for_insn(addr);
address stub_addr = MacroAssembler::target_addr_for_insn(addr);
CodeBlob* cb = CodeCache::find_blob(addr);
assert(cb != nullptr && cb->is_nmethod(), "nmethod expected");
nmethod *nm = (nmethod *)cb;
assert(nm != nullptr, "Sanity");
assert(nm->stub_contains(destination), "Sanity");
assert(destination != nullptr, "Sanity");
return stub_address_destination_at(destination);
assert(nm->stub_contains(stub_addr), "Sanity");
assert(stub_addr != nullptr, "Sanity");
return stub_address_destination_at(stub_addr);
}
address NativeCall::reloc_destination() {
@@ -89,6 +90,30 @@ void NativeCall::print() {
tty->print_cr(PTR_FORMAT ": auipc,ld,jalr x1, offset/reg, ", p2i(instruction_address()));
}
void NativeCall::optimize_call(address dest, bool mt_safe) {
// Skip over auipc + ld
address jmp_ins_pc = instruction_address() + 2 * NativeInstruction::instruction_size;
// Rutime calls may be unaligned, but they are never changed after relocation.
assert(!mt_safe || is_aligned(jmp_ins_pc, NativeInstruction::instruction_size), "Must be naturally aligned: %p", jmp_ins_pc);
// If reachable use JAL
if (Assembler::reachable_from_branch_at(jmp_ins_pc, dest)) {
int64_t distance = dest - jmp_ins_pc;
uint32_t new_jal = Assembler::encode_jal(ra, distance);
Atomic::store((uint32_t *)jmp_ins_pc, new_jal);
} else if (!MacroAssembler::is_jalr_at(jmp_ins_pc)) { // The jalr is always identical: jalr ra, 0(t1)
uint32_t new_jalr = Assembler::encode_jalr(ra, t1, 0);
Atomic::store((uint32_t *)jmp_ins_pc, new_jalr);
} else {
// No change to instruction stream
return;
}
// We changed instruction stream
if (mt_safe) {
// IC invalidate provides a leading full fence, it thus happens after we changed the instruction stream.
ICache::invalidate_range(jmp_ins_pc, NativeInstruction::instruction_size);
}
}
bool NativeCall::set_destination_mt_safe(address dest) {
assert(NativeCall::is_at(instruction_address()), "unexpected code at call site");
assert((CodeCache_lock->is_locked() || SafepointSynchronize::is_at_safepoint()) ||
@@ -96,15 +121,17 @@ bool NativeCall::set_destination_mt_safe(address dest) {
"concurrent code patching");
address stub_addr = stub_address();
if (stub_addr != nullptr) {
set_stub_address_destination_at(stub_addr, dest);
return true;
}
assert(stub_addr != nullptr, "No stub?");
set_stub_address_destination_at(stub_addr, dest); // release
// optimize_call happens after we stored new address in addr stub.
// patches jalr -> jal/jal -> jalr depending on dest
optimize_call(dest, true);
return false;
return true;
}
bool NativeCall::reloc_set_destination(address dest) {
// The argument passed in is the address to the stub containing the destination
bool NativeCall::reloc_set_destination(address stub_addr) {
address call_addr = instruction_address();
assert(NativeCall::is_at(call_addr), "unexpected code at call site");
@@ -113,10 +140,12 @@ bool NativeCall::reloc_set_destination(address dest) {
if (code->is_nmethod()) {
// TODO: Need to revisit this when porting the AOT features.
assert(dest != nullptr, "Sanity");
assert(dest == trampoline_stub_Relocation::get_trampoline_for(call_addr,
code->as_nmethod()), "Sanity");
MacroAssembler::pd_patch_instruction_size(call_addr, dest);
assert(stub_addr != nullptr, "Sanity");
assert(stub_addr == trampoline_stub_Relocation::get_trampoline_for(call_addr, code->as_nmethod()), "Sanity");
MacroAssembler::pd_patch_instruction_size(call_addr, stub_addr); // patches auipc + ld to stub_addr
address dest = stub_address_destination_at(stub_addr);
optimize_call(dest, false); // patches jalr -> jal/jal -> jalr depending on dest
}
return true;
@@ -142,9 +171,9 @@ address NativeCall::stub_address() {
CodeBlob *code = CodeCache::find_blob(call_addr);
assert(code != nullptr, "Could not find the containing code blob");
address dest = MacroAssembler::target_addr_for_insn(call_addr);
assert(code->contains(dest), "Sanity");
return dest;
address stub_addr = MacroAssembler::target_addr_for_insn(call_addr);
assert(code->contains(stub_addr), "Sanity");
return stub_addr;
}
bool NativeCall::is_at(address addr) {
@@ -160,6 +189,15 @@ bool NativeCall::is_at(address addr) {
(MacroAssembler::extract_rd(addr + 2 * instr_size) == x1)) {
return true;
}
if (MacroAssembler::is_auipc_at(addr) &&
MacroAssembler::is_ld_at(addr + instr_size) &&
MacroAssembler::is_jal_at(addr + 2 * instr_size) &&
(MacroAssembler::extract_rd(addr) == x6) &&
(MacroAssembler::extract_rd(addr + instr_size) == x6) &&
(MacroAssembler::extract_rs1(addr + instr_size) == x6) &&
(MacroAssembler::extract_rd(addr + 2 * instr_size) == x1)) {
return true;
}
return false;
}
@@ -157,6 +157,10 @@ class NativeCall: private NativeInstruction {
static void set_stub_address_destination_at(address dest, address value);
// return target address at stub
static address stub_address_destination_at(address src);
// We either have a jalr or jal depending on distance to old destination.
// This method emits a new jal if new destination is within jal reach.
// Otherwise restores the jalr which can reach any destination.
void optimize_call(address dest, bool mt_safe = true);
};
// An interface for accessing/manipulating native mov reg, imm instructions.
+1 -1
View File
@@ -8932,7 +8932,7 @@ instruct encodeKlass_not_null(iRegNNoSp dst, iRegP src) %{
instruct decodeKlass_not_null(iRegPNoSp dst, iRegN src, iRegPNoSp tmp) %{
match(Set dst (DecodeNKlass src));
effect(TEMP tmp);
effect(TEMP_DEF dst, TEMP tmp);
ins_cost(ALU_COST);
format %{ "decode_klass_not_null $dst, $src\t#@decodeKlass_not_null" %}
@@ -683,10 +683,11 @@ class StubGenerator: public StubCodeGenerator {
address start = __ pc();
if (UseBlockZeroing) {
// Ensure count >= 2*CacheLineSize so that it still deserves a cbo.zero
// after alignment.
int zicboz_block_size = VM_Version::zicboz_block_size.value();
// Ensure count >= 2 * zicboz_block_size so that it still deserves
// a cbo.zero after alignment.
Label small;
int low_limit = MAX2(2 * CacheLineSize, BlockZeroingLowLimit) / wordSize;
int low_limit = MAX2(2 * zicboz_block_size, (int)BlockZeroingLowLimit) / wordSize;
__ mv(tmp1, low_limit);
__ blt(cnt, tmp1, small);
__ zero_dcache_blocks(base, cnt, tmp1, tmp2);
+3 -6
View File
@@ -181,12 +181,13 @@ void VM_Version::common_initialize() {
FLAG_SET_DEFAULT(UsePopCountInstruction, false);
}
if (UseZicboz) {
if (UseZicboz && zicboz_block_size.enabled() && zicboz_block_size.value() > 0) {
assert(is_power_of_2(zicboz_block_size.value()), "Sanity");
if (FLAG_IS_DEFAULT(UseBlockZeroing)) {
FLAG_SET_DEFAULT(UseBlockZeroing, true);
}
if (FLAG_IS_DEFAULT(BlockZeroingLowLimit)) {
FLAG_SET_DEFAULT(BlockZeroingLowLimit, 2 * CacheLineSize);
FLAG_SET_DEFAULT(BlockZeroingLowLimit, 4 * zicboz_block_size.value());
}
} else if (UseBlockZeroing) {
warning("Block zeroing is not available");
@@ -476,10 +477,6 @@ void VM_Version::c2_initialize() {
warning("AES/CTR intrinsics are not available on this CPU");
FLAG_SET_DEFAULT(UseAESCTRIntrinsics, false);
}
if (FLAG_IS_DEFAULT(AlignVector)) {
FLAG_SET_DEFAULT(AlignVector, AvoidUnalignedAccesses);
}
}
#endif // COMPILER2
+61 -58
View File
@@ -86,25 +86,27 @@ class VM_Version : public Abstract_VM_Version {
} \
} \
#define UPDATE_DEFAULT_DEP(flag, dep) \
void update_flag() { \
assert(enabled(), "Must be."); \
/* dep must be declared before */ \
assert((uintptr_t)(this) > \
(uintptr_t)(&dep), "Invalid");\
if (FLAG_IS_DEFAULT(flag)) { \
if (dep.enabled()) { \
FLAG_SET_DEFAULT(flag, true); \
} else { \
FLAG_SET_DEFAULT(flag, false); \
} \
} else { \
/* Sync CPU features with flags */ \
if (!flag) { \
disable_feature(); \
} \
} \
} \
#define UPDATE_DEFAULT_DEP(flag, dep) \
void update_flag() { \
assert(enabled(), "Must be."); \
/* dep must be declared before */ \
assert((uintptr_t)(this) > \
(uintptr_t)(&dep), "Invalid"); \
if (FLAG_IS_DEFAULT(flag)) { \
if (dep.enabled()) { \
FLAG_SET_DEFAULT(flag, true); \
} else { \
FLAG_SET_DEFAULT(flag, false); \
/* Sync CPU features with flags */ \
disable_feature(); \
} \
} else { \
/* Sync CPU features with flags */ \
if (!flag) { \
disable_feature(); \
} \
} \
} \
#define NO_UPDATE_DEFAULT \
void update_flag() {} \
@@ -160,45 +162,46 @@ class VM_Version : public Abstract_VM_Version {
// Note: the order matters, depender should be after their dependee. E.g. ext_V before ext_Zvbb.
// declaration name , extension name, bit pos ,in str, mapped flag)
#define RV_FEATURE_FLAGS(decl) \
decl(ext_I , "i" , ('I' - 'A'), true , NO_UPDATE_DEFAULT) \
decl(ext_M , "m" , ('M' - 'A'), true , NO_UPDATE_DEFAULT) \
decl(ext_A , "a" , ('A' - 'A'), true , NO_UPDATE_DEFAULT) \
decl(ext_F , "f" , ('F' - 'A'), true , NO_UPDATE_DEFAULT) \
decl(ext_D , "d" , ('D' - 'A'), true , NO_UPDATE_DEFAULT) \
decl(ext_C , "c" , ('C' - 'A'), true , UPDATE_DEFAULT(UseRVC)) \
decl(ext_Q , "q" , ('Q' - 'A'), true , NO_UPDATE_DEFAULT) \
decl(ext_H , "h" , ('H' - 'A'), true , NO_UPDATE_DEFAULT) \
decl(ext_V , "v" , ('V' - 'A'), true , UPDATE_DEFAULT(UseRVV)) \
decl(ext_Zicbom , "Zicbom" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZicbom)) \
decl(ext_Zicboz , "Zicboz" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZicboz)) \
decl(ext_Zicbop , "Zicbop" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZicbop)) \
decl(ext_Zba , "Zba" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZba)) \
decl(ext_Zbb , "Zbb" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZbb)) \
decl(ext_Zbc , "Zbc" , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \
decl(ext_Zbs , "Zbs" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZbs)) \
decl(ext_Zbkb , "Zbkb" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZbkb)) \
decl(ext_Zcb , "Zcb" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZcb)) \
decl(ext_Zfa , "Zfa" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZfa)) \
decl(ext_Zfh , "Zfh" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZfh)) \
decl(ext_Zfhmin , "Zfhmin" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZfhmin)) \
decl(ext_Zicsr , "Zicsr" , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \
decl(ext_Zicntr , "Zicntr" , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \
decl(ext_Zifencei , "Zifencei" , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \
decl(ext_Zic64b , "Zic64b" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZic64b)) \
decl(ext_Ztso , "Ztso" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZtso)) \
decl(ext_Zihintpause , "Zihintpause" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZihintpause)) \
decl(ext_Zacas , "Zacas" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZacas)) \
decl(ext_Zvbb , "Zvbb" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT_DEP(UseZvbb, ext_V)) \
decl(ext_Zvbc , "Zvbc" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT_DEP(UseZvbc, ext_V)) \
decl(ext_Zvfh , "Zvfh" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT_DEP(UseZvfh, ext_V)) \
decl(ext_Zvkn , "Zvkn" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT_DEP(UseZvkn, ext_V)) \
decl(ext_Zicond , "Zicond" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZicond)) \
decl(mvendorid , "VendorId" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \
decl(marchid , "ArchId" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \
decl(mimpid , "ImpId" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \
decl(unaligned_access, "Unaligned" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \
decl(satp_mode , "SATP" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \
#define RV_FEATURE_FLAGS(decl) \
decl(ext_I , "i" , ('I' - 'A'), true , NO_UPDATE_DEFAULT) \
decl(ext_M , "m" , ('M' - 'A'), true , NO_UPDATE_DEFAULT) \
decl(ext_A , "a" , ('A' - 'A'), true , NO_UPDATE_DEFAULT) \
decl(ext_F , "f" , ('F' - 'A'), true , NO_UPDATE_DEFAULT) \
decl(ext_D , "d" , ('D' - 'A'), true , NO_UPDATE_DEFAULT) \
decl(ext_C , "c" , ('C' - 'A'), true , UPDATE_DEFAULT(UseRVC)) \
decl(ext_Q , "q" , ('Q' - 'A'), true , NO_UPDATE_DEFAULT) \
decl(ext_H , "h" , ('H' - 'A'), true , NO_UPDATE_DEFAULT) \
decl(ext_V , "v" , ('V' - 'A'), true , UPDATE_DEFAULT(UseRVV)) \
decl(ext_Zicbom , "Zicbom" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZicbom)) \
decl(ext_Zicboz , "Zicboz" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZicboz)) \
decl(ext_Zicbop , "Zicbop" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZicbop)) \
decl(ext_Zba , "Zba" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZba)) \
decl(ext_Zbb , "Zbb" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZbb)) \
decl(ext_Zbc , "Zbc" , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \
decl(ext_Zbs , "Zbs" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZbs)) \
decl(ext_Zbkb , "Zbkb" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZbkb)) \
decl(ext_Zcb , "Zcb" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZcb)) \
decl(ext_Zfa , "Zfa" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZfa)) \
decl(ext_Zfh , "Zfh" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZfh)) \
decl(ext_Zfhmin , "Zfhmin" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZfhmin)) \
decl(ext_Zicsr , "Zicsr" , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \
decl(ext_Zicntr , "Zicntr" , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \
decl(ext_Zifencei , "Zifencei" , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \
decl(ext_Zic64b , "Zic64b" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZic64b)) \
decl(ext_Ztso , "Ztso" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZtso)) \
decl(ext_Zihintpause , "Zihintpause" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZihintpause)) \
decl(ext_Zacas , "Zacas" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZacas)) \
decl(ext_Zvbb , "Zvbb" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT_DEP(UseZvbb, ext_V)) \
decl(ext_Zvbc , "Zvbc" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT_DEP(UseZvbc, ext_V)) \
decl(ext_Zvfh , "Zvfh" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT_DEP(UseZvfh, ext_V)) \
decl(ext_Zvkn , "Zvkn" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT_DEP(UseZvkn, ext_V)) \
decl(ext_Zicond , "Zicond" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZicond)) \
decl(mvendorid , "VendorId" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \
decl(marchid , "ArchId" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \
decl(mimpid , "ImpId" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \
decl(unaligned_access , "Unaligned" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \
decl(satp_mode , "SATP" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \
decl(zicboz_block_size, "ZicbozBlockSize", RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \
#define DECLARE_RV_FEATURE(NAME, PRETTY, BIT, FSTRING, FLAGF) \
struct NAME##RVFeatureValue : public RVFeatureValue { \
+1
View File
@@ -1069,6 +1069,7 @@ void VM_Version::get_processor_features() {
if (FLAG_IS_DEFAULT(IntelJccErratumMitigation)) {
_has_intel_jcc_erratum = compute_has_intel_jcc_erratum();
FLAG_SET_ERGO(IntelJccErratumMitigation, _has_intel_jcc_erratum);
} else {
_has_intel_jcc_erratum = IntelJccErratumMitigation;
}
@@ -89,6 +89,8 @@
#define RISCV_HWPROBE_MISALIGNED_UNSUPPORTED (4 << 0)
#define RISCV_HWPROBE_MISALIGNED_MASK (7 << 0)
#define RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE 6
#ifndef NR_riscv_hwprobe
#ifndef NR_arch_specific_syscall
#define NR_arch_specific_syscall 244
@@ -114,7 +116,8 @@ static struct riscv_hwprobe query[] = {{RISCV_HWPROBE_KEY_MVENDORID, 0},
{RISCV_HWPROBE_KEY_MIMPID, 0},
{RISCV_HWPROBE_KEY_BASE_BEHAVIOR, 0},
{RISCV_HWPROBE_KEY_IMA_EXT_0, 0},
{RISCV_HWPROBE_KEY_CPUPERF_0, 0}};
{RISCV_HWPROBE_KEY_CPUPERF_0, 0},
{RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE, 0}};
bool RiscvHwprobe::probe_features() {
assert(!rw_hwprobe_completed, "Called twice.");
@@ -188,6 +191,9 @@ void RiscvHwprobe::add_features_from_query_result() {
VM_Version::ext_Zbs.enable_feature();
}
#ifndef PRODUCT
if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZICBOZ)) {
VM_Version::ext_Zicboz.enable_feature();
}
if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZBKB)) {
VM_Version::ext_Zbkb.enable_feature();
}
@@ -244,4 +250,7 @@ void RiscvHwprobe::add_features_from_query_result() {
VM_Version::unaligned_access.enable_feature(
query[RISCV_HWPROBE_KEY_CPUPERF_0].value & RISCV_HWPROBE_MISALIGNED_MASK);
}
if (is_valid(RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE)) {
VM_Version::zicboz_block_size.enable_feature(query[RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE].value);
}
}
+1
View File
@@ -80,6 +80,7 @@ friend class ciObjectFactory; \
// Any more access must be given explicitly.
#define CI_PACKAGE_ACCESS_TO \
friend class ciObjectFactory; \
friend class VMStructs; \
friend class ciCallSite; \
friend class ciConstantPoolCache; \
friend class ciField; \
@@ -404,7 +404,7 @@ double CompilationPolicy::threshold_scale(CompLevel level, int feedback_k) {
return 1;
}
void CompilationPolicy::print_counters(const char* prefix, Method* m) {
void CompilationPolicy::print_counters_on(outputStream* st, const char* prefix, Method* m) {
int invocation_count = m->invocation_count();
int backedge_count = m->backedge_count();
MethodData* mdh = m->method_data();
@@ -416,133 +416,140 @@ void CompilationPolicy::print_counters(const char* prefix, Method* m) {
mdo_invocations_start = mdh->invocation_count_start();
mdo_backedges_start = mdh->backedge_count_start();
}
tty->print(" %stotal=%d,%d %smdo=%d(%d),%d(%d)", prefix,
invocation_count, backedge_count, prefix,
mdo_invocations, mdo_invocations_start,
mdo_backedges, mdo_backedges_start);
tty->print(" %smax levels=%d,%d", prefix,
m->highest_comp_level(), m->highest_osr_comp_level());
st->print(" %stotal=%d,%d %smdo=%d(%d),%d(%d)", prefix,
invocation_count, backedge_count, prefix,
mdo_invocations, mdo_invocations_start,
mdo_backedges, mdo_backedges_start);
st->print(" %smax levels=%d,%d", prefix, m->highest_comp_level(), m->highest_osr_comp_level());
}
void CompilationPolicy::print_training_data(const char* prefix, Method* method) {
void CompilationPolicy::print_training_data_on(outputStream* st, const char* prefix, Method* method) {
methodHandle m(Thread::current(), method);
tty->print(" %smtd: ", prefix);
st->print(" %smtd: ", prefix);
MethodTrainingData* mtd = MethodTrainingData::find(m);
if (mtd == nullptr) {
tty->print("null");
st->print("null");
} else {
MethodData* md = mtd->final_profile();
tty->print("mdo=");
st->print("mdo=");
if (md == nullptr) {
tty->print("null");
st->print("null");
} else {
int mdo_invocations = md->invocation_count();
int mdo_backedges = md->backedge_count();
int mdo_invocations_start = md->invocation_count_start();
int mdo_backedges_start = md->backedge_count_start();
tty->print("%d(%d), %d(%d)", mdo_invocations, mdo_invocations_start, mdo_backedges, mdo_backedges_start);
st->print("%d(%d), %d(%d)", mdo_invocations, mdo_invocations_start, mdo_backedges, mdo_backedges_start);
}
CompileTrainingData* ctd = mtd->last_toplevel_compile(CompLevel_full_optimization);
tty->print(", deps=");
st->print(", deps=");
if (ctd == nullptr) {
tty->print("null");
st->print("null");
} else {
tty->print("%d", ctd->init_deps_left());
st->print("%d", ctd->init_deps_left());
}
}
}
// Print an event.
void CompilationPolicy::print_event(EventType type, Method* m, Method* im, int bci, CompLevel level) {
void CompilationPolicy::print_event_on(outputStream *st, EventType type, Method* m, Method* im, int bci, CompLevel level) {
bool inlinee_event = m != im;
ttyLocker tty_lock;
tty->print("%lf: [", os::elapsedTime());
st->print("%lf: [", os::elapsedTime());
switch(type) {
case CALL:
tty->print("call");
st->print("call");
break;
case LOOP:
tty->print("loop");
st->print("loop");
break;
case COMPILE:
tty->print("compile");
st->print("compile");
break;
case FORCE_COMPILE:
tty->print("force-compile");
st->print("force-compile");
break;
case REMOVE_FROM_QUEUE:
tty->print("remove-from-queue");
st->print("remove-from-queue");
break;
case UPDATE_IN_QUEUE:
tty->print("update-in-queue");
st->print("update-in-queue");
break;
case REPROFILE:
tty->print("reprofile");
st->print("reprofile");
break;
case MAKE_NOT_ENTRANT:
tty->print("make-not-entrant");
st->print("make-not-entrant");
break;
default:
tty->print("unknown");
st->print("unknown");
}
tty->print(" level=%d ", level);
st->print(" level=%d ", level);
ResourceMark rm;
char *method_name = m->name_and_sig_as_C_string();
tty->print("[%s", method_name);
st->print("[%s", method_name);
if (inlinee_event) {
char *inlinee_name = im->name_and_sig_as_C_string();
tty->print(" [%s]] ", inlinee_name);
st->print(" [%s]] ", inlinee_name);
}
else tty->print("] ");
tty->print("@%d queues=%d,%d", bci, CompileBroker::queue_size(CompLevel_full_profile),
CompileBroker::queue_size(CompLevel_full_optimization));
else st->print("] ");
st->print("@%d queues=%d,%d", bci, CompileBroker::queue_size(CompLevel_full_profile),
CompileBroker::queue_size(CompLevel_full_optimization));
tty->print(" rate=");
if (m->prev_time() == 0) tty->print("n/a");
else tty->print("%f", m->rate());
st->print(" rate=");
if (m->prev_time() == 0) st->print("n/a");
else st->print("%f", m->rate());
tty->print(" k=%.2lf,%.2lf", threshold_scale(CompLevel_full_profile, Tier3LoadFeedback),
threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback));
st->print(" k=%.2lf,%.2lf", threshold_scale(CompLevel_full_profile, Tier3LoadFeedback),
threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback));
if (type != COMPILE) {
print_counters("", m);
print_counters_on(st, "", m);
if (inlinee_event) {
print_counters("inlinee ", im);
print_counters_on(st, "inlinee ", im);
}
tty->print(" compilable=");
st->print(" compilable=");
bool need_comma = false;
if (!m->is_not_compilable(CompLevel_full_profile)) {
tty->print("c1");
st->print("c1");
need_comma = true;
}
if (!m->is_not_osr_compilable(CompLevel_full_profile)) {
if (need_comma) tty->print(",");
tty->print("c1-osr");
if (need_comma) st->print(",");
st->print("c1-osr");
need_comma = true;
}
if (!m->is_not_compilable(CompLevel_full_optimization)) {
if (need_comma) tty->print(",");
tty->print("c2");
if (need_comma) st->print(",");
st->print("c2");
need_comma = true;
}
if (!m->is_not_osr_compilable(CompLevel_full_optimization)) {
if (need_comma) tty->print(",");
tty->print("c2-osr");
if (need_comma) st->print(",");
st->print("c2-osr");
}
tty->print(" status=");
st->print(" status=");
if (m->queued_for_compilation()) {
tty->print("in-queue");
} else tty->print("idle");
print_training_data("", m);
st->print("in-queue");
} else st->print("idle");
print_training_data_on(st, "", m);
if (inlinee_event) {
print_training_data("inlinee ", im);
print_training_data_on(st, "inlinee ", im);
}
}
tty->print_cr("]");
st->print_cr("]");
}
void CompilationPolicy::print_event(EventType type, Method* m, Method* im, int bci, CompLevel level) {
stringStream s;
print_event_on(&s, type, m, im, bci, level);
ResourceMark rm;
tty->print("%s", s.as_string());
}
void CompilationPolicy::initialize() {
@@ -1335,17 +1342,24 @@ CompLevel CompilationPolicy::standard_transition(const methodHandle& method, Com
return next_level;
}
template<typename Predicate> static inline bool apply_predicate(const methodHandle& method, CompLevel cur_level, int i, int b, bool delay_profiling, double delay_profiling_scale) {
if (delay_profiling) {
return Predicate::apply_scaled(method, cur_level, i, b, delay_profiling_scale);
} else {
return Predicate::apply(method, cur_level, i, b);
}
}
template<typename Predicate>
CompLevel CompilationPolicy::transition_from_none(const methodHandle& method, CompLevel cur_level, bool delay_profiling, bool disable_feedback) {
precond(cur_level == CompLevel_none);
CompLevel next_level = cur_level;
int i = method->invocation_count();
int b = method->backedge_count();
double scale = delay_profiling ? Tier0ProfileDelayFactor : 1.0;
// If we were at full profile level, would we switch to full opt?
if (transition_from_full_profile<Predicate>(method, CompLevel_full_profile) == CompLevel_full_optimization) {
next_level = CompLevel_full_optimization;
} else if (!CompilationModeFlag::disable_intermediate() && Predicate::apply_scaled(method, cur_level, i, b, scale)) {
} else if (!CompilationModeFlag::disable_intermediate() && apply_predicate<Predicate>(method, cur_level, i, b, delay_profiling, Tier0ProfileDelayFactor)) {
// C1-generated fully profiled code is about 30% slower than the limited profile
// code that has only invocation and backedge counters. The observation is that
// if C2 queue is large enough we can spend too much time in the fully profiled code
@@ -1387,13 +1401,12 @@ CompLevel CompilationPolicy::transition_from_limited_profile(const methodHandle&
CompLevel next_level = cur_level;
int i = method->invocation_count();
int b = method->backedge_count();
double scale = delay_profiling ? Tier2ProfileDelayFactor : 1.0;
MethodData* mdo = method->method_data();
if (mdo != nullptr) {
if (mdo->would_profile()) {
if (disable_feedback || (CompileBroker::queue_size(CompLevel_full_optimization) <=
Tier3DelayOff * compiler_count(CompLevel_full_optimization) &&
Predicate::apply_scaled(method, cur_level, i, b, scale))) {
apply_predicate<Predicate>(method, cur_level, i, b, delay_profiling, Tier2ProfileDelayFactor))) {
next_level = CompLevel_full_profile;
}
} else {
@@ -1403,7 +1416,7 @@ CompLevel CompilationPolicy::transition_from_limited_profile(const methodHandle&
// If there is no MDO we need to profile
if (disable_feedback || (CompileBroker::queue_size(CompLevel_full_optimization) <=
Tier3DelayOff * compiler_count(CompLevel_full_optimization) &&
Predicate::apply_scaled(method, cur_level, i, b, scale))) {
apply_predicate<Predicate>(method, cur_level, i, b, delay_profiling, Tier2ProfileDelayFactor))) {
next_level = CompLevel_full_profile;
}
}
@@ -287,8 +287,8 @@ class CompilationPolicy : AllStatic {
// loop_event checks if a method should be OSR compiled at a different
// level.
static CompLevel loop_event(const methodHandle& method, CompLevel cur_level, JavaThread* THREAD);
static void print_counters(const char* prefix, Method* m);
static void print_training_data(const char* prefix, Method* method);
static void print_counters_on(outputStream* st, const char* prefix, Method* m);
static void print_training_data_on(outputStream* st, const char* prefix, Method* method);
// Has a method been long around?
// We don't remove old methods from the compile queue even if they have
// very low activity (see select_task()).
@@ -318,6 +318,7 @@ class CompilationPolicy : AllStatic {
static void set_c2_count(int x) { _c2_count = x; }
enum EventType { CALL, LOOP, COMPILE, FORCE_COMPILE, FORCE_RECOMPILE, REMOVE_FROM_QUEUE, UPDATE_IN_QUEUE, REPROFILE, MAKE_NOT_ENTRANT };
static void print_event_on(outputStream *st, EventType type, Method* m, Method* im, int bci, CompLevel level);
static void print_event(EventType type, Method* m, Method* im, int bci, CompLevel level);
// Check if the method can be compiled, change level if necessary
static void compile(const methodHandle& mh, int bci, CompLevel level, TRAPS);
@@ -34,6 +34,7 @@ public:
enum Type {
_alloc_shared, // Allocate common, outside of TLAB
_alloc_shared_gc, // Allocate common, outside of GCLAB/PLAB
_alloc_cds, // Allocate for CDS
_alloc_tlab, // Allocate TLAB
_alloc_gclab, // Allocate GCLAB
_alloc_plab, // Allocate PLAB
@@ -46,6 +47,8 @@ public:
return "Shared";
case _alloc_shared_gc:
return "Shared GC";
case _alloc_cds:
return "CDS";
case _alloc_tlab:
return "TLAB";
case _alloc_gclab:
@@ -121,6 +124,10 @@ public:
return ShenandoahAllocRequest(0, requested_size, _alloc_shared, ShenandoahAffiliation::YOUNG_GENERATION);
}
static inline ShenandoahAllocRequest for_cds(size_t requested_size) {
return ShenandoahAllocRequest(0, requested_size, _alloc_cds, ShenandoahAffiliation::YOUNG_GENERATION);
}
inline size_t size() const {
return _requested_size;
}
@@ -163,6 +170,7 @@ public:
switch (_alloc_type) {
case _alloc_tlab:
case _alloc_shared:
case _alloc_cds:
return true;
case _alloc_gclab:
case _alloc_plab:
@@ -178,6 +186,7 @@ public:
switch (_alloc_type) {
case _alloc_tlab:
case _alloc_shared:
case _alloc_cds:
return false;
case _alloc_gclab:
case _alloc_plab:
@@ -197,6 +206,7 @@ public:
return true;
case _alloc_shared:
case _alloc_shared_gc:
case _alloc_cds:
return false;
default:
ShouldNotReachHere();
@@ -1198,6 +1198,7 @@ void ShenandoahConcurrentGC::op_final_update_refs() {
// We are not concerned about skipping this step in abbreviated cycles because regions
// with no live objects cannot have been written to and so cannot have entries in the SATB
// buffers.
ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_update_refs_transfer_satb);
heap->old_generation()->transfer_pointers_from_satb();
// Aging_cycle is only relevant during evacuation cycle for individual objects and during final mark for
@@ -816,6 +816,7 @@ HeapWord* ShenandoahFreeSet::allocate_single(ShenandoahAllocRequest& req, bool&
switch (req.type()) {
case ShenandoahAllocRequest::_alloc_tlab:
case ShenandoahAllocRequest::_alloc_shared:
case ShenandoahAllocRequest::_alloc_cds:
return allocate_for_mutator(req, in_new_region);
case ShenandoahAllocRequest::_alloc_gclab:
case ShenandoahAllocRequest::_alloc_plab:
@@ -1169,8 +1170,8 @@ HeapWord* ShenandoahFreeSet::try_allocate_in(ShenandoahHeapRegion* r, Shenandoah
return result;
}
HeapWord* ShenandoahFreeSet::allocate_contiguous(ShenandoahAllocRequest& req) {
assert(req.is_mutator_alloc(), "All humongous allocations are performed by mutator");
HeapWord* ShenandoahFreeSet::allocate_contiguous(ShenandoahAllocRequest& req, bool is_humongous) {
assert(req.is_mutator_alloc(), "All contiguous allocations are performed by mutator");
shenandoah_assert_heaplocked();
size_t words_size = req.size();
@@ -1244,10 +1245,16 @@ HeapWord* ShenandoahFreeSet::allocate_contiguous(ShenandoahAllocRequest& req) {
assert(i == beg || _heap->get_region(i - 1)->index() + 1 == r->index(), "Should be contiguous");
assert(r->is_empty(), "Should be empty");
if (i == beg) {
r->make_humongous_start();
r->set_affiliation(req.affiliation());
if (is_humongous) {
if (i == beg) {
r->make_humongous_start();
} else {
r->make_humongous_cont();
}
} else {
r->make_humongous_cont();
r->make_regular_allocation(req.affiliation());
}
// Trailing region may be non-full, record the remainder there
@@ -1257,8 +1264,6 @@ HeapWord* ShenandoahFreeSet::allocate_contiguous(ShenandoahAllocRequest& req) {
} else {
used_words = ShenandoahHeapRegion::region_size_words();
}
r->set_affiliation(req.affiliation());
r->set_update_watermark(r->bottom());
r->set_top(r->bottom() + used_words);
}
@@ -1268,14 +1273,26 @@ HeapWord* ShenandoahFreeSet::allocate_contiguous(ShenandoahAllocRequest& req) {
_heap->notify_mutator_alloc_words(ShenandoahHeapRegion::region_size_words() - remainder, true);
}
// retire_range_from_partition() will adjust bounds on Mutator free set if appropriate
_partitions.retire_range_from_partition(ShenandoahFreeSetPartitionId::Mutator, beg, end);
size_t total_humongous_size = ShenandoahHeapRegion::region_size_bytes() * num;
_partitions.increase_used(ShenandoahFreeSetPartitionId::Mutator, total_humongous_size);
size_t total_used = 0;
if (is_humongous) {
// Humongous allocation retires all regions at once: no allocation is possible anymore.
_partitions.retire_range_from_partition(ShenandoahFreeSetPartitionId::Mutator, beg, end);
total_used = ShenandoahHeapRegion::region_size_bytes() * num;
} else {
// Non-humongous allocation retires only the regions that cannot be used for allocation anymore.
for (idx_t i = beg; i <= end; i++) {
ShenandoahHeapRegion* r = _heap->get_region(i);
if (r->free() < PLAB::min_size() * HeapWordSize) {
_partitions.retire_from_partition(ShenandoahFreeSetPartitionId::Mutator, i, r->used());
}
total_used += r->used();
}
}
_partitions.increase_used(ShenandoahFreeSetPartitionId::Mutator, total_used);
_partitions.assert_bounds();
req.set_actual_size(words_size);
if (remainder != 0) {
if (remainder != 0 && is_humongous) {
req.set_waste(ShenandoahHeapRegion::region_size_words() - remainder);
}
return _heap->get_region(beg)->bottom();
@@ -2064,7 +2081,10 @@ HeapWord* ShenandoahFreeSet::allocate(ShenandoahAllocRequest& req, bool& in_new_
case ShenandoahAllocRequest::_alloc_shared:
case ShenandoahAllocRequest::_alloc_shared_gc:
in_new_region = true;
return allocate_contiguous(req);
return allocate_contiguous(req, /* is_humongous = */ true);
case ShenandoahAllocRequest::_alloc_cds:
in_new_region = true;
return allocate_contiguous(req, /* is_humongous = */ false);
case ShenandoahAllocRequest::_alloc_plab:
case ShenandoahAllocRequest::_alloc_gclab:
case ShenandoahAllocRequest::_alloc_tlab:
@@ -345,7 +345,7 @@ private:
// object. No other objects are packed into these regions.
//
// Precondition: ShenandoahHeapRegion::requires_humongous(req.size())
HeapWord* allocate_contiguous(ShenandoahAllocRequest& req);
HeapWord* allocate_contiguous(ShenandoahAllocRequest& req, bool is_humongous);
// Change region r from the Mutator partition to the GC's Collector or OldCollector partition. This requires that the
// region is entirely empty.
@@ -2796,41 +2796,15 @@ bool ShenandoahHeap::requires_barriers(stackChunkOop obj) const {
HeapWord* ShenandoahHeap::allocate_loaded_archive_space(size_t size) {
#if INCLUDE_CDS_JAVA_HEAP
// CDS wants a continuous memory range to load a bunch of objects.
// This effectively bypasses normal allocation paths, and requires
// a bit of massaging to unbreak GC invariants.
// CDS wants a raw continuous memory range to load a bunch of objects itself.
// This is an unusual request, since all requested regions should be regular, not humongous.
//
// CDS would guarantee no objects straddle multiple regions, as long as regions are as large
// as MIN_GC_REGION_ALIGNMENT.
guarantee(ShenandoahHeapRegion::region_size_bytes() >= ArchiveHeapWriter::MIN_GC_REGION_ALIGNMENT, "Must be");
ShenandoahAllocRequest req = ShenandoahAllocRequest::for_shared(size);
// Easy case: a single regular region, no further adjustments needed.
if (!ShenandoahHeapRegion::requires_humongous(size)) {
return allocate_memory(req);
}
// Hard case: the requested size would cause a humongous allocation.
// We need to make sure it looks like regular allocation to the rest of GC.
// CDS code would guarantee no objects straddle multiple regions, as long as
// regions are as large as MIN_GC_REGION_ALIGNMENT. It is impractical at this
// point to deal with case when Shenandoah runs with smaller regions.
// TODO: This check can be dropped once MIN_GC_REGION_ALIGNMENT agrees more with Shenandoah.
if (ShenandoahHeapRegion::region_size_bytes() < ArchiveHeapWriter::MIN_GC_REGION_ALIGNMENT) {
return nullptr;
}
HeapWord* mem = allocate_memory(req);
size_t start_idx = heap_region_index_containing(mem);
size_t num_regions = ShenandoahHeapRegion::required_regions(size * HeapWordSize);
// Flip humongous -> regular.
{
ShenandoahHeapLocker locker(lock(), false);
for (size_t c = start_idx; c < start_idx + num_regions; c++) {
get_region(c)->make_regular_bypass();
}
}
return mem;
ShenandoahAllocRequest req = ShenandoahAllocRequest::for_cds(size);
return allocate_memory(req);
#else
assert(false, "Archive heap loader should not be available, should not be here");
return nullptr;
@@ -2857,17 +2831,25 @@ void ShenandoahHeap::complete_loaded_archive_space(MemRegion archive_space) {
"Archive space should be fully used: " PTR_FORMAT " " PTR_FORMAT,
p2i(cur), p2i(end));
// Region bounds are good.
ShenandoahHeapRegion* begin_reg = heap_region_containing(start);
ShenandoahHeapRegion* end_reg = heap_region_containing(end);
assert(begin_reg->is_regular(), "Must be");
assert(end_reg->is_regular(), "Must be");
assert(begin_reg->bottom() == start,
"Must agree: archive-space-start: " PTR_FORMAT ", begin-region-bottom: " PTR_FORMAT,
p2i(start), p2i(begin_reg->bottom()));
assert(end_reg->top() == end,
"Must agree: archive-space-end: " PTR_FORMAT ", end-region-top: " PTR_FORMAT,
p2i(end), p2i(end_reg->top()));
// All regions in contiguous space have good state.
size_t begin_reg_idx = heap_region_index_containing(start);
size_t end_reg_idx = heap_region_index_containing(end);
for (size_t idx = begin_reg_idx; idx <= end_reg_idx; idx++) {
ShenandoahHeapRegion* r = get_region(idx);
assert(r->is_regular(), "Must be regular");
assert(r->is_young(), "Must be young");
assert(idx == end_reg_idx || r->top() == r->end(),
"All regions except the last one should be full: " PTR_FORMAT " " PTR_FORMAT,
p2i(r->top()), p2i(r->end()));
assert(idx != begin_reg_idx || r->bottom() == start,
"Archive space start should be at the bottom of first region: " PTR_FORMAT " " PTR_FORMAT,
p2i(r->bottom()), p2i(start));
assert(idx != end_reg_idx || r->top() == end,
"Archive space end should be at the top of last region: " PTR_FORMAT " " PTR_FORMAT,
p2i(r->top()), p2i(end));
}
#endif
}
@@ -142,27 +142,17 @@ void ShenandoahHeapRegion::make_affiliated_maybe() {
void ShenandoahHeapRegion::make_regular_bypass() {
shenandoah_assert_heaplocked();
assert (!Universe::is_fully_initialized() ||
ShenandoahHeap::heap()->is_full_gc_in_progress() ||
assert (ShenandoahHeap::heap()->is_full_gc_in_progress() ||
ShenandoahHeap::heap()->is_degenerated_gc_in_progress(),
"Only for STW GC or when Universe is initializing (CDS)");
"Only for STW GC");
reset_age();
auto cur_state = state();
switch (cur_state) {
switch (state()) {
case _empty_uncommitted:
do_commit();
case _empty_committed:
case _cset:
case _humongous_start:
case _humongous_cont:
if (cur_state == _humongous_start || cur_state == _humongous_cont) {
// CDS allocates chunks of the heap to fill with regular objects. The allocator
// will dutifully track any waste in the unused portion of the last region. Once
// CDS has finished initializing the objects, it will convert these regions to
// regular regions. The 'waste' in the last region is no longer wasted at this point,
// so we must stop treating it as such.
decrement_humongous_waste();
}
set_state(_regular);
return;
case _pinned_cset:
@@ -113,6 +113,7 @@ inline void ShenandoahHeapRegion::adjust_alloc_metadata(ShenandoahAllocRequest::
switch (type) {
case ShenandoahAllocRequest::_alloc_shared:
case ShenandoahAllocRequest::_alloc_shared_gc:
case ShenandoahAllocRequest::_alloc_cds:
// Counted implicitly by tlab/gclab allocs
break;
case ShenandoahAllocRequest::_alloc_tlab:
@@ -126,6 +126,7 @@ class outputStream;
f(final_update_refs, "Pause Final Update Refs (N)") \
f(final_update_refs_verify, " Verify") \
f(final_update_refs_update_region_states, " Update Region States") \
f(final_update_refs_transfer_satb, " Transfer Old From SATB") \
f(final_update_refs_trash_cset, " Trash Collection Set") \
f(final_update_refs_rebuild_freeset, " Rebuild Free Set") \
f(final_update_refs_propagate_gc_state, " Propagate GC State") \
+14 -9
View File
@@ -1087,7 +1087,8 @@ void ZPartition::free_memory_alloc_failed(ZMemoryAllocation* allocation) {
freed += vmem.size();
_cache.insert(vmem);
}
assert(allocation->harvested() + allocation->committed_capacity() == freed, "must have freed all");
assert(allocation->harvested() + allocation->committed_capacity() == freed, "must have freed all"
" %zu + %zu == %zu", allocation->harvested(), allocation->committed_capacity(), freed);
// Adjust capacity to reflect the failed capacity increase
const size_t remaining = allocation->size() - freed;
@@ -1904,23 +1905,27 @@ void ZPageAllocator::cleanup_failed_commit_single_partition(ZSinglePartitionAllo
ZMemoryAllocation* const allocation = single_partition_allocation->allocation();
assert(allocation->commit_failed(), "Must have failed to commit");
assert(allocation->partial_vmems()->is_empty(), "Invariant for single partition commit failure");
const size_t committed = allocation->committed_capacity();
const ZVirtualMemory non_harvested_vmem = vmem.last_part(allocation->harvested());
const ZVirtualMemory committed_vmem = non_harvested_vmem.first_part(committed);
const ZVirtualMemory non_committed_vmem = non_harvested_vmem.last_part(committed);
// For a single partition we have unmapped the harvested memory before we
// started committing, and moved its physical memory association to the start
// of the vmem. As such, the partial_vmems is empty. All the harvested and
// partially successfully committed memory is mapped in the first part of vmem.
const size_t harvested_and_committed_capacity = allocation->harvested() + allocation->committed_capacity();
const ZVirtualMemory succeeded_vmem = vmem.first_part(harvested_and_committed_capacity);
const ZVirtualMemory failed_vmem = vmem.last_part(harvested_and_committed_capacity);
if (committed_vmem.size() > 0) {
if (succeeded_vmem.size() > 0) {
// Register the committed and mapped memory. We insert the committed
// memory into partial_vmems so that it will be inserted into the cache
// in a subsequent step.
allocation->partial_vmems()->append(committed_vmem);
allocation->partial_vmems()->append(succeeded_vmem);
}
// Free the virtual and physical memory we fetched to use but failed to commit
ZPartition& partition = allocation->partition();
partition.free_physical(non_committed_vmem);
partition.free_virtual(non_committed_vmem);
partition.free_physical(failed_vmem);
partition.free_virtual(failed_vmem);
}
void ZPageAllocator::cleanup_failed_commit_multi_partition(ZMultiPartitionAllocation* multi_partition_allocation, const ZVirtualMemory& vmem) {
+3 -2
View File
@@ -113,12 +113,13 @@ static char* reserve_memory_inner(char* requested_address,
ReservedSpace MemoryReserver::reserve_memory(char* requested_address,
size_t size,
size_t alignment,
size_t page_size,
bool exec,
MemTag mem_tag) {
char* base = reserve_memory_inner(requested_address, size, alignment, exec, mem_tag);
if (base != nullptr) {
return ReservedSpace(base, size, alignment, os::vm_page_size(), exec, false /* special */);
return ReservedSpace(base, size, alignment, page_size, exec, false /* special */);
}
// Failed
@@ -191,7 +192,7 @@ ReservedSpace MemoryReserver::reserve(char* requested_address,
}
// == Case 3 ==
return reserve_memory(requested_address, size, alignment, executable, mem_tag);
return reserve_memory(requested_address, size, alignment, page_size, executable, mem_tag);
}
ReservedSpace MemoryReserver::reserve(char* requested_address,
@@ -34,6 +34,7 @@ class MemoryReserver : AllStatic {
static ReservedSpace reserve_memory(char* requested_address,
size_t size,
size_t alignment,
size_t page_size,
bool exec,
MemTag mem_tag);
@@ -52,6 +52,9 @@ class InstanceMirrorKlass: public InstanceKlass {
InstanceMirrorKlass(const ClassFileParser& parser) : InstanceKlass(parser, Kind) {}
template <class OopClosureType>
inline void do_metadata(oop obj, OopClosureType* closure);
public:
InstanceMirrorKlass();
@@ -46,38 +46,41 @@ void InstanceMirrorKlass::oop_oop_iterate_statics(oop obj, OopClosureType* closu
}
}
template <class OopClosureType>
void InstanceMirrorKlass::do_metadata(oop obj, OopClosureType* closure) {
Klass* klass = java_lang_Class::as_Klass(obj);
if (klass != nullptr) {
if (klass->class_loader_data() == nullptr) {
// This is a mirror that belongs to a shared class that has not been loaded yet.
assert(klass->is_shared(), "Must be");
} else if (klass->is_instance_klass() && klass->class_loader_data()->has_class_mirror_holder()) {
// A non-strong hidden class doesn't have its own class loader,
// so when handling the java mirror for the class we need to make sure its class
// loader data is claimed, this is done by calling do_cld explicitly.
// For non-strong hidden classes the call to do_cld is made when the class
// loader itself is handled.
Devirtualizer::do_cld(closure, klass->class_loader_data());
} else {
Devirtualizer::do_klass(closure, klass);
}
} else {
// Java mirror -> Klass* "nullptr" backlink means either:
// 1. This is a Java mirror for a primitive class. We do not need to follow it,
// these mirrors are always strong roots.
// 2. This is a Java mirror for a newly allocated non-primitive class, and we
// somehow managed to reach the newly allocated Java mirror with not yet
// installed backlink. We cannot do anything here, this case would be handled
// separately by GC, e.g. by keeping the relevant metadata alive during the GC.
// Unfortunately, the existence of corner case (2) prevents us from asserting (1).
}
}
template <typename T, class OopClosureType>
void InstanceMirrorKlass::oop_oop_iterate(oop obj, OopClosureType* closure) {
InstanceKlass::oop_oop_iterate<T>(obj, closure);
if (Devirtualizer::do_metadata(closure)) {
Klass* klass = java_lang_Class::as_Klass(obj);
// We'll get null for primitive mirrors.
if (klass != nullptr) {
if (klass->class_loader_data() == nullptr) {
// This is a mirror that belongs to a shared class that has not be loaded yet.
assert(klass->is_shared(), "must be");
} else if (klass->is_instance_klass() && klass->class_loader_data()->has_class_mirror_holder()) {
// A non-strong hidden class doesn't have its own class loader,
// so when handling the java mirror for the class we need to make sure its class
// loader data is claimed, this is done by calling do_cld explicitly.
// For non-strong hidden classes the call to do_cld is made when the class
// loader itself is handled.
Devirtualizer::do_cld(closure, klass->class_loader_data());
} else {
Devirtualizer::do_klass(closure, klass);
}
} else {
// We would like to assert here (as below) that if klass has been null, then
// this has been a mirror for a primitive type that we do not need to follow
// as they are always strong roots.
// However, we might get across a klass that just changed during CMS concurrent
// marking if allocation occurred in the old generation.
// This is benign here, as we keep alive all CLDs that were loaded during the
// CMS concurrent phase in the class loading, i.e. they will be iterated over
// and kept alive during remark.
// assert(java_lang_Class::is_primitive(obj), "Sanity check");
}
do_metadata<OopClosureType>(obj, closure);
}
oop_oop_iterate_statics<T>(obj, closure);
@@ -121,11 +124,7 @@ void InstanceMirrorKlass::oop_oop_iterate_bounded(oop obj, OopClosureType* closu
if (Devirtualizer::do_metadata(closure)) {
if (mr.contains(obj)) {
Klass* klass = java_lang_Class::as_Klass(obj);
// We'll get null for primitive mirrors.
if (klass != nullptr) {
Devirtualizer::do_klass(closure, klass);
}
do_metadata<OopClosureType>(obj, closure);
}
}
+19 -4
View File
@@ -96,7 +96,7 @@ public:
// TrainingDataLocker is used to guard read/write operations on non-MT-safe data structures.
// It supports recursive locking and a read-only mode (in which case no locks are taken).
// It is also a part of the TD collection termination protocol (see the "spanshot" field).
// It is also a part of the TD collection termination protocol (see the "snapshot" field).
class TrainingDataLocker {
static volatile bool _snapshot; // If true we're not allocating new training data
static int _lock_mode;
@@ -105,7 +105,7 @@ public:
#if INCLUDE_CDS
assert(_lock_mode != 0, "Forgot to call TrainingDataLocker::initialize()");
if (_lock_mode > 0) {
TrainingData_lock->lock();
TrainingData_lock->lock_without_safepoint_check();
}
#endif
}
@@ -152,6 +152,9 @@ public:
_lock_mode = need_data() ? +1 : -1; // if -1, we go lock-free
#endif
}
static void assert_locked_or_snapshotted() {
assert(safely_locked() || _snapshot, "use under TrainingDataLocker or after snapshot");
}
static void assert_locked() {
assert(safely_locked(), "use under TrainingDataLocker");
}
@@ -338,20 +341,24 @@ private:
}
int length() const {
TrainingDataLocker::assert_locked_or_snapshotted();
return (_deps_dyn != nullptr ? _deps_dyn->length()
: _deps != nullptr ? _deps->length()
: 0);
}
E* adr_at(int i) const {
TrainingDataLocker::assert_locked_or_snapshotted();
return (_deps_dyn != nullptr ? _deps_dyn->adr_at(i)
: _deps != nullptr ? _deps->adr_at(i)
: nullptr);
}
E at(int i) const {
TrainingDataLocker::assert_locked_or_snapshotted();
assert(i >= 0 && i < length(), "oob");
return *adr_at(i);
}
bool append_if_missing(E dep) {
TrainingDataLocker::assert_can_add();
if (_deps_dyn == nullptr) {
_deps_dyn = new GrowableArrayCHeap<E, mtCompiler>(10);
_deps_dyn->append(dep);
@@ -361,23 +368,27 @@ private:
}
}
bool remove_if_existing(E dep) {
TrainingDataLocker::assert_can_add();
if (_deps_dyn != nullptr) {
return _deps_dyn->remove_if_existing(dep);
}
return false;
}
void clear() {
TrainingDataLocker::assert_can_add();
if (_deps_dyn != nullptr) {
_deps_dyn->clear();
}
}
void append(E dep) {
TrainingDataLocker::assert_can_add();
if (_deps_dyn == nullptr) {
_deps_dyn = new GrowableArrayCHeap<E, mtCompiler>(10);
}
_deps_dyn->append(dep);
}
bool contains(E dep) {
TrainingDataLocker::assert_locked();
for (int i = 0; i < length(); i++) {
if (dep == at(i)) {
return true; // found
@@ -593,6 +604,7 @@ public:
DepList<Record> _data;
public:
OptionalReturnType find(const Args&... args) {
TrainingDataLocker l;
ArgumentsType a(args...);
for (int i = 0; i < _data.length(); i++) {
if (_data.at(i).arguments() == a) {
@@ -601,8 +613,11 @@ public:
}
return OptionalReturnType(false, ReturnType());
}
bool append_if_missing(const ReturnType& result, const Args&... args) {
return _data.append_if_missing(Record(result, ArgumentsType(args...)));
void append_if_missing(const ReturnType& result, const Args&... args) {
TrainingDataLocker l;
if (l.can_add()) {
_data.append_if_missing(Record(result, ArgumentsType(args...)));
}
}
#if INCLUDE_CDS
void remove_unshareable_info() { _data.remove_unshareable_info(); }
+2
View File
@@ -2593,6 +2593,8 @@ static bool can_subword_truncate(Node* in, const Type* type) {
case Op_ReverseI:
case Op_CountLeadingZerosI:
case Op_CountTrailingZerosI:
case Op_IsFiniteF:
case Op_IsFiniteD:
case Op_IsInfiniteF:
case Op_IsInfiniteD:
case Op_ExtractS:
@@ -996,6 +996,11 @@ void JvmtiClassFileReconstituter::write_u8(u8 x) {
void JvmtiClassFileReconstituter::copy_bytecodes(const methodHandle& mh,
unsigned char* bytecodes) {
// We must copy bytecodes only from linked classes.
// Being linked guarantees we are not getting bytecodes at
// the same time the linking process is rewriting them.
guarantee(mh->method_holder()->is_linked(), "Bytecodes must be copied from a linked class");
// use a BytecodeStream to iterate over the bytecodes. JVM/fast bytecodes
// and the breakpoint bytecode are converted to their original bytecodes.
+21 -1
View File
@@ -451,6 +451,18 @@ JvmtiEnv::RetransformClasses(jint class_count, const jclass* classes) {
InstanceKlass* ik = InstanceKlass::cast(klass);
if (ik->get_cached_class_file_bytes() == nullptr) {
// Link the class to avoid races with the rewriter. This will call the verifier also
// on the class. Linking is also done in VM_RedefineClasses below, but we need
// to keep that for other VM_RedefineClasses callers.
JavaThread* THREAD = current_thread;
ik->link_class(THREAD);
if (HAS_PENDING_EXCEPTION) {
// Retransform/JVMTI swallows error messages. Using this class will rerun the verifier in a context
// that propagates the VerifyError, if thrown.
CLEAR_PENDING_EXCEPTION;
return JVMTI_ERROR_INVALID_CLASS;
}
// Not cached, we need to reconstitute the class file from the
// VM representation. We don't attach the reconstituted class
// bytes to the InstanceKlass here because they have not been
@@ -3428,7 +3440,8 @@ jvmtiError
JvmtiEnv::GetBytecodes(Method* method, jint* bytecode_count_ptr, unsigned char** bytecodes_ptr) {
NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);
methodHandle mh(Thread::current(), method);
JavaThread* current_thread = JavaThread::current();
methodHandle mh(current_thread, method);
jint size = (jint)mh->code_size();
jvmtiError err = allocate(size, bytecodes_ptr);
if (err != JVMTI_ERROR_NONE) {
@@ -3437,6 +3450,13 @@ JvmtiEnv::GetBytecodes(Method* method, jint* bytecode_count_ptr, unsigned char**
(*bytecode_count_ptr) = size;
// get byte codes
// Make sure the class is verified and rewritten first.
JavaThread* THREAD = current_thread;
mh->method_holder()->link_class(THREAD);
if (HAS_PENDING_EXCEPTION) {
CLEAR_PENDING_EXCEPTION;
return JVMTI_ERROR_INVALID_CLASS;
}
JvmtiClassFileReconstituter::copy_bytecodes(mh, *bytecodes_ptr);
return JVMTI_ERROR_NONE;
+19
View File
@@ -593,6 +593,25 @@ int VectorSupport::vop2ideal(jint id, BasicType bt) {
break;
}
case VECTOR_OP_TAN: // fall-through
case VECTOR_OP_TANH: // fall-through
case VECTOR_OP_SIN: // fall-through
case VECTOR_OP_SINH: // fall-through
case VECTOR_OP_COS: // fall-through
case VECTOR_OP_COSH: // fall-through
case VECTOR_OP_ASIN: // fall-through
case VECTOR_OP_ACOS: // fall-through
case VECTOR_OP_ATAN: // fall-through
case VECTOR_OP_ATAN2: // fall-through
case VECTOR_OP_CBRT: // fall-through
case VECTOR_OP_LOG: // fall-through
case VECTOR_OP_LOG10: // fall-through
case VECTOR_OP_LOG1P: // fall-through
case VECTOR_OP_POW: // fall-through
case VECTOR_OP_EXP: // fall-through
case VECTOR_OP_EXPM1: // fall-through
case VECTOR_OP_HYPOT: return 0; // not supported; should be handled in Java code
default: fatal("unknown op: %d", vop);
}
return 0; // Unimplemented
+19
View File
@@ -101,6 +101,25 @@ class VectorSupport : AllStatic {
VECTOR_OP_COMPRESS_BITS = 33,
VECTOR_OP_EXPAND_BITS = 34,
VECTOR_OP_TAN = 101,
VECTOR_OP_TANH = 102,
VECTOR_OP_SIN = 103,
VECTOR_OP_SINH = 104,
VECTOR_OP_COS = 105,
VECTOR_OP_COSH = 106,
VECTOR_OP_ASIN = 107,
VECTOR_OP_ACOS = 108,
VECTOR_OP_ATAN = 109,
VECTOR_OP_ATAN2 = 110,
VECTOR_OP_CBRT = 111,
VECTOR_OP_LOG = 112,
VECTOR_OP_LOG10 = 113,
VECTOR_OP_LOG1P = 114,
VECTOR_OP_POW = 115,
VECTOR_OP_EXP = 116,
VECTOR_OP_EXPM1 = 117,
VECTOR_OP_HYPOT = 118,
VECTOR_OP_SADD = 119,
VECTOR_OP_SSUB = 120,
VECTOR_OP_SUADD = 121,
+1 -1
View File
@@ -259,7 +259,7 @@ void mutex_init() {
MUTEX_DEFN(CompiledIC_lock , PaddedMutex , nosafepoint); // locks VtableStubs_lock
MUTEX_DEFN(MethodCompileQueue_lock , PaddedMonitor, safepoint);
MUTEX_DEFL(TrainingData_lock , PaddedMutex , MethodCompileQueue_lock);
MUTEX_DEFN(TrainingData_lock , PaddedMutex , nosafepoint);
MUTEX_DEFN(TrainingReplayQueue_lock , PaddedMonitor, safepoint);
MUTEX_DEFN(CompileStatistics_lock , PaddedMutex , safepoint);
MUTEX_DEFN(DirectivesStack_lock , PaddedMutex , nosafepoint);
+14
View File
@@ -667,6 +667,14 @@
static_field(VMRegImpl, regName[0], const char*) \
static_field(VMRegImpl, stack0, VMReg) \
\
/******************************************************************************************/ \
/* CI (NOTE: these CI fields are retained in VMStructs for the benefit of external tools, */ \
/* to ease their migration to a future alternative.) */ \
/******************************************************************************************/ \
\
nonstatic_field(CompilerThread, _env, ciEnv*) \
nonstatic_field(ciEnv, _task, CompileTask*) \
\
/************/ \
/* Monitors */ \
/************/ \
@@ -1150,6 +1158,12 @@
declare_toplevel_type(BasicLock) \
declare_toplevel_type(BasicObjectLock) \
\
/*********************/ \
/* CI */ \
/*********************/ \
\
declare_toplevel_type(ciEnv) \
\
/********************/ \
/* -XX flags */ \
/********************/ \
@@ -182,11 +182,11 @@ public final class LocalDate
/**
* @serial The month-of-year.
*/
private final byte month;
private final short month;
/**
* @serial The day-of-month.
*/
private final byte day;
private final short day;
//-----------------------------------------------------------------------
/**
@@ -490,8 +490,8 @@ public final class LocalDate
*/
private LocalDate(int year, int month, int dayOfMonth) {
this.year = year;
this.month = (byte) month;
this.day = (byte) dayOfMonth;
this.month = (short) month;
this.day = (short) dayOfMonth;
}
//-----------------------------------------------------------------------
@@ -146,11 +146,11 @@ public final class MonthDay
/**
* @serial The month-of-year, not null.
*/
private final byte month;
private final int month;
/**
* @serial The day-of-month.
*/
private final byte day;
private final int day;
//-----------------------------------------------------------------------
/**
@@ -319,8 +319,8 @@ public final class MonthDay
* @param dayOfMonth the day-of-month to represent, validated from 1 to 29-31
*/
private MonthDay(int month, int dayOfMonth) {
this.month = (byte) month;
this.day = (byte) dayOfMonth;
this.month = month;
this.day = dayOfMonth;
}
//-----------------------------------------------------------------------
@@ -153,7 +153,7 @@ public final class YearMonth
/**
* @serial The month-of-year, not null.
*/
private final byte month;
private final int month;
//-----------------------------------------------------------------------
/**
@@ -306,7 +306,7 @@ public final class YearMonth
*/
private YearMonth(int year, int month) {
this.year = year;
this.month = (byte) month;
this.month = month;
}
/**
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2019, 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
@@ -137,11 +137,11 @@ public final class HijrahDate
/**
* The month-of-year.
*/
private final transient byte monthOfYear;
private final transient int monthOfYear;
/**
* The day-of-month.
*/
private final transient byte dayOfMonth;
private final transient int dayOfMonth;
//-------------------------------------------------------------------------
/**
@@ -273,8 +273,8 @@ public final class HijrahDate
this.chrono = chrono;
this.prolepticYear = prolepticYear;
this.monthOfYear = (byte) monthOfYear;
this.dayOfMonth = (byte) dayOfMonth;
this.monthOfYear = monthOfYear;
this.dayOfMonth = dayOfMonth;
}
/**
@@ -287,8 +287,8 @@ public final class HijrahDate
this.chrono = chrono;
this.prolepticYear = dateInfo[0];
this.monthOfYear = (byte) dateInfo[1];
this.dayOfMonth = (byte) dateInfo[2];
this.monthOfYear = dateInfo[1];
this.dayOfMonth = dateInfo[2];
}
//-----------------------------------------------------------------------
@@ -32,7 +32,7 @@ formatVersion=3
# Version of the currency code information in this class.
# It is a serial number that accompanies with each amendment.
dataVersion=179
dataVersion=180
# List of all valid ISO 4217 currency codes.
# To ensure compatibility, do not remove codes.
@@ -147,7 +147,7 @@ IO=USD
# BRUNEI DARUSSALAM
BN=BND
# BULGARIA
BG=BGN
BG=BGN;2025-12-31-22-00-00;EUR
# BURKINA FASO
BF=XOF
# BURUNDI
@@ -193,7 +193,7 @@ HR=EUR
# CUBA
CU=CUP
# Curaçao
CW=ANG;2025-04-01-04-00-00;XCG
CW=XCG
# CYPRUS
CY=EUR
# CZECHIA
@@ -510,7 +510,7 @@ SR=SRD
# SVALBARD AND JAN MAYEN
SJ=NOK
# Sint Maarten (Dutch part)
SX=ANG;2025-04-01-04-00-00;XCG
SX=XCG
# ESWATINI
SZ=SZL
# SWEDEN
@@ -72,10 +72,6 @@ public class SwingUtilities3 {
private static final Object DELEGATE_REPAINT_MANAGER_KEY =
new StringBuilder("DelegateRepaintManagerKey");
private static Color disabledForeground;
private static Color acceleratorSelectionForeground;
private static Color acceleratorForeground;
/**
* Registers delegate RepaintManager for {@code JComponent}.
*/
@@ -210,7 +206,10 @@ public class SwingUtilities3 {
public static void paintAccText(Graphics g, MenuItemLayoutHelper lh,
MenuItemLayoutHelper.LayoutResult lr) {
MenuItemLayoutHelper.LayoutResult lr,
Color disabledForeground,
Color acceleratorSelectionForeground,
Color acceleratorForeground) {
if (!lh.getAccText().isEmpty()) {
ButtonModel model = lh.getMenuItem().getModel();
g.setFont(lh.getAccFontMetrics().getFont());
@@ -249,18 +248,6 @@ public class SwingUtilities3 {
}
}
public static void setDisabledForeground(Color disabledFg) {
disabledForeground = disabledFg;
}
public static void setAcceleratorSelectionForeground(Color acceleratorSelectionFg) {
acceleratorSelectionForeground = acceleratorSelectionFg;
}
public static void setAcceleratorForeground(Color acceleratorFg) {
acceleratorForeground = acceleratorFg;
}
public static void paintArrowIcon(Graphics g, MenuItemLayoutHelper lh,
MenuItemLayoutHelper.LayoutResult lr,
Color foreground) {
@@ -1120,6 +1120,9 @@ class GTKFileChooserUI extends SynthFileChooserUI {
if (showFileIcons) {
setIcon(getFileChooser().getIcon((File)value));
}
putClientProperty("html.disable", getFileChooser().getClientProperty("html.disable"));
return this;
}
}
@@ -1137,6 +1140,9 @@ class GTKFileChooserUI extends SynthFileChooserUI {
} else {
setText(getFileChooser().getName((File)value) + "/");
}
putClientProperty("html.disable", getFileChooser().getClientProperty("html.disable"));
return this;
}
}
@@ -716,11 +716,10 @@ public class BasicMenuItemUI extends MenuItemUI
private void paintAccText(Graphics g, MenuItemLayoutHelper lh,
MenuItemLayoutHelper.LayoutResult lr) {
SwingUtilities3.setDisabledForeground(disabledForeground);
SwingUtilities3.setAcceleratorSelectionForeground(
acceleratorSelectionForeground);
SwingUtilities3.setAcceleratorForeground(acceleratorForeground);
SwingUtilities3.paintAccText(g, lh, lr);
SwingUtilities3.paintAccText(g, lh, lr,
disabledForeground,
acceleratorSelectionForeground,
acceleratorForeground);
}
private void paintText(Graphics g, MenuItemLayoutHelper lh,
@@ -84,7 +84,9 @@ public final class WindowsCheckBoxMenuItemUI extends BasicCheckBoxMenuItemUI {
int defaultTextIconGap) {
if (WindowsMenuItemUI.isVistaPainting()) {
WindowsMenuItemUI.paintMenuItem(accessor, g, c, checkIcon,
arrowIcon, background, foreground, defaultTextIconGap,
arrowIcon, background, foreground,
disabledForeground, acceleratorSelectionForeground,
acceleratorForeground, defaultTextIconGap,
menuItem, getPropertyPrefix());
return;
}
@@ -67,9 +67,6 @@ public final class WindowsMenuItemUI extends BasicMenuItemUI {
* The instance of {@code PropertyChangeListener}.
*/
private PropertyChangeListener changeListener;
private static Color disabledForeground;
private static Color acceleratorSelectionForeground;
private static Color acceleratorForeground;
final WindowsMenuItemUIAccessor accessor =
new WindowsMenuItemUIAccessor() {
@@ -167,36 +164,6 @@ public final class WindowsMenuItemUI extends BasicMenuItemUI {
changeListener = null;
}
private static void applyInsets(Rectangle rect, Insets insets) {
SwingUtilities3.applyInsets(rect, insets);
}
private static void paintCheckIcon(Graphics g, MenuItemLayoutHelper lh,
MenuItemLayoutHelper.LayoutResult lr,
Color holdc, Color foreground) {
SwingUtilities3.paintCheckIcon(g, lh, lr, holdc, foreground);
}
private static void paintIcon(Graphics g, MenuItemLayoutHelper lh,
MenuItemLayoutHelper.LayoutResult lr, Color holdc) {
SwingUtilities3.paintIcon(g, lh, lr, holdc);
}
private static void paintAccText(Graphics g, MenuItemLayoutHelper lh,
MenuItemLayoutHelper.LayoutResult lr) {
SwingUtilities3.setDisabledForeground(disabledForeground);
SwingUtilities3.setAcceleratorSelectionForeground(
acceleratorSelectionForeground);
SwingUtilities3.setAcceleratorForeground(acceleratorForeground);
SwingUtilities3.paintAccText(g, lh, lr);
}
private static void paintArrowIcon(Graphics g, MenuItemLayoutHelper lh,
MenuItemLayoutHelper.LayoutResult lr,
Color foreground) {
SwingUtilities3.paintArrowIcon(g, lh, lr, foreground);
}
protected void paintMenuItem(Graphics g, JComponent c,
Icon checkIcon, Icon arrowIcon,
Color background, Color foreground,
@@ -204,7 +171,8 @@ public final class WindowsMenuItemUI extends BasicMenuItemUI {
if (WindowsMenuItemUI.isVistaPainting()) {
WindowsMenuItemUI.paintMenuItem(accessor, g, c, checkIcon,
arrowIcon, background, foreground,
defaultTextIconGap, menuItem,
disabledForeground, acceleratorSelectionForeground,
acceleratorForeground, defaultTextIconGap, menuItem,
getPropertyPrefix());
return;
}
@@ -215,6 +183,9 @@ public final class WindowsMenuItemUI extends BasicMenuItemUI {
static void paintMenuItem(WindowsMenuItemUIAccessor accessor, Graphics g,
JComponent c, Icon checkIcon, Icon arrowIcon,
Color background, Color foreground,
Color disabledForeground,
Color acceleratorSelectionForeground,
Color acceleratorForeground,
int defaultTextIconGap, JMenuItem menuItem, String prefix) {
// Save original graphics font and color
Font holdf = g.getFont();
@@ -224,7 +195,7 @@ public final class WindowsMenuItemUI extends BasicMenuItemUI {
g.setFont(mi.getFont());
Rectangle viewRect = new Rectangle(0, 0, mi.getWidth(), mi.getHeight());
applyInsets(viewRect, mi.getInsets());
SwingUtilities3.applyInsets(viewRect, mi.getInsets());
String acceleratorDelimiter =
UIManager.getString("MenuItem.acceleratorDelimiter");
@@ -242,8 +213,8 @@ public final class WindowsMenuItemUI extends BasicMenuItemUI {
MenuItemLayoutHelper.LayoutResult lr = lh.layoutMenuItem();
paintBackground(accessor, g, mi, background);
paintCheckIcon(g, lh, lr, holdc, foreground);
paintIcon(g, lh, lr, holdc);
SwingUtilities3.paintCheckIcon(g, lh, lr, holdc, foreground);
SwingUtilities3.paintIcon(g, lh, lr, holdc);
if (lh.getCheckIcon() != null && lh.useCheckAndArrow()) {
Rectangle rect = lr.getTextRect();
@@ -267,8 +238,10 @@ public final class WindowsMenuItemUI extends BasicMenuItemUI {
rect.x += lh.getAfterCheckIconGap();
lr.setAccRect(rect);
}
paintAccText(g, lh, lr);
paintArrowIcon(g, lh, lr, foreground);
SwingUtilities3.paintAccText(g, lh, lr, disabledForeground,
acceleratorSelectionForeground,
acceleratorForeground);
SwingUtilities3.paintArrowIcon(g, lh, lr, foreground);
// Restore original graphics font and color
g.setColor(holdc);
@@ -140,7 +140,8 @@ public final class WindowsMenuUI extends BasicMenuUI {
if (WindowsMenuItemUI.isVistaPainting()) {
WindowsMenuItemUI.paintMenuItem(accessor, g, c, checkIcon, arrowIcon,
background, foreground,
defaultTextIconGap, menuItem,
disabledForeground, acceleratorSelectionForeground,
acceleratorForeground, defaultTextIconGap, menuItem,
getPropertyPrefix());
return;
}
@@ -84,7 +84,9 @@ public final class WindowsRadioButtonMenuItemUI extends BasicRadioButtonMenuItem
int defaultTextIconGap) {
if (WindowsMenuItemUI.isVistaPainting()) {
WindowsMenuItemUI.paintMenuItem(accessor, g, c, checkIcon,
arrowIcon, background, foreground, defaultTextIconGap,
arrowIcon, background, foreground,
disabledForeground, acceleratorSelectionForeground,
acceleratorForeground, defaultTextIconGap,
menuItem, getPropertyPrefix());
return;
}
@@ -2498,32 +2498,22 @@ jint AwtWindow::_GetScreenImOn(void *param)
jobject self = (jobject)param;
// It's entirely possible that our native resources have been destroyed
// before our java peer - if we're dispose()d, for instance.
// Alert caller w/ IllegalComponentStateException.
if (self == NULL) {
JNU_ThrowByName(env, "java/awt/IllegalComponentStateException",
"Peer null in JNI");
return 0;
}
PDATA pData = JNI_GET_PDATA(self);
if (pData == NULL) {
JNU_ThrowByName(env, "java/awt/IllegalComponentStateException",
"Native resources unavailable");
env->DeleteGlobalRef(self);
return 0;
}
jint result = -1;
AwtWindow* window = NULL;
jint result = 0;
AwtWindow *w = (AwtWindow *)pData;
if (::IsWindow(w->GetHWnd()))
// Our native resources may have been destroyed before the Java peer,
// e.g., if dispose() was called. In that case, return the default screen.
PDATA pData;
JNI_CHECK_PEER_GOTO(self, ret);
window = (AwtWindow *)pData;
if (::IsWindow(window->GetHWnd()))
{
result = (jint)w->GetScreenImOn();
result = (jint)window->GetScreenImOn();
}
ret:
env->DeleteGlobalRef(self);
return result;
return (result != -1) ? result : AwtWin32GraphicsDevice::GetDefaultDeviceIndex();
}
void AwtWindow::_SetFocusableWindow(void *param)
@@ -420,7 +420,8 @@ public class Main {
if (fname != null) {
file = new File(fname);
} else {
file = createTemporaryFile("tmpJar", ".jar");
tmpFile = createTemporaryFile("tmpJar", ".jar");
file = tmpFile;
try (InputStream in = new FileInputStream(FileDescriptor.in);
OutputStream os = Files.newOutputStream(file.toPath())) {
in.transferTo(os);
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -256,6 +256,16 @@ bool needRestartLauncher(AppLauncher& appLauncher, CfgFile& cfgFile) {
}
void enableConsoleCtrlHandler(bool enable) {
if (!SetConsoleCtrlHandler(NULL, enable ? FALSE : TRUE)) {
JP_THROW(SysError(tstrings::any() << "SetConsoleCtrlHandler(NULL, "
<< (enable ? "FALSE" : "TRUE")
<< ") failed",
SetConsoleCtrlHandler));
}
}
void launchApp() {
// [RT-31061] otherwise UI can be left in back of other windows.
::AllowSetForegroundWindow(ASFW_ANY);
@@ -310,6 +320,19 @@ void launchApp() {
exec.arg(arg);
});
exec.afterProcessCreated([&](HANDLE pid) {
//
// Ignore Ctrl+C in the current process.
// This will prevent child process termination without allowing
// it to handle Ctrl+C events.
//
// Disable the default Ctrl+C handler *after* the child process
// has been created as it is inheritable and we want the child
// process to have the default handler.
//
enableConsoleCtrlHandler(false);
});
DWORD exitCode = RunExecutorWithMsgLoop::apply(exec);
exit(exitCode);
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -161,6 +161,10 @@ UniqueHandle Executor::startProcess(UniqueHandle* threadHandle) const {
}
}
if (afterProcessCreatedCallback) {
afterProcessCreatedCallback(processInfo.hProcess);
}
// Return process handle.
return UniqueHandle(processInfo.hProcess);
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,8 @@
#ifndef EXECUTOR_H
#define EXECUTOR_H
#include <functional>
#include "tstrings.h"
#include "UniqueHandle.h"
@@ -97,6 +99,14 @@ public:
*/
int execAndWaitForExit() const;
/**
* Call provided function after the process hass been created.
*/
Executor& afterProcessCreated(const std::function<void(HANDLE)>& v) {
afterProcessCreatedCallback = v;
return *this;
}
private:
UniqueHandle startProcess(UniqueHandle* threadHandle=0) const;
@@ -106,6 +116,7 @@ private:
HANDLE jobHandle;
tstring_array argsArray;
std::wstring appPath;
std::function<void(HANDLE)> afterProcessCreatedCallback;
};
#endif // #ifndef EXECUTOR_H
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -195,7 +195,7 @@ static int get_jvmticks(ticks *pticks) {
uint64_t userTicks;
uint64_t systemTicks;
if (read_ticks("/proc/self/stat", &userTicks, &systemTicks) < 0) {
if (read_ticks("/proc/self/stat", &userTicks, &systemTicks) != 2) {
return -1;
}
@@ -22,7 +22,6 @@
*/
#include "jvm.h"
#include "unittest.hpp"
#include "runtime/arguments.hpp"
#include "runtime/flags/jvmFlag.hpp"
#include "utilities/align.hpp"
@@ -30,6 +29,8 @@
#include <errno.h>
#include "unittest.hpp"
class ArgumentsTest : public ::testing::Test {
public:
static intx parse_xss_inner_annotated(const char* str, jint expected_err, const char* file, int line_number);
@@ -57,7 +58,7 @@ public:
TEST_F(ArgumentsTest, atojulong) {
char ullong_max[32];
int ret = jio_snprintf(ullong_max, sizeof(ullong_max), JULONG_FORMAT, ULLONG_MAX);
int ret = jio_snprintf(ullong_max, sizeof(ullong_max), "%llu", ULLONG_MAX);
ASSERT_NE(-1, ret);
julong value;
+2
View File
@@ -79,6 +79,8 @@ requires.properties= \
vm.rtm.cpu \
vm.rtm.compiler \
vm.cds \
vm.cds.default.archive.available \
vm.cds.nocoops.archive.available \
vm.cds.custom.loaders \
vm.cds.supports.aot.class.linking \
vm.cds.supports.aot.code.caching \
@@ -0,0 +1,131 @@
/*
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package compiler.vectorapi;
import jdk.incubator.vector.FloatVector;
import jdk.incubator.vector.VectorOperators;
import jdk.incubator.vector.VectorSpecies;
/*
* @test
* @bug 8367333
* @requires vm.compiler2.enabled
* @modules jdk.incubator.vector
* @library /test/lib
*
* @run main/othervm -Xbatch -XX:-TieredCompilation
* -XX:+UnlockDiagnosticVMOptions -XX:+StressIncrementalInlining
* -XX:CompileCommand=quiet
* -XX:CompileCommand=compileonly,compiler.vectorapi.TestVectorMathLib::test*
* compiler.vectorapi.TestVectorMathLib
*/
public class TestVectorMathLib {
private static final VectorSpecies SPECIES = FloatVector.SPECIES_PREFERRED;
static FloatVector testTAN(FloatVector fv) {
return fv.lanewise(VectorOperators.TAN);
}
static FloatVector testTANH(FloatVector fv) {
return fv.lanewise(VectorOperators.TANH);
}
static FloatVector testSIN(FloatVector fv) {
return fv.lanewise(VectorOperators.SIN);
}
static FloatVector testSINH(FloatVector fv) {
return fv.lanewise(VectorOperators.SINH);
}
static FloatVector testCOS(FloatVector fv) {
return fv.lanewise(VectorOperators.COS);
}
static FloatVector testCOSH(FloatVector fv) {
return fv.lanewise(VectorOperators.COSH);
}
static FloatVector testASIN(FloatVector fv) {
return fv.lanewise(VectorOperators.ASIN);
}
static FloatVector testACOS(FloatVector fv) {
return fv.lanewise(VectorOperators.ACOS);
}
static FloatVector testATAN(FloatVector fv) {
return fv.lanewise(VectorOperators.ATAN);
}
static FloatVector testATAN2(FloatVector fv) {
return fv.lanewise(VectorOperators.ATAN2, fv);
}
static FloatVector testCBRT(FloatVector fv) {
return fv.lanewise(VectorOperators.CBRT);
}
static FloatVector testLOG(FloatVector fv) {
return fv.lanewise(VectorOperators.LOG);
}
static FloatVector testLOG10(FloatVector fv) {
return fv.lanewise(VectorOperators.LOG10);
}
static FloatVector testLOG1P(FloatVector fv) {
return fv.lanewise(VectorOperators.LOG1P);
}
static FloatVector testPOW(FloatVector fv) {
return fv.lanewise(VectorOperators.POW, fv);
}
static FloatVector testEXP(FloatVector fv) {
return fv.lanewise(VectorOperators.EXP);
}
static FloatVector testEXPM1(FloatVector fv) {
return fv.lanewise(VectorOperators.EXPM1);
}
static FloatVector testHYPOT(FloatVector fv) {
return fv.lanewise(VectorOperators.HYPOT, fv);
}
public static void main(String[] args) {
FloatVector z = FloatVector.zero(SPECIES);
for (int i = 0; i < 20_000; i++) {
z.neg(); // unary
z.add(z); // binary
testTAN(z);
testTANH(z);
testSIN(z);
testSINH(z);
testCOS(z);
testCOSH(z);
testASIN(z);
testACOS(z);
testATAN(z);
testATAN2(z);
testCBRT(z);
testLOG(z);
testLOG10(z);
testLOG1P(z);
testPOW(z);
testEXP(z);
testEXPM1(z);
testHYPOT(z);
}
System.out.println("TEST PASSED");
}
}
@@ -0,0 +1,181 @@
/*
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test id=G1
* @summary Run tests with G1
* @library /test/lib
* @build jdk.test.lib.Platform
* @requires os.family == "linux"
* @requires vm.gc.G1
* @run driver TestTransparentHugePagesHeap G1
*/
/*
* @test id=Parallel
* @summary Run tests with Parallel
* @library /test/lib
* @build jdk.test.lib.Platform
* @requires os.family == "linux"
* @requires vm.gc.Parallel
* @run driver TestTransparentHugePagesHeap Parallel
*/
/*
* @test id=Serial
* @summary Run tests with Serial
* @library /test/lib
* @build jdk.test.lib.Platform
* @requires os.family == "linux"
* @requires vm.gc.Serial
* @run driver TestTransparentHugePagesHeap Serial
*/
import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.Scanner;
import jdk.test.lib.os.linux.HugePageConfiguration;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.process.ProcessTools;
import jdk.test.lib.Platform;
import jtreg.SkippedException;
// We verify that the heap can be backed by THP by looking at the
// THPeligible field for the heap section in /proc/self/smaps. This
// field indicates if a mapping can use THP.
// THP mode 'always': this field is 1 whenever huge pages can be used
// THP mode 'madvise': this field is 1 if the mapping has been madvised
// as MADV_HUGEPAGE. In the JVM that should happen when the flag
// -XX:+UseTransparentHugePages is specified.
//
// Note: we don't verify if the heap is backed by huge pages because we
// can't know if the underlying system have any available.
public class TestTransparentHugePagesHeap {
public static void main(String args[]) throws Exception {
// To be able to detect large page use (esp. THP) somewhat reliably, we
// need at least kernel 3.8 to get the "VmFlags" tag in smaps.
// (Note: its still good we started the VM at least since this serves as a nice
// test for all manners of large page options).
if (Platform.getOsVersionMajor() < 3 ||
(Platform.getOsVersionMajor() == 3 && Platform.getOsVersionMinor() < 8)) {
throw new SkippedException("Kernel older than 3.8 - skipping this test.");
}
final HugePageConfiguration hugePageConfiguration = HugePageConfiguration.readFromOS();
if (!hugePageConfiguration.supportsTHP()) {
throw new SkippedException("THP is turned off");
}
OutputAnalyzer oa = ProcessTools.executeTestJava("-XX:+Use" + args[0] + "GC", "-Xmx128m", "-Xms128m", "-Xlog:pagesize:thp-%p.log", "-XX:+UseTransparentHugePages", VerifyTHPEnabledForHeap.class.getName());
oa.shouldHaveExitValue(0);
}
class VerifyTHPEnabledForHeap {
public static void main(String args[]) throws Exception {
// Extract the heap start from pagesize logging
BigInteger heapStart = extractHeapStartFromLog();
Path smaps = makeSmapsCopy();
final Pattern addressRangePattern = Pattern.compile("([0-9a-f]*?)-([0-9a-f]*?) .*");
final Pattern thpEligiblePattern = Pattern.compile("THPeligible:\\s+(\\d)\\s*");
Scanner smapsFile = new Scanner(smaps);
while (smapsFile.hasNextLine()) {
Matcher addressRangeMatcher = addressRangePattern.matcher(smapsFile.nextLine());
if (!addressRangeMatcher.matches()) {
continue;
}
// Found an address range line in the smaps file
BigInteger addressStart = new BigInteger(addressRangeMatcher.group(1), 16);
BigInteger addressEnd = new BigInteger(addressRangeMatcher.group(2), 16);
// Linux sometimes merges adjacent VMAs so we can't search for a range that
// exactly matches the heap range. Instead we look for the first range that
// contains the start of the heap and verify that that range is THP eligible.
if (addressStart.compareTo(heapStart) > 0 || heapStart.compareTo(addressEnd) >= 0) {
continue;
}
// Found a range that contains the start of the heap, verify that it is THP eligible.
while (smapsFile.hasNextLine()) {
Matcher m = thpEligiblePattern.matcher(smapsFile.nextLine());
if (!m.matches()) {
continue;
}
// Found the THPeligible line
if (m.group(1).equals("1")) {
// Success - THPeligible is 1, heap can be backed by huge pages
return;
}
throw new RuntimeException("The address range 0x" + addressStart.toString(16)
+ "-0x" + addressEnd.toString(16)
+ " that contains the heap start" + heapStart
+ " is not THPeligible");
}
throw new RuntimeException("Couldn't find THPeligible in the smaps file");
}
throw new RuntimeException("Could not find an address range containing the heap start " + heapStart + " in the smaps file");
}
private static BigInteger extractHeapStartFromLog() throws Exception {
// [0.041s][info][pagesize] Heap: min=128M max=128M base=0x0000ffff5c600000 size=128M page_size=2M
final Pattern heapAddress = Pattern.compile(".* Heap: .*base=0x([0-9A-Fa-f]*).*");
Scanner logFile = new Scanner(Paths.get("thp-" + ProcessHandle.current().pid() + ".log"));
while (logFile.hasNextLine()) {
String line = logFile.nextLine();
Matcher m = heapAddress.matcher(line);
if (m.matches()) {
return new BigInteger(m.group(1), 16);
}
}
throw new RuntimeException("Failed to find heap start");
}
private static Path makeSmapsCopy() throws Exception {
Path src = Paths.get("/proc/self/smaps");
Path dest = Paths.get("smaps-copy-" + ProcessHandle.current().pid() + ".txt");
Files.copy(src, dest, StandardCopyOption.REPLACE_EXISTING);
return dest;
}
}
}
@@ -23,6 +23,14 @@
package gc.z;
/*
* @test id=Normal
* @requires vm.gc.Z & vm.debug
* @summary Test ZGC graceful failure when a commit fails
* @library / /test/lib
* @run driver gc.z.TestCommitFailure
*/
/*
* @test id=ZFakeNUMA
* @requires vm.gc.Z & vm.debug
@@ -108,7 +108,16 @@ public class TestUncommit {
throw new Exception("Uncommitted too fast");
}
// In typical conditions (system not over-provisioned or slow),
// uncommitting is expected to complete within 3 * ZUncommitDelay after
// the last commit. To accommodate less ideal environments, only
// durations exceeding 5 * ZUncommitDelay are flagged as errors.
if (actualDelay > delay * 3) {
log(" *** Uncommit slower than expected. ***");
}
if (actualDelay > delay * 5) {
throw new Exception("Uncommitted too slow");
}
@@ -28,6 +28,7 @@
* @requires vm.bits == 64 & !vm.graal.enabled & vm.debug == true
* @requires vm.flagless
* @requires vm.cds
* @requires vm.cds.default.archive.available
* @requires (os.family != "windows") & (os.family != "aix")
* @library /test/lib
* @modules java.base/jdk.internal.misc
@@ -30,6 +30,7 @@
* jdk.internal.jvmstat/sun.jvmstat.monitor
* @run driver CreateCoredumpOnCrash
* @requires vm.flagless
* @requires !vm.asan
*/
import jdk.test.lib.process.ProcessTools;
@@ -26,6 +26,7 @@
* @test id=nocoops_nocoh
* @summary Test Loading of default archives in all configurations
* @requires vm.cds
* @requires vm.cds.default.archive.available
* @requires vm.cds.write.archived.java.heap
* @requires vm.bits == 64
* @library /test/lib
@@ -38,6 +39,7 @@
* @test id=nocoops_coh
* @summary Test Loading of default archives in all configurations (requires --enable-cds-archive-coh)
* @requires vm.cds
* @requires vm.cds.default.archive.available
* @requires vm.cds.write.archived.java.heap
* @requires vm.bits == 64
* @library /test/lib
@@ -50,6 +52,7 @@
* @test id=coops_nocoh
* @summary Test Loading of default archives in all configurations
* @requires vm.cds
* @requires vm.cds.default.archive.available
* @requires vm.cds.write.archived.java.heap
* @requires vm.bits == 64
* @library /test/lib
@@ -62,6 +65,7 @@
* @test id=coops_coh
* @summary Test Loading of default archives in all configurations (requires --enable-cds-archive-coh)
* @requires vm.cds
* @requires vm.cds.default.archive.available
* @requires vm.cds.write.archived.java.heap
* @requires vm.bits == 64
* @library /test/lib
@@ -90,8 +94,8 @@ public class TestDefaultArchiveLoading {
"server", archiveName(archiveSuffix));
}
private static boolean isCOHArchiveAvailable(char coops, char coh,
String archiveSuffix) throws Exception {
private static boolean isArchiveAvailable(char coops, char coh,
String archiveSuffix) throws Exception {
Path archive= archivePath(archiveSuffix);
return Files.exists(archive);
}
@@ -109,12 +113,16 @@ public class TestDefaultArchiveLoading {
case "nocoops_nocoh":
coh = coops = '-';
archiveSuffix = "_nocoops";
if (!isArchiveAvailable(coops, coh, archiveSuffix)) {
throw new SkippedException("Skipping test due to " +
archivePath(archiveSuffix).toString() + " not available");
}
break;
case "nocoops_coh":
coops = '-';
coh = '+';
archiveSuffix = "_nocoops_coh";
if (!isCOHArchiveAvailable(coops, coh, archiveSuffix)) {
if (!isArchiveAvailable(coops, coh, archiveSuffix)) {
throw new SkippedException("Skipping test due to " +
archivePath(archiveSuffix).toString() + " not available");
}
@@ -123,11 +131,15 @@ public class TestDefaultArchiveLoading {
coops = '+';
coh = '-';
archiveSuffix = "";
if (!isArchiveAvailable(coops, coh, archiveSuffix)) {
throw new SkippedException("Skipping test due to " +
archivePath(archiveSuffix).toString() + " not available");
}
break;
case "coops_coh":
coh = coops = '+';
archiveSuffix = "_coh";
if (!isCOHArchiveAvailable(coops, coh, archiveSuffix)) {
if (!isArchiveAvailable(coops, coh, archiveSuffix)) {
throw new SkippedException("Skipping test due to " +
archivePath(archiveSuffix).toString() + " not available");
}
@@ -67,6 +67,8 @@ public class ArchiveRelocationTest {
String logArg = "-Xlog:cds=debug,cds+reloc=debug,aot+heap";
String unlockArg = "-XX:+UnlockDiagnosticVMOptions";
String nmtArg = "-XX:NativeMemoryTracking=detail";
String relocMsg1 = "ArchiveRelocationMode == 1: always map archive(s) at an alternative address";
String relocMsg2 = "Try to map archive(s) at an alternative address";
OutputAnalyzer out = TestCommon.dump(appJar,
TestCommon.list(mainClass),
@@ -76,8 +78,10 @@ public class ArchiveRelocationTest {
TestCommon.run("-cp", appJar, unlockArg, runRelocArg, logArg, mainClass)
.assertNormalExit(output -> {
if (run_reloc) {
output.shouldContain("ArchiveRelocationMode == 1: always map archive(s) at an alternative address")
.shouldContain("Try to map archive(s) at an alternative address");
if (!output.contains(relocMsg1) && !output.contains(relocMsg2)) {
throw new RuntimeException("Relocation messages \"" + relocMsg1 +
"\" and \"" + relocMsg2 + "\" are missing from the output");
}
} else {
output.shouldContain("ArchiveRelocationMode: 0");
}
@@ -120,9 +120,9 @@ public class LotsOfSyntheticClasses {
OutputAnalyzer output = TestCommon.createArchive(
APP_JAR.toString(),
listAppClasses(),
MAIN_CLASS_NAME,
// Verification for lots of classes slows down the test.
"-XX:+IgnoreUnrecognizedVMOptions",
"-XX:+UnlockDiagnosticVMOptions",
"-XX:-VerifyDependencies",
"-XX:-VerifyBeforeExit"
);
@@ -134,6 +134,7 @@ public class LotsOfSyntheticClasses {
TestCommon.run(
// Verification for lots of classes slows down the test.
"-XX:+IgnoreUnrecognizedVMOptions",
"-XX:+UnlockDiagnosticVMOptions",
"-XX:-VerifyDependencies",
"-XX:-VerifyBeforeExit",
"-cp", APP_JAR.toString(),
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -427,8 +427,6 @@ public class TestCommon extends CDSTestUtils {
cmd.add(opts.appJar);
}
CDSTestUtils.addVerifyArchivedFields(cmd);
for (String s : opts.suffix) cmd.add(s);
if (RUN_WITH_JFR) {
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
* @summary test dynamic dump meanwhile output loaded class list
* @bug 8279009 8275084
* @requires vm.cds
* @requires vm.cds.default.archive.available
* @requires vm.cds.custom.loaders
* @requires vm.flagless
* @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
* @summary Transforming an interface of an archived lambda proxy class should not
* crash the VM. The lambda proxy class should be regenerated during runtime.
* @requires vm.cds
* @requires vm.cds.default.archive.available
* @requires vm.jvmti
* @requires vm.flagless
* @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds/test-classes
@@ -98,11 +98,8 @@ public class ExcludedClasses {
@Override
public void checkExecution(OutputAnalyzer out, RunMode runMode) {
if (runMode == RunMode.TRAINING) {
out.shouldMatch("aot,resolve.*reverted field.*TestApp.Foo => TestApp.Foo.ShouldBeExcluded.f:I");
} else if (runMode == RunMode.ASSEMBLY) {
if (runMode == RunMode.ASSEMBLY) {
out.shouldNotMatch("aot,resolve.*archived field.*TestApp.Foo => TestApp.Foo.ShouldBeExcluded.f:I");
out.shouldMatch("aot,resolve.*archived method.*TestApp.Foo java/lang/Integer.intValue:[(][)]I => java/lang/Integer");
} else if (runMode == RunMode.PRODUCTION) {
out.shouldContain("check_verification_constraint: TestApp$Foo$Taz: TestApp$Foo$ShouldBeExcludedChild must be subclass of TestApp$Foo$ShouldBeExcluded");
out.shouldContain("jdk.jfr.Event source: jrt:/jdk.jfr");
@@ -257,6 +257,16 @@ public class AOTFlags {
out.shouldContain("AOTCache creation is complete: hello.aot");
out.shouldMatch("Picked up JAVA_TOOL_OPTIONS:.* -Dmy.prop=My' 'string' '-Xshare:off' 'here");
out.shouldHaveExitValue(0);
// Training run with -XX:+PrintTieredEvents (see JDK-8362530).
printTestCase("Training run with -XX:+PrintTieredEvents");
pb = ProcessTools.createLimitedTestJavaProcessBuilder(
"-XX:AOTMode=record",
"-XX:+PrintTieredEvents",
"-XX:AOTConfiguration=" + aotConfigFile,
"-cp", appJar, helloClass);
out = CDSTestUtils.executeAndLog(pb, "train-with-tiered-events");
out.shouldHaveExitValue(0);
}
static void negativeTests() throws Exception {
@@ -27,6 +27,7 @@
* @summary Test -XX:+AutoCreateSharedArchive on a copied JDK without default shared archive
* @bug 8261455
* @requires vm.cds
* @requires vm.cds.default.archive.available
* @requires vm.flagless
* @comment This test doesn't work on Windows because it depends on symlinks
* @requires os.family != "windows"
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -55,6 +55,7 @@
/**
* @test id=custom-cl-zgc
* @requires vm.cds.custom.loaders
* @requires vm.cds.nocoops.archive.available
* @requires vm.gc.Z
* @summary Test dumptime_table entries are removed with zgc eager class unloading
* @bug 8274935
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, Google and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -47,12 +47,36 @@ extern "C" {
#endif
// JVMTI_ERROR_WRONG_PHASE guard
static jrawMonitorID event_mon = NULL;
static int is_vm_dead = 0;
void lock(jvmtiEnv *jvmti, JNIEnv *jni) {
jvmtiError err = (*jvmti)->RawMonitorEnter(jvmti, event_mon);
if (err != JVMTI_ERROR_NONE) {
JNI_ENV_PTR(jni)->FatalError(JNI_ENV_ARGS2(jni, "RawMonitorEnter failed"));
}
}
void unlock(jvmtiEnv *jvmti, JNIEnv *jni) {
jvmtiError err = (*jvmti)->RawMonitorExit(jvmti, event_mon);
if (err != JVMTI_ERROR_NONE) {
JNI_ENV_PTR(jni)->FatalError(JNI_ENV_ARGS2(jni, "RawMonitorExit failed"));
}
}
extern JNIEXPORT void JNICALL VMObjectAlloc(jvmtiEnv *jvmti,
JNIEnv* jni,
jthread thread,
jobject object,
jclass klass,
jlong size) {
lock(jvmti, jni);
if (is_vm_dead) {
unlock(jvmti, jni);
return;
}
char *signature = NULL;
jvmtiError error = (*jvmti)->GetClassSignature(jvmti, klass, &signature, NULL);
@@ -78,25 +102,40 @@ extern JNIEXPORT void JNICALL VMObjectAlloc(jvmtiEnv *jvmti,
JNI_ENV_ARGS2(jni, "Failed during the CallObjectMethod call"));
}
}
unlock(jvmti, jni);
}
extern JNIEXPORT void JNICALL OnVMInit(jvmtiEnv *jvmti, JNIEnv *jni, jthread thread) {
(*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_VM_OBJECT_ALLOC, NULL);
}
extern JNIEXPORT void JNICALL OnVMDeath(jvmtiEnv *jvmti, JNIEnv *jni) {
lock(jvmti, jni);
is_vm_dead = 1;
unlock(jvmti, jni);
}
extern JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options,
void *reserved) {
jvmtiEnv *jvmti;
jvmtiEventCallbacks callbacks;
jvmtiCapabilities caps;
jvmtiError err;
if ((*jvm)->GetEnv(jvm, (void **) (&jvmti), JVMTI_VERSION) != JNI_OK) {
return JNI_ERR;
}
err = (*jvmti)->CreateRawMonitor(jvmti, "Event Monitor", &event_mon);
if (err != JVMTI_ERROR_NONE) {
printf("CreateRawMonitor failed: %d\n", err);
return JNI_ERR;
}
memset(&callbacks, 0, sizeof(callbacks));
callbacks.VMObjectAlloc = &VMObjectAlloc;
callbacks.VMInit = &OnVMInit;
callbacks.VMDeath = &OnVMDeath;
memset(&caps, 0, sizeof(caps));
caps.can_generate_vm_object_alloc_events = 1;
@@ -104,6 +143,7 @@ extern JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options,
(*jvmti)->SetEventCallbacks(jvmti, &callbacks, sizeof(jvmtiEventCallbacks));
(*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_VM_INIT, NULL);
(*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_VM_DEATH, NULL);
return 0;
}
@@ -58,9 +58,12 @@ public class Stresser implements ExecutionController {
private String name;
private long maxIterations;
private long iterations;
// In nanoseconds
private long startTime;
private long finishTime;
private long currentTime;
private long stressTime;
private PrintStream defaultOutput = System.out;
/*
@@ -179,15 +182,15 @@ public class Stresser implements ExecutionController {
*/
public void printExecutionInfo(PrintStream out) {
println(out, "Completed iterations: " + iterations);
println(out, "Execution time: " + (currentTime - startTime) + " seconds");
println(out, "Execution time: " + (currentTime - startTime) / 1_000_000_000.0 + " seconds");
if (!finished) {
println(out, "Execution is not finished yet");
} else if (forceFinish) {
println(out, "Execution was forced to finish");
} else if (maxIterations != 0 && iterations >= maxIterations) {
println(out, "Execution finished because number of iterations was exceeded: " + iterations + " >= " + maxIterations);
} else if (finishTime != 0 && currentTime >= finishTime) {
println(out, "Execution finished because time was exceeded: " + (currentTime - startTime) + " >= " + (finishTime - startTime));
} else if (stressTime != 0 && (currentTime - startTime) >= stressTime) {
println(out, "Execution finished because time has exceeded stress time: " + stressTime / 1_000_000_000 + " seconds");
}
}
@@ -208,13 +211,8 @@ public class Stresser implements ExecutionController {
public void start(long stdIterations) {
maxIterations = stdIterations * options.getIterationsFactor();
iterations = 0;
long stressTime = options.getTime();
startTime = System.currentTimeMillis();
if (stressTime == 0) {
finishTime = 0;
} else {
finishTime = startTime + stressTime * 1000;
}
stressTime = options.getTime() * 1_000_000_000;
startTime = System.nanoTime();
finished = false;
forceFinish = false;
if (options.isDebugEnabled()) {
@@ -232,7 +230,7 @@ public class Stresser implements ExecutionController {
* finally {} block.
*/
public void finish() {
currentTime = System.currentTimeMillis();
currentTime = System.nanoTime();
finished = true;
if (options.isDebugEnabled()) {
printExecutionInfo(defaultOutput);
@@ -255,10 +253,12 @@ public class Stresser implements ExecutionController {
*/
public boolean iteration() {
++iterations;
boolean result = continueExecution();
// Call print at the end to show the most up-to-date info.
if (options.isDebugDetailed()) {
printExecutionInfo(defaultOutput);
}
return continueExecution();
return result;
}
/**
@@ -267,14 +267,14 @@ public class Stresser implements ExecutionController {
* @return true if execution needs to continue
*/
public boolean continueExecution() {
currentTime = System.currentTimeMillis();
currentTime = System.nanoTime();
if (startTime == 0) {
throw new TestBug("Stresser is not started.");
}
return !forceFinish
&& !finished
&& (maxIterations == 0 || iterations < maxIterations)
&& (finishTime == 0 || currentTime < finishTime);
&& (stressTime == 0 || (currentTime - startTime) < stressTime);
}
/**
@@ -309,7 +309,7 @@ public class Stresser implements ExecutionController {
* @return time
*/
public long getExecutionTime() {
return System.currentTimeMillis() - startTime;
return (System.nanoTime() - startTime) / 1_000_000;
}
/**
@@ -318,11 +318,11 @@ public class Stresser implements ExecutionController {
* @return time
*/
public long getTimeLeft() {
long current = System.currentTimeMillis();
if (current >= finishTime) {
long elapsedTime = System.nanoTime() - startTime;
if (elapsedTime >= stressTime) {
return 0;
} else {
return finishTime - current;
return (stressTime - elapsedTime) / 1_000_000;
}
}
+1 -3
View File
@@ -119,6 +119,7 @@ java/awt/Focus/FocusOwnerFrameOnClick/FocusOwnerFrameOnClick.java 8081489 generi
java/awt/Focus/IconifiedFrameFocusChangeTest/IconifiedFrameFocusChangeTest.java 6849364 generic-all
java/awt/Focus/AutoRequestFocusTest/AutoRequestFocusToFrontTest.java 6848406 generic-all
java/awt/Focus/AutoRequestFocusTest/AutoRequestFocusSetVisibleTest.java 6848407 generic-all
java/awt/Frame/BogusFocusableWindowState/BogusFocusableWindowState.java 8361521 linux-all
java/awt/Frame/MaximizedToMaximized/MaximizedToMaximized.java 8340374 macosx-all
java/awt/Frame/MaximizedUndecorated/MaximizedUndecorated.java 8022302 generic-all
java/awt/Frame/RestoreToOppositeScreen/RestoreToOppositeScreen.java 8286840 linux-all
@@ -455,7 +456,6 @@ java/awt/Focus/TranserFocusToWindow/TranserFocusToWindow.java 6848810 macosx-all
java/awt/FileDialog/ModalFocus/FileDialogModalFocusTest.java 8194751 linux-all
java/awt/image/VolatileImage/BitmaskVolatileImage.java 8133102 linux-all
java/awt/SplashScreen/MultiResolutionSplash/unix/UnixMultiResolutionSplashTest.java 8203004 linux-all
java/awt/ScrollPane/ScrollPositionTest.java 8040070 linux-all
java/awt/ScrollPane/ScrollPaneEventType.java 8296516 macosx-all
java/awt/Robot/AcceptExtraMouseButtons/AcceptExtraMouseButtons.java 7107528 linux-all,macosx-all
java/awt/Mouse/MouseDragEvent/MouseDraggedTest.java 8080676 linux-all
@@ -803,7 +803,6 @@ java/awt/event/MouseEvent/SpuriousExitEnter/SpuriousExitEnter_2.java 7131438,802
java/awt/Modal/WsDisabledStyle/CloseBlocker/CloseBlocker.java 7187741 linux-all,macosx-all
java/awt/xembed/server/TestXEmbedServerJava.java 8001150,8004031 generic-all
java/awt/Modal/PrintDialogsTest/PrintDialogsTest.java 8068378 generic-all
java/awt/event/MouseEvent/AltGraphModifierTest/AltGraphModifierTest.java 8162380 generic-all
java/awt/image/VolatileImage/VolatileImageConfigurationTest.java 8171069 macosx-all,linux-all
java/awt/Modal/InvisibleParentTest/InvisibleParentTest.java 8172245 linux-all
java/awt/Frame/FrameStateTest/FrameStateTest.java 8203920 macosx-all,linux-all
@@ -825,7 +824,6 @@ java/awt/Focus/FrameMinimizeTest/FrameMinimizeTest.java 8016266 linux-x64
java/awt/Frame/SizeMinimizedTest.java 8305915 linux-x64
java/awt/PopupMenu/PopupHangTest.java 8340022 windows-all
java/awt/Focus/MinimizeNonfocusableWindowTest.java 8024487 windows-all
java/awt/Focus/InactiveFocusRace.java 8023263 linux-all
java/awt/List/HandlingKeyEventIfMousePressedTest.java 6848358 macosx-all,windows-all
java/awt/List/ListScrollbarCursorTest.java 8066410 generic-all
java/awt/Checkbox/CheckboxBoxSizeTest.java 8340870 windows-all
@@ -28,7 +28,7 @@
*
* @comment Don't allow -Xcomp or -Xint as they impact memory useage and number of iterations.
* Require compressed oops because not doing so increases memory usage.
* @requires (vm.compMode == "Xmixed") & vm.opt.final.UseCompressedOops
* @requires (vm.compMode == "Xmixed") & (vm.bits == 32 | vm.opt.final.UseCompressedOops)
* @run build TestScaffold VMConnection TargetListener TargetAdapter
* @run compile -g ThreadMemoryLeakTest.java
* @comment run with -Xmx7m so any leak will quickly produce OOME
+41 -16
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,6 +30,7 @@
*/
import java.awt.Button;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.KeyboardFocusManager;
@@ -48,19 +49,27 @@ public class InactiveFocusRace {
Button activeButton, inactiveButton1, inactiveButton2;
Semaphore sema;
final static int TIMEOUT = 10000;
private static Robot robot;
public static void main(String[] args) throws Exception {
try {
robot = new Robot();
InactiveFocusRace test = new InactiveFocusRace();
test.init();
EventQueue.invokeAndWait(() -> {
test.init();
});
robot.waitForIdle();
robot.delay(1000);
test.start();
} finally {
if (activeFrame != null) {
activeFrame.dispose();
}
if (inactiveFrame != null) {
inactiveFrame.dispose();
}
EventQueue.invokeAndWait(() -> {
if (activeFrame != null) {
activeFrame.dispose();
}
if (inactiveFrame != null) {
inactiveFrame.dispose();
}
});
}
}
@@ -91,24 +100,40 @@ public class InactiveFocusRace {
sema.raise();
}
});
inactiveFrame.addWindowListener(new WindowAdapter() {
public void windowActivated(WindowEvent e) {
System.err.println("inactive Window activated");
sema.raise();
}
});
activeFrame.addWindowListener(new WindowAdapter() {
public void windowActivated(WindowEvent e) {
System.err.println("Window activated");
sema.raise();
}
});
inactiveFrame.setVisible(true);
}
public void start() {
Robot robot = null;
try {
robot = new Robot();
} catch (Exception e) {
throw new RuntimeException("Unable to create robot");
}
inactiveFrame.setVisible(true);
activeFrame.setVisible(true);
// Wait for inactive frame to become active
try {
sema.doWait(TIMEOUT);
} catch (InterruptedException ie) {
throw new RuntimeException("Wait was interrupted");
}
if (!sema.getState()) {
throw new RuntimeException("Frame doesn't become active on show");
}
sema.setState(false);
try {
EventQueue.invokeAndWait(() -> activeFrame.setVisible(true));
} catch (Exception e) {
throw new RuntimeException("Interrupted active frame rendering");
}
// Wait for active frame to become active
try {
@@ -0,0 +1,50 @@
/*
* Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.awt.Window;
/**
* @test
* @bug 8346952
* @summary Verifies no exception occurs when triggering updateCG()
* for an ownerless window.
* @key headful
*/
public final class BogusFocusableWindowState {
public static void main(String[] args) {
Window frame = new Window(null) {
@Override
public boolean getFocusableWindowState() {
removeNotify();
return true;
}
};
try {
frame.pack();
frame.setVisible(true);
} finally {
frame.dispose();
}
}
}
@@ -27,7 +27,7 @@ import java.util.concurrent.TimeUnit;
/**
* @test
* @bug 8235638 8235739 8285094
* @bug 8235638 8235739 8285094 8346952
* @key headful
*/
public final class GetGraphicsStressTest {
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,6 @@ import java.awt.Frame;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.InvocationTargetException;
/*
* @test
@@ -54,16 +53,17 @@ public class SetEchoCharTest4 extends Frame implements ActionListener {
Make sure the actual text matches what you typed in for each field.
Press Pass if everything's ok, otherwise Fail
""";
""";
public SetEchoCharTest4() {
super("SetEchoCharTest4");
setLayout(new FlowLayout());
tf1.setEchoChar('*');
tf2.setEchoChar('$');
tf3.setEchoChar('#');
addStuff();
b.addActionListener(this);
setSize (200,200);
setSize (300, 150);
}
private void addStuff() {
@@ -78,7 +78,6 @@ public class SetEchoCharTest4 extends Frame implements ActionListener {
PassFailJFrame.log("TextField2 = " + tf2.getText());
PassFailJFrame.log("TextField3 = " + tf3.getText());
PassFailJFrame.log("--------------");
setVisible(false);
remove(tf1);
remove(tf2);
remove(tf3);
@@ -86,16 +85,14 @@ public class SetEchoCharTest4 extends Frame implements ActionListener {
addStuff();
}
public static void main(String[] args) throws InterruptedException,
InvocationTargetException {
public static void main(String[] args) throws Exception {
PassFailJFrame.builder()
.title("Set Echo Character Test")
.testUI(SetEchoCharTest4::new)
.instructions(INSTRUCTIONS)
.rows((int) INSTRUCTIONS.lines().count() + 1)
.columns(40)
.logArea()
.build()
.awaitAndCheck();
.title("Set Echo Character Test")
.testUI(SetEchoCharTest4::new)
.instructions(INSTRUCTIONS)
.columns(40)
.logArea()
.build()
.awaitAndCheck();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,55 +22,52 @@
*/
/*
* test
* @test
* @bug 6282388
* @summary Tests that AWT use correct toolkit to be wrapped into HeadlessToolkit
* @author artem.ananiev@sun.com: area=awt.headless
* @run shell WrappedToolkitTest.sh
* @summary Tests that AWT uses correct toolkit wrapped into HeadlessToolkit
* @modules java.desktop/sun.awt:open
* @library /test/lib
* @run main/othervm -Djava.awt.headless=true TestWrapped
*/
import java.awt.*;
import java.awt.Toolkit;
import java.lang.Class;
import java.lang.reflect.Field;
import java.lang.reflect.*;
import jdk.test.lib.Platform;
import sun.awt.*;
public final class TestWrapped {
public class TestWrapped
{
public static void main(String[] args)
{
try
{
if (args.length != 1) {
System.err.println("No correct toolkit class name is specified, test is not run");
System.exit(0);
private static final String HEADLESS_TOOLKIT = "sun.awt.HeadlessToolkit";
private static final String MACOSX_TOOLKIT = "sun.lwawt.macosx.LWCToolkit";
private static final String UNIX_TOOLKIT = "sun.awt.X11.XToolkit";
private static final String WINDOWS_TOOLKIT = "sun.awt.windows.WToolkit";
public static void main(String[] args) throws Exception {
String expectedToolkitClassName;
if (Platform.isWindows()) {
expectedToolkitClassName = WINDOWS_TOOLKIT;
} else if (Platform.isOSX()) {
expectedToolkitClassName = MACOSX_TOOLKIT;
} else {
expectedToolkitClassName = UNIX_TOOLKIT;
}
String correctToolkitClassName = args[0];
Toolkit tk = Toolkit.getDefaultToolkit();
Class tkClass = tk.getClass();
if (!tkClass.getName().equals("sun.awt.HeadlessToolkit"))
{
System.err.println(tkClass.getName());
System.err.println("Error: default toolkit is not an instance of HeadlessToolkit");
System.exit(-1);
Class<?> tkClass = tk.getClass();
if (!tkClass.getName().equals(HEADLESS_TOOLKIT)) {
System.err.println("Expected: " + HEADLESS_TOOLKIT);
System.err.println("Actual: " + tkClass.getName());
throw new RuntimeException("Wrong default toolkit");
}
Field f = tkClass.getDeclaredField("tk");
f.setAccessible(true);
Class wrappedClass = f.get(tk).getClass();
if (!wrappedClass.getName().equals(correctToolkitClassName)) {
System.err.println(wrappedClass.getName());
System.err.println("Error: wrapped toolkit is not an instance of " + correctToolkitClassName);
System.exit(-1);
Class<?> wrappedClass = f.get(tk).getClass();
if (!wrappedClass.getName().equals(expectedToolkitClassName)) {
System.err.println("Expected: " + expectedToolkitClassName);
System.err.println("Actual: " + wrappedClass.getName());
throw new RuntimeException("Wrong wrapped toolkit");
}
}
catch (Exception z)
{
z.printStackTrace(System.err);
System.exit(-1);
}
System.exit(0);
}
}
@@ -1,221 +0,0 @@
#!/bin/ksh -p
#
# Copyright (c) 2012, 2020, 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 6282388 8030640
# @summary Tests that AWT use correct toolkit to be wrapped into HeadlessToolkit
# @author artem.ananiev@sun.com: area=awt.headless
# compile TestWrapped.java
# @run shell WrappedToolkitTest.sh
# Beginning of subroutines:
status=1
#Call this from anywhere to fail the test with an error message
# usage: fail "reason why the test failed"
fail()
{ echo "The test failed :-("
echo "$*" 1>&2
echo "exit status was $status"
exit $status
} #end of fail()
#Call this from anywhere to pass the test with a message
# usage: pass "reason why the test passed if applicable"
pass()
{ echo "The test passed!!!"
echo "$*" 1>&2
exit 0
} #end of pass()
# end of subroutines
# The beginning of the script proper
# Checking for proper OS
OS=`uname -s`
case "$OS" in
AIX | CYGWIN* | Darwin | Linux )
FILESEP="/"
;;
Windows* )
FILESEP="\\"
;;
# catch all other OSs
* )
echo "Unrecognized system! $OS"
fail "Unrecognized system! $OS"
;;
esac
# check that some executable or other file you need is available, abort if not
# note that the name of the executable is in the fail string as well.
# this is how to check for presence of the compiler, etc.
#RESOURCE=`whence SomeProgramOrFileNeeded`
#if [ "${RESOURCE}" = "" ] ;
# then fail "Need SomeProgramOrFileNeeded to perform the test" ;
#fi
# Want this test to run standalone as well as in the harness, so do the
# following to copy the test's directory into the harness's scratch directory
# and set all appropriate variables:
if [ -z "${TESTJAVA}" ] ; then
# TESTJAVA is not set, so the test is running stand-alone.
# TESTJAVA holds the path to the root directory of the build of the JDK
# to be tested. That is, any java files run explicitly in this shell
# should use TESTJAVA in the path to the java interpreter.
# So, we'll set this to the JDK spec'd on the command line. If none
# is given on the command line, tell the user that and use a cheesy
# default.
# THIS IS THE JDK BEING TESTED.
if [ -n "$1" ] ;
then TESTJAVA=$1
else fail "no JDK specified on command line!"
fi
TESTSRC=.
TESTCLASSES=.
STANDALONE=1;
fi
echo "JDK under test is: $TESTJAVA"
#if in test harness, then copy the entire directory that the test is in over
# to the scratch directory. This catches any support files needed by the test.
if [ -z "${STANDALONE}" ] ;
then cp ${TESTSRC}/* .
fi
case "$OS" in
Windows* | CYGWIN* )
${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} \
--add-exports java.desktop/sun.awt=ALL-UNNAMED \
--add-exports java.desktop/sun.awt.windows=ALL-UNNAMED ${CP} \
*.java
status=$?
if [ ! $status -eq "0" ]; then
fail "Compilation failed";
fi
;;
AIX | Linux )
${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} \
--add-exports java.desktop/sun.awt=ALL-UNNAMED \
--add-exports java.desktop/sun.awt.X11=ALL-UNNAMED ${CP} \
*.java
status=$?
if [ ! $status -eq "0" ]; then
fail "Compilation failed";
fi
;;
Darwin)
${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} \
--add-exports java.desktop/sun.awt=ALL-UNNAMED \
--add-exports java.desktop/sun.lwawt.macosx=ALL-UNNAMED ${CP} \
*.java
status=$?
if [ ! $status -eq "0" ]; then
fail "Compilation failed";
fi
;;
esac
#Just before executing anything, make sure it has executable permission!
chmod 777 ./*
############### YOUR TEST CODE HERE!!!!!!! #############
case "$OS" in
Windows* | CYGWIN* )
${TESTJAVA}/bin/java ${TESTVMOPTS} -Djava.awt.headless=true \
--add-opens java.desktop/sun.awt=ALL-UNNAMED \
--add-opens java.desktop/sun.awt.windows=ALL-UNNAMED ${CP} \
TestWrapped sun.awt.windows.WToolkit
status=$?
if [ ! $status -eq "0" ]; then
fail "Test FAILED: toolkit wrapped into HeadlessToolkit is not an instance of sun.awt.windows.WToolkit";
fi
${TESTJAVA}/bin/java ${TESTVMOPTS} -Djava.awt.headless=true \
--add-opens java.desktop/sun.awt=ALL-UNNAMED \
--add-opens java.desktop/sun.awt.windows=ALL-UNNAMED ${CP} \
-Dawt.toolkit=sun.awt.windows.WToolkit \
TestWrapped sun.awt.windows.WToolkit
status=$?
if [ ! $status -eq "0" ]; then
fail "Test FAILED: toolkit wrapped into HeadlessToolkit is not an instance of sun.awt.windows.WToolkit";
fi
;;
AIX | Linux )
${TESTJAVA}/bin/java ${TESTVMOPTS} -Djava.awt.headless=true \
--add-opens java.desktop/sun.awt=ALL-UNNAMED \
--add-opens java.desktop/sun.awt.X11=ALL-UNNAMED ${CP} \
-Dawt.toolkit=sun.awt.X11.XToolkit \
TestWrapped sun.awt.X11.XToolkit
status=$?
if [ ! $status -eq "0" ]; then
fail "Test FAILED: toolkit wrapped into HeadlessToolkit is not an instance of sun.awt.xawt.XToolkit";
fi
AWT_TOOLKIT=XToolkit ${TESTJAVA}/bin/java ${TESTVMOPTS} \
--add-opens java.desktop/sun.awt=ALL-UNNAMED \
--add-opens java.desktop/sun.awt.X11=ALL-UNNAMED ${CP} \
-Djava.awt.headless=true \
TestWrapped sun.awt.X11.XToolkit
status=$?
if [ ! $status -eq "0" ]; then
fail "Test FAILED: toolkit wrapped into HeadlessToolkit is not an instance of sun.awt.xawt.XToolkit";
fi
;;
Darwin)
${TESTJAVA}/bin/java ${TESTVMOPTS} -Djava.awt.headless=true \
--add-opens java.desktop/sun.awt=ALL-UNNAMED \
--add-opens java.desktop/sun.lwawt.macosx=ALL-UNNAMED ${CP} \
TestWrapped sun.lwawt.macosx.LWCToolkit
status=$?
if [ ! $status -eq "0" ]; then
fail "Test FAILED: toolkit wrapped into HeadlessToolkit is not an instance of sun.lwawt.macosx.LWCToolkit";
fi
${TESTJAVA}/bin/java ${TESTVMOPTS} -Djava.awt.headless=true \
--add-opens java.desktop/sun.awt=ALL-UNNAMED \
--add-opens java.desktop/sun.lwawt.macosx=ALL-UNNAMED ${CP} \
-Dawt.toolkit=sun.lwawt.macosx.LWCToolkit \
TestWrapped sun.lwawt.macosx.LWCToolkit
status=$?
if [ ! $status -eq "0" ]; then
fail "Test FAILED: toolkit wrapped into HeadlessToolkit is not an instance of sun.lwawt.macosx.LWCToolkit";
fi
;;
esac
pass "All the tests are PASSED";
#For additional examples of how to write platform independent KSH scripts,
# see the jtreg file itself. It is a KSH script for both Solaris and Win32
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,51 +22,57 @@
*/
/*
@test
@bug 8041928 8158616
@requires (os.family != "mac")
@summary Confirm that the Alt-Gr Modifier bit is set correctly.
@run main/manual AltGraphModifierTest
* @test
* @bug 8041928 8158616
* @requires (os.family != "mac")
* @summary Confirm that the Alt-Gr Modifier bit is set correctly.
* @library /java/awt/regtesthelpers
* @build PassFailJFrame
* @run main/manual AltGraphModifierTest
*/
import java.awt.Button;
import java.awt.Dialog;
import java.awt.Frame;
import java.awt.Panel;
import java.awt.TextArea;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class AltGraphModifierTest {
private static void init() throws Exception {
String[] instructions
= {
"This test is for verifying Alt-Gr modifier of an event.",
"Linux :-",
"1. Please check if Alt-Gr key is present on keyboard.",
"2. If present, press the Alt-Gr key and perform",
" mouse click on the TestWindow.",
"3. Navigate to System Settings-> Keyboard-> Shortcuts->",
" Typing.",
"4. Select an option for the Alternative Characters Key",
" For example. Right Alt",
"5. Close the settings and navigate to test",
"6. Press Right Alt Key & perform mouse click on the",
" TestWindow",
"7. Test will exit by itself with appropriate result.",
" ",
};
Sysout.createDialog();
Sysout.printInstructions(instructions);
public static void main(String[] args) throws Exception {
String INSTRUCTIONS = """
This test is for verifying Alt-Gr modifier of an event.
Please check if Alt-Gr key is present on keyboard.
If not present, press Pass.
On Windows:
Press Alt-Gr or Right Alt key and simultaneously
perform mouse click on the "TestWindow".
On Linux:
Navigate to
System Settings-> Keyboard-> Special Character Entry
Select "Right Alt" option for the "Alternate Characters Key"
Close the settings and navigate to test
Press Right Alt Key & simultaneously
perform mouse click on the "TestWindow".
If the system does not have such setting, press Pass.
After the test, change the Setting of "Alternate Characters Key"
back to "Layout default".
If "Alt-Gr Modifier bit is set" message is displayed in logArea,
press Pass else press Fail.
""";
PassFailJFrame.builder()
.instructions(INSTRUCTIONS)
.columns(35)
.testUI(AltGraphModifierTest::initTestWindow)
.logArea()
.build()
.awaitAndCheck();
}
static Frame mainFrame;
public static void initTestWindow() {
mainFrame = new Frame();
public static Frame initTestWindow() {
Frame mainFrame = new Frame();
mainFrame.setTitle("TestWindow");
mainFrame.setBounds(700, 10, 300, 300);
mainFrame.addMouseListener(new MouseAdapter() {
@@ -74,186 +80,12 @@ public class AltGraphModifierTest {
public void mousePressed(MouseEvent e) {
int ex = e.getModifiersEx();
if ((ex & InputEvent.ALT_GRAPH_DOWN_MASK) == 0) {
AltGraphModifierTest.fail("Alt-Gr Modifier bit is not set.");
PassFailJFrame.log("Alt-Gr Modifier bit is not set.");
} else {
AltGraphModifierTest.pass();
PassFailJFrame.log("Alt-Gr Modifier bit is set");
}
}
});
mainFrame.setVisible(true);
}
public static void dispose() {
Sysout.dispose();
mainFrame.dispose();
}
/**
* ***************************************************
* Standard Test Machinery Section DO NOT modify anything in this section --
* it's a standard chunk of code which has all of the synchronisation
* necessary for the test harness. By keeping it the same in all tests, it
* is easier to read and understand someone else's test, as well as insuring
* that all tests behave correctly with the test harness. There is a section
* following this for test-defined classes
* ****************************************************
*/
private static boolean theTestPassed = false;
private static boolean testGeneratedInterrupt = false;
private static String failureMessage = "";
private static Thread mainThread = null;
final private static int sleepTime = 300000;
public static void main(String args[]) throws Exception {
mainThread = Thread.currentThread();
try {
init();
initTestWindow();
} catch (Exception e) {
e.printStackTrace();
}
try {
mainThread.sleep(sleepTime);
} catch (InterruptedException e) {
dispose();
if (testGeneratedInterrupt && !theTestPassed) {
throw new Exception(failureMessage);
}
}
if (!testGeneratedInterrupt) {
dispose();
throw new RuntimeException("Timed out after " + sleepTime / 1000
+ " seconds");
}
}
public static synchronized void pass() {
theTestPassed = true;
testGeneratedInterrupt = true;
mainThread.interrupt();
}
public static synchronized void fail(String whyFailed) {
theTestPassed = false;
testGeneratedInterrupt = true;
failureMessage = whyFailed;
mainThread.interrupt();
}
}
// *********** End Standard Test Machinery Section **********
/**
* **************************************************
* Standard Test Machinery DO NOT modify anything below -- it's a standard chunk
* of code whose purpose is to make user interaction uniform, and thereby make
* it simpler to read and understand someone else's test.
* **************************************************
*/
/**
* This is part of the standard test machinery. It creates a dialog (with the
* instructions), and is the interface for sending text messages to the user. To
* print the instructions, send an array of strings to Sysout.createDialog
* WithInstructions method. Put one line of instructions per array entry. To
* display a message for the tester to see, simply call Sysout.println with the
* string to be displayed. This mimics System.out.println but works within the
* test harness as well as standalone.
*/
class Sysout {
private static TestDialog dialog;
private static Frame frame;
public static void createDialog() {
frame = new Frame();
dialog = new TestDialog(frame, "Instructions");
String[] defInstr = {"Instructions will appear here. ", ""};
dialog.printInstructions(defInstr);
dialog.show();
println("Any messages for the tester will display here.");
}
public static void printInstructions(String[] instructions) {
dialog.printInstructions(instructions);
}
public static void println(String messageIn) {
dialog.displayMessage(messageIn);
}
public static void dispose() {
dialog.dispose();
frame.dispose();
}
}
/**
* This is part of the standard test machinery. It provides a place for the test
* instructions to be displayed, and a place for interactive messages to the
* user to be displayed. To have the test instructions displayed, see Sysout. To
* have a message to the user be displayed, see Sysout. Do not call anything in
* this dialog directly.
*/
class TestDialog extends Dialog implements ActionListener {
TextArea instructionsText;
TextArea messageText;
int maxStringLength = 80;
Panel buttonP;
Button failB;
// DO NOT call this directly, go through Sysout
public TestDialog(Frame frame, String name) {
super(frame, name);
int scrollBoth = TextArea.SCROLLBARS_BOTH;
instructionsText = new TextArea("", 15, maxStringLength, scrollBoth);
add("North", instructionsText);
messageText = new TextArea("", 5, maxStringLength, scrollBoth);
add("Center", messageText);
buttonP = new Panel();
failB = new Button("Fail");
failB.setActionCommand("fail");
failB.addActionListener(this);
buttonP.add("Center", failB);
add("South", buttonP);
pack();
setVisible(true);
}
// DO NOT call this directly, go through Sysout
public void printInstructions(String[] instructions) {
instructionsText.setText("");
String printStr, remainingStr;
for (int i = 0; i < instructions.length; i++) {
remainingStr = instructions[i];
while (remainingStr.length() > 0) {
if (remainingStr.length() >= maxStringLength) {
int posOfSpace = remainingStr.
lastIndexOf(' ', maxStringLength - 1);
if (posOfSpace <= 0) {
posOfSpace = maxStringLength - 1;
}
printStr = remainingStr.substring(0, posOfSpace + 1);
remainingStr = remainingStr.substring(posOfSpace + 1);
}
else {
printStr = remainingStr;
remainingStr = "";
}
instructionsText.append(printStr + "\n");
}
}
}
public void displayMessage(String messageIn) {
messageText.append(messageIn + "\n");
}
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand() == "fail") {
AltGraphModifierTest.fail("User Clicked Fail");
}
return mainFrame;
}
}
@@ -72,6 +72,7 @@ import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.Timer;
import javax.swing.border.Border;
import javax.swing.event.HyperlinkListener;
import javax.swing.text.JTextComponent;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.StyleSheet;
@@ -98,7 +99,8 @@ import static javax.swing.SwingUtilities.isEventDispatchThread;
* tester. The instructions can be either plain text or HTML. If the
* text of the instructions starts with {@code "<html>"}, the
* instructions are displayed as HTML, as supported by Swing, which
* provides richer formatting options.
* provides richer formatting options. To handle navigating links in the
* instructions, call {@link Builder#hyperlinkListener} to install a listener.
* <p>
* The instructions are displayed in a text component with word-wrapping
* so that there's no horizontal scroll bar. If the text doesn't fit, a
@@ -592,6 +594,7 @@ public final class PassFailJFrame {
frame.add(createInstructionUIPanel(instructions,
testTimeOut,
rows, columns,
null,
false,
false, 0),
BorderLayout.CENTER);
@@ -610,6 +613,7 @@ public final class PassFailJFrame {
createInstructionUIPanel(builder.instructions,
builder.testTimeOut,
builder.rows, builder.columns,
builder.hyperlinkListener,
builder.screenCapture,
builder.addLogArea,
builder.logAreaRows);
@@ -631,6 +635,7 @@ public final class PassFailJFrame {
private static JComponent createInstructionUIPanel(String instructions,
long testTimeOut,
int rows, int columns,
HyperlinkListener hyperlinkListener,
boolean enableScreenCapture,
boolean addLogArea,
int logAreaRows) {
@@ -643,6 +648,9 @@ public final class PassFailJFrame {
JTextComponent text = instructions.startsWith("<html>")
? configureHTML(instructions, rows, columns)
: configurePlainText(instructions, rows, columns);
if (hyperlinkListener != null && text instanceof JEditorPane ep) {
ep.addHyperlinkListener(hyperlinkListener);
}
text.setEditable(false);
text.setBorder(createTextBorder());
text.setCaretPosition(0);
@@ -716,7 +724,7 @@ public final class PassFailJFrame {
// Reduce the list default margins
styles.addRule("ol, ul { margin-left-ltr: 30; margin-left-rtl: 30 }");
// Make the size of code (and other elements) the same as other text
styles.addRule("code, kbd, samp, pre { font-size: inherit }");
styles.addRule("code, kbd, samp, pre { font-size: inherit; background: #DDD; }");
return text;
}
@@ -1398,6 +1406,7 @@ public final class PassFailJFrame {
private int rows;
private int columns;
private boolean screenCapture;
private HyperlinkListener hyperlinkListener;
private boolean addLogArea;
private int logAreaRows = 10;
@@ -1478,6 +1487,18 @@ public final class PassFailJFrame {
return this;
}
/**
* Sets a {@link HyperlinkListener} for navigating links inside
* the instructions pane.
*
* @param hyperlinkListener the listener
* @return this builder
*/
public Builder hyperlinkListener(HyperlinkListener hyperlinkListener) {
this.hyperlinkListener = hyperlinkListener;
return this;
}
public Builder screenCapture() {
this.screenCapture = true;
return this;
+17 -18
View File
@@ -28,7 +28,7 @@
* 6464154 6523983 6206031 4960438 6631352 6631966 6850957 6850958
* 4947220 7018606 7034570 4244896 5049299 8003488 8054494 8058464
* 8067796 8224905 8263729 8265173 8272600 8231297 8282219 8285517
* 8352533
* 8352533 8368192
* @key intermittent
* @summary Basic tests for Process and Environment Variable code
* @modules java.base/java.lang:open
@@ -777,30 +777,29 @@ public class Basic {
return Pattern.compile(regex).matcher(str).find();
}
private static String matchAndExtract(String str, String regex) {
Matcher matcher = Pattern.compile(regex).matcher(str);
if (matcher.find()) {
return matcher.group();
} else {
return "";
}
// Return the string with the matching regex removed
private static String matchAndRemove(String str, String regex) {
return Pattern.compile(regex)
.matcher(str)
.replaceAll("");
}
/* Only used for Mac OS X --
* Mac OS X (may) add the variable __CF_USER_TEXT_ENCODING to an empty
* environment. The environment variable JAVA_MAIN_CLASS_<pid> may also
* be set in Mac OS X.
* Remove them both from the list of env variables
* Mac OS X (may) add the variables: __CF_USER_TEXT_ENCODING, JAVA_MAIN_CLASS_<pid>,
* and TMPDIR.
* Remove them from the list of env variables
*/
private static String removeMacExpectedVars(String vars) {
// Check for __CF_USER_TEXT_ENCODING
String cleanedVars = vars.replace("__CF_USER_TEXT_ENCODING="
+cfUserTextEncoding+",","");
String cleanedVars = matchAndRemove(vars,
"__CF_USER_TEXT_ENCODING=" + cfUserTextEncoding + ",");
// Check for JAVA_MAIN_CLASS_<pid>
String javaMainClassStr
= matchAndExtract(cleanedVars,
"JAVA_MAIN_CLASS_\\d+=Basic.JavaChild,");
return cleanedVars.replace(javaMainClassStr,"");
cleanedVars = matchAndRemove(cleanedVars,
"JAVA_MAIN_CLASS_\\d+=Basic.JavaChild,");
// Check and remove TMPDIR
cleanedVars = matchAndRemove(cleanedVars,
"TMPDIR=[^,]*,");
return cleanedVars;
}
/* Only used for AIX --
@@ -53,8 +53,8 @@ public class GetStackTraceALotWhenBlocking {
int iterations;
int value = Integer.parseInt(args[0]);
if (Platform.isOSX() && Platform.isX64()) {
// reduced iterations on macosx-x64
if (Platform.isOSX()) {
// reduced iterations on macosx
iterations = Math.max(value / 4, 1);
} else {
iterations = value;
@@ -56,8 +56,8 @@ public class GetStackTraceALotWhenPinned {
int iterations;
int value = Integer.parseInt(args[0]);
if (Platform.isOSX() && Platform.isX64()) {
// reduced iterations on macosx-x64
if (Platform.isOSX()) {
// reduced iterations on macosx
iterations = Math.max(value / 4, 1);
} else {
iterations = value;
@@ -49,8 +49,8 @@ public class ParkALot {
public static void main(String[] args) throws Exception {
int iterations;
int value = Integer.parseInt(args[0]);
if (Platform.isOSX() && Platform.isX64()) {
// reduced iterations on macosx-x64
if (Platform.isOSX()) {
// reduced iterations on macosx
iterations = Math.max(value / 4, 1);
} else {
iterations = value;
@@ -0,0 +1,161 @@
/*
* Copyright Amazon.com Inc. 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 8277444
*
* @library /test/lib
* @compile SimpleIdentityTransformer.java
* @run shell MakeJAR.sh retransformAgent
* @run main/othervm -javaagent:retransformAgent.jar RetransformBigClassTest
*/
import jdk.test.lib.compiler.InMemoryJavaCompiler;
/*
* JvmtiClassFileReconstituter::copy_bytecodes restores bytecodes rewritten
* by the linking process. It is used by RetransformClasses.
* JDK-8277444 is a data race between copy_bytecodes and the linking process.
* This test puts the linking process in one thread and the retransforming process
* in another thread. The test uses Class.forName("BigClass", false, classLoader)
* which does not link the class. When the class is used, the linking process starts.
* In another thread retransforming of the class is happening.
* We generate a class with big methods. A number of methods and their size are
* chosen to make the linking and retransforming processes run concurrently.
* We delay the retransforming process to follow the linking process.
* If there is no synchronization between the processes, a data race will happen.
*/
public class RetransformBigClassTest extends AInstrumentationTestCase {
private static final Object LOCK = new Object();
private static final int COUNTER_INC_COUNT = 2000; // A number of 'c+=1;' statements in methods of a class.
private static final int MIN_LINK_TIME_MS = 60; // Large enough so the linking and retransforming processes run in parallel.
private static final int RETRANSFORM_CLASSES_DELAY_MS = 37; // We manage to create a data race when a delay is in the range 0.52x - 0.62x of MIN_LINK_TIME_MS.
private static Class<?> bigClass;
private static byte[] bigClassBytecode;
private Thread retransformThread;
RetransformBigClassTest() {
super("RetransformBigClassTest");
}
public static void main(String[] args) throws Throwable {
new RetransformBigClassTest().runTest();
}
protected final void doRunTest() throws Throwable {
ClassLoader classLoader = new ClassLoader() {
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
if (name.equals("BigClass")) {
return defineClass(name, bigClassBytecode, 0, bigClassBytecode.length);
}
return super.findClass(name);
}
};
synchronized (LOCK) {
bigClass = Class.forName("BigClass", false, classLoader);
LOCK.notify();
}
// Make a use of the BigClass
assertTrue(bigClass.getConstructor().newInstance().hashCode() != 0);
retransformThread.join();
}
private byte[] createClassBytecode(String className, int methodCount) throws Exception {
String methodBody = "";
for (int j = 0; j < COUNTER_INC_COUNT; j++) {
methodBody += "c+=1;";
}
String classSrc = "public class " + className + " { int c;";
for (int i = 0; i < methodCount; i++) {
classSrc += "\npublic void m" + i + "(){";
classSrc += methodBody;
classSrc += "\n}";
}
classSrc += "\n}";
return InMemoryJavaCompiler.compile(className, classSrc);
}
// We need a number of methods such that the linking time is greater than
// or equal to MIN_LINK_TIME_MS.
// We create a class having 5 methods and trigger the linking process.
// We measure the time taken and use it to calculate the needed number.
private int findMethodCount() throws Exception {
int methodCount = 5;
final String className = "BigClass" + methodCount;
final byte[] bytecode = createClassBytecode(className, methodCount);
ClassLoader classLoader = new ClassLoader() {
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
if (name.equals(className)) {
return defineClass(name, bytecode, 0, bytecode.length);
}
return super.findClass(name);
}
};
var bigClass = Class.forName(className, false, classLoader);
long startTime = System.nanoTime();
assertTrue(bigClass.getConstructor().newInstance().hashCode() != 0);
double linkTimeMs = (System.nanoTime() - startTime) / 1000000.0;
System.out.println("Link time for a class with " + methodCount + " methods each having " + COUNTER_INC_COUNT + " counter increments: " + Math.round(linkTimeMs));
if (linkTimeMs < MIN_LINK_TIME_MS) {
methodCount = (int)Math.round((MIN_LINK_TIME_MS * methodCount) / linkTimeMs);
}
System.out.println("The number of methods to exceed " + MIN_LINK_TIME_MS + " ms linking time: " + methodCount);
return methodCount;
}
@Override
protected void setUp() throws Exception {
super.setUp();
bigClassBytecode = createClassBytecode("BigClass", findMethodCount());
fInst.addTransformer(new SimpleIdentityTransformer());
retransformThread = new Thread(() -> {
try {
synchronized (LOCK) {
while (bigClass == null) {
System.out.println("[retransformThread]: Waiting for bigClass");
LOCK.wait();
}
}
Thread.sleep(RETRANSFORM_CLASSES_DELAY_MS);
fInst.retransformClasses(bigClass);
} catch (Exception e) {
e.printStackTrace();
}
});
retransformThread.start();
Thread.sleep(100);
}
}
+10 -18
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -40,7 +40,7 @@ import static java.util.stream.Collectors.toList;
* Two threads are created per client connection. So, it's not
* intended for large numbers of parallel connections.
*/
public class ProxyServer extends Thread implements Closeable {
public final class ProxyServer implements Closeable {
// could use the test library here - Platform.isWindows(),
// but it would force all tests that use ProxyServer to
@@ -97,9 +97,7 @@ public class ProxyServer extends Thread implements Closeable {
this(port, debug, null);
}
public ProxyServer(Integer port,
Boolean debug,
Credentials credentials)
private ProxyServer(Integer port, Boolean debug, Credentials credentials)
throws IOException
{
this.debug = debug;
@@ -108,15 +106,8 @@ public class ProxyServer extends Thread implements Closeable {
listener.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), port));
this.port = ((InetSocketAddress)listener.getLocalAddress()).getPort();
this.credentials = credentials;
setName("ProxyListener");
setDaemon(true);
connections = new CopyOnWriteArrayList<Connection>();
start();
}
public ProxyServer(String s) {
credentials = null;
connections = new CopyOnWriteArrayList<Connection>();
Thread.ofPlatform().name("ProxyListener").daemon().start(this::run);
}
/**
@@ -148,7 +139,7 @@ public class ProxyServer extends Thread implements Closeable {
volatile boolean done;
public void run() {
private void run() {
int id = 0;
try {
while (!done) {
@@ -656,10 +647,11 @@ public class ProxyServer extends Thread implements Closeable {
int port = Integer.parseInt(args[0]);
boolean debug = args.length > 1 && args[1].equals("-debug");
System.out.println("Debugging : " + debug);
ProxyServer ps = new ProxyServer(port, debug);
System.out.println("Proxy server listening on port " + ps.getPort());
while (true) {
Thread.sleep(5000);
try (ProxyServer ps = new ProxyServer(port, debug)) {
System.out.println("Proxy server listening on port " + ps.getPort());
while (true) {
Thread.sleep(5000);
}
}
}
}
@@ -27,11 +27,13 @@
* @summary Test for ExtendedOpenOption.DIRECT flag
* @requires (os.family == "linux" | os.family == "aix")
* @library /test/lib
* @modules java.base/sun.nio.ch:+open java.base/java.io:+open
* @build jdk.test.lib.Platform
* @run main/native DirectIOTest
*/
import java.io.*;
import java.lang.reflect.Field;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.*;
@@ -47,10 +49,25 @@ import com.sun.nio.file.ExtendedOpenOption;
public class DirectIOTest {
private static final int BASE_SIZE = 4096;
private static final int TRIES = 3;
public static int getFD(FileChannel channel) throws Exception {
Field fFdFd = channel.getClass().getDeclaredField("fd");
fFdFd.setAccessible(true);
FileDescriptor fd = (FileDescriptor) fFdFd.get(channel);
Field fFd = FileDescriptor.class.getDeclaredField("fd");
fFd.setAccessible(true);
return fFd.getInt(fd);
}
private static void testWrite(Path p, long blockSize) throws Exception {
try (FileChannel fc = FileChannel.open(p,
StandardOpenOption.READ,
StandardOpenOption.WRITE,
ExtendedOpenOption.DIRECT)) {
int fd = getFD(fc);
private static int testWrite(Path p, long blockSize) throws Exception {
try (FileChannel fc = FileChannel.open(p, StandardOpenOption.WRITE,
ExtendedOpenOption.DIRECT)) {
int bs = (int)blockSize;
int size = Math.max(BASE_SIZE, bs);
int alignment = bs;
@@ -60,22 +77,55 @@ public class DirectIOTest {
for (int j = 0; j < size; j++) {
src.put((byte)0);
}
src.flip();
fc.write(src);
return size;
// If there is AV or other FS tracing software, it may cache the file
// contents on first access, even though we have asked for DIRECT here.
// Do several attempts to make test more resilient.
for (int t = 0; t < TRIES; t++) {
flushFileCache(size, fd);
src.flip();
fc.position(0);
fc.write(src);
if (!isFileInCache(size, fd)) {
return;
}
}
throw new RuntimeException("DirectIO is not working properly with " +
"write. File still exists in cache!");
}
}
private static int testRead(Path p, long blockSize) throws Exception {
try (FileChannel fc = FileChannel.open(p, ExtendedOpenOption.DIRECT)) {
private static void testRead(Path p, long blockSize) throws Exception {
try (FileChannel fc = FileChannel.open(p,
StandardOpenOption.READ,
ExtendedOpenOption.DIRECT)) {
int fd = getFD(fc);
int bs = (int)blockSize;
int size = Math.max(BASE_SIZE, bs);
int alignment = bs;
ByteBuffer dest = ByteBuffer.allocateDirect(size + alignment - 1)
.alignedSlice(alignment);
assert dest.capacity() != 0;
fc.read(dest);
return size;
// If there is AV or other FS tracing software, it may cache the file
// contents on first access, even though we have asked for DIRECT here.
// Do several attempts to make test more resilient.
for (int t = 0; t < TRIES; t++) {
flushFileCache(size, fd);
dest.clear();
fc.position(0);
fc.read(dest);
if (!isFileInCache(size, fd)) {
return;
}
}
throw new RuntimeException("DirectIO is not working properly with " +
"read. File still exists in cache!");
}
}
@@ -84,12 +134,8 @@ public class DirectIOTest {
Paths.get(System.getProperty("test.dir", ".")), "test", null);
}
private static boolean isFileInCache(int size, Path p) {
String path = p.toString();
return isFileInCache0(size, path);
}
private static native boolean isFileInCache0(int size, String path);
private static native boolean flushFileCache(int size, int fd);
private static native boolean isFileInCache(int size, int fd);
public static void main(String[] args) throws Exception {
Path p = createTempFile();
@@ -98,16 +144,8 @@ public class DirectIOTest {
System.loadLibrary("DirectIO");
try {
int size = testWrite(p, blockSize);
if (isFileInCache(size, p)) {
throw new RuntimeException("DirectIO is not working properly with "
+ "write. File still exists in cache!");
}
size = testRead(p, blockSize);
if (isFileInCache(size, p)) {
throw new RuntimeException("DirectIO is not working properly with "
+ "read. File still exists in cache!");
}
testWrite(p, blockSize);
testRead(p, blockSize);
} finally {
Files.delete(p);
}
@@ -45,13 +45,27 @@ static void ThrowException(JNIEnv *env, const char *name, const char *msg) {
/*
* Class: DirectIO
* Method: isFileInCache0
* Signature: (ILjava/lang/String;)Z
* Method: flushFileCache
* Signature: (II;)V
*/
JNIEXPORT jboolean Java_DirectIOTest_isFileInCache0(JNIEnv *env,
JNIEXPORT void Java_DirectIOTest_flushFileCache(JNIEnv *env,
jclass cls,
jint file_size,
jstring file_path) {
jint fd) {
#ifdef __linux__
posix_fadvise(fd, 0, file_size, POSIX_FADV_DONTNEED);
#endif
}
/*
* Class: DirectIO
* Method: isFileInCache
* Signature: (II;)Z
*/
JNIEXPORT jboolean Java_DirectIOTest_isFileInCache(JNIEnv *env,
jclass cls,
jint file_size,
jint fd) {
void *f_mmap;
#ifdef __linux__
unsigned char *f_seg;
@@ -69,17 +83,10 @@ JNIEXPORT jboolean Java_DirectIOTest_isFileInCache0(JNIEnv *env,
size_t index = (file_size + page_size - 1) /page_size;
jboolean result = JNI_FALSE;
const char* path = (*env)->GetStringUTFChars(env, file_path, JNI_FALSE);
int fd = open(path, O_RDWR);
(*env)->ReleaseStringUTFChars(env, file_path, path);
f_mmap = mmap(0, file_size, PROT_NONE, MAP_SHARED, fd, 0);
if (f_mmap == MAP_FAILED) {
close(fd);
ThrowException(env, "java/io/IOException",
"test of whether file exists in cache failed");
"test of whether file exists in cache failed: mmap failed");
}
f_seg = malloc(index);
if (f_seg != NULL) {
@@ -95,9 +102,8 @@ JNIEXPORT jboolean Java_DirectIOTest_isFileInCache0(JNIEnv *env,
free(f_seg);
} else {
ThrowException(env, "java/io/IOException",
"test of whether file exists in cache failed");
"test of whether file exists in cache failed: malloc failed");
}
close(fd);
munmap(f_mmap, file_size);
return result;
}
@@ -1,12 +1,12 @@
#
#
# Amendments up until ISO 4217 AMENDMENT NUMBER 179
# (As of 02 May 2025)
# Amendments up until ISO 4217 AMENDMENT NUMBER 180
# (As of 22 September 2025)
#
# Version
FILEVERSION=3
DATAVERSION=179
DATAVERSION=180
# ISO 4217 currency data
AF AFN 971 2
@@ -44,7 +44,7 @@ BV NOK 578 2
BR BRL 986 2
IO USD 840 2
BN BND 96 2
BG BGN 975 2
BG BGN 975 2 2025-12-31-22-00-00 EUR 978 2
BF XOF 952 0
BI BIF 108 0
KH KHR 116 2
@@ -69,7 +69,7 @@ CR CRC 188 2
CI XOF 952 0
HR EUR 978 2
CU CUP 192 2
CW ANG 532 2 2025-04-01-04-00-00 XCG 532 2
CW XCG 532 2
CY EUR 978 2
CZ CZK 203 2
DK DKK 208 2
@@ -233,7 +233,7 @@ LK LKR 144 2
SD SDG 938 2
SR SRD 968 2
SJ NOK 578 2
SX ANG 532 2 2025-04-01-04-00-00 XCG 532 2
SX XCG 532 2
SZ SZL 748 2
SE SEK 752 2
CH CHF 756 2
@@ -26,7 +26,7 @@
* @bug 4691089 4819436 4942982 5104960 6544471 6627549 7066203 7195759
* 8039317 8074350 8074351 8145952 8187946 8193552 8202026 8204269
* 8208746 8209775 8264792 8274658 8283277 8296239 8321480 8334653
* 8354343 8354344 8356096
* 8354343 8354344 8356096 8368308
* @summary Validate ISO 4217 data for Currency class.
* @modules java.base/java.util:open
* jdk.localedata
@@ -116,7 +116,7 @@ public class ValidateISO4217 {
private static final Set<String> currenciesNotYetDefined = new HashSet<>();
// Codes that are obsolete, do not have related country, extra currency
private static final String otherCodes =
"ADP-AFA-ATS-AYM-AZM-BEF-BGL-BOV-BYB-BYR-CHE-CHW-CLF-COU-CUC-CYP-"
"ADP-AFA-ATS-AYM-AZM-BEF-BGL-BGN-BOV-BYB-BYR-CHE-CHW-CLF-COU-CUC-CYP-"
+ "DEM-EEK-ESP-FIM-FRF-GHC-GRD-GWP-HRK-IEP-ITL-LTL-LUF-LVL-MGF-MRO-MTL-MXV-MZM-NLG-"
+ "PTE-ROL-RUR-SDD-SIT-SLL-SKK-SRG-STD-TMM-TPE-TRL-VEF-UYI-USN-USS-VEB-VED-"
+ "XAD-XAG-XAU-XBA-XBB-XBC-XBD-XDR-XFO-XFU-XPD-XPT-XSU-XTS-XUA-XXX-"
@@ -41,7 +41,7 @@ import javax.swing.filechooser.FileSystemView;
/*
* @test id=system
* @bug 8139228
* @bug 8139228 8358532
* @summary JFileChooser should not render Directory names in HTML format
* @library /java/awt/regtesthelpers
* @build PassFailJFrame
@@ -52,6 +52,7 @@ import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -246,8 +247,10 @@ public class TestIOTopFrame {
r.enable(EVENT_SOCKET_READ).withStackTrace();
r.enable(EVENT_SOCKET_WRITE).withStackTrace();
r.start();
Thread readerThread = Thread.ofPlatform().start(() -> readSocketChannel(ssc));
CountDownLatch latch = new CountDownLatch(1);
Thread readerThread = Thread.ofPlatform().start(() -> readSocketChannel(ssc, latch));
writeSocketChannel(ssc);
latch.countDown();
readerThread.join();
r.stop();
assertTopFrames(r, "readSocket", 6, "readSocketChannel", 2, "writeSocket", 3, "writeSocketChannel", 2);
@@ -255,13 +258,14 @@ public class TestIOTopFrame {
}
}
private static void readSocketChannel(ServerSocketChannel ssc) {
private static void readSocketChannel(ServerSocketChannel ssc, CountDownLatch latch) {
ByteBuffer[] buffers = createBuffers();
try (SocketChannel sc = ssc.accept()) {
sc.read(buffers[0]); // 1
sc.read(buffers); // 2
try (InputStream is = sc.socket().getInputStream()) {
readSocket(is);
latch.await();
}
} catch (Exception ioe) {
throw new RuntimeException(ioe);
@@ -38,12 +38,13 @@ import java.io.FileOutputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import jdk.test.lib.SecurityTools;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
public class VerifyJarEntryName {
@@ -85,7 +86,7 @@ public class VerifyJarEntryName {
*/
@Test
void verifyManifestEntryName() throws Exception {
modifyJarEntryName(ORIGINAL_JAR, MODIFIED_JAR, "MANIFEST.MF");
modifyJarEntryName(ORIGINAL_JAR, MODIFIED_JAR, "META-INF/MANIFEST.MF");
SecurityTools.jarsigner("-verify -verbose " + MODIFIED_JAR)
.shouldContain("This JAR file contains internal " +
"inconsistencies that may result in different " +
@@ -95,6 +96,22 @@ public class VerifyJarEntryName {
.shouldHaveExitValue(0);
}
/*
* Modify a single byte in signature filename in LOC, and
* validate that jarsigner -verify emits a warning message.
*/
@Test
void verifySignatureEntryName() throws Exception {
modifyJarEntryName(ORIGINAL_JAR, MODIFIED_JAR, "META-INF/MYKEY.SF");
SecurityTools.jarsigner("-verify -verbose " + MODIFIED_JAR)
.shouldContain("This JAR file contains internal " +
"inconsistencies that may result in different " +
"contents when reading via JarFile and JarInputStream:")
.shouldContain("- Entry XETA-INF/MYKEY.SF is present when reading " +
"via JarInputStream but missing when reading via JarFile")
.shouldHaveExitValue(0);
}
/*
* Validate that jarsigner -verify on a valid JAR works without
* emitting warnings about internal inconsistencies.
@@ -111,9 +128,14 @@ public class VerifyJarEntryName {
private void modifyJarEntryName(Path origJar, Path modifiedJar,
String entryName) throws Exception {
byte[] jarBytes = Files.readAllBytes(origJar);
var jarString = new String(jarBytes, StandardCharsets.UTF_8);
var pos = jarString.indexOf(entryName);
assertTrue(pos != -1, entryName + " is not present in the JAR");
byte[] entryNameBytes = entryName.getBytes(StandardCharsets.UTF_8);
int pos = 0;
try {
while (!Arrays.equals(jarBytes, pos, pos + entryNameBytes.length,
entryNameBytes, 0, entryNameBytes.length)) pos++;
} catch (ArrayIndexOutOfBoundsException ignore) {
fail(entryName + " is not present in the JAR");
}
jarBytes[pos] = 'X';
Files.write(modifiedJar, jarBytes);
}

Some files were not shown because too many files have changed in this diff Show More