Compare commits

...

68 Commits

Author SHA1 Message Date
Richard Reingruber
532b1c732e 8360599: [TESTBUG] DumpThreadsWithEliminatedLock.java fails because of unstable inlining
Reviewed-by: mdoerr, kevinw
Backport-of: fea73c1d40
2025-07-10 07:34:40 +00:00
Erik Gahlin
1de8943731 8361175: JFR: Document differences between method sample events
Reviewed-by: mgronlun
Backport-of: 63e08d4af7
2025-07-09 15:32:57 +00:00
Jan Lahoda
50751da562 8361570: Incorrect 'sealed is not allowed here' compile-time error
Reviewed-by: liach, vromero
Backport-of: 853319439e
2025-07-09 13:41:05 +00:00
Jan Lahoda
21cb2acda0 8361445: javac crashes on unresolvable constant in @SuppressWarnings
Reviewed-by: liach, asotona
Backport-of: 0bd2f9cba2
2025-07-09 05:07:20 +00:00
Vicente Romero
0e4422b284 8361214: An anonymous class is erroneously being classify as an abstract class
Reviewed-by: liach
Backport-of: 05c9eec8d0
2025-07-08 21:13:43 +00:00
Ioi Lam
1e985168d6 8358680: AOT cache creation fails: no strings should have been added
Reviewed-by: shade, kvn
Backport-of: 3daa03c30f
2025-07-08 19:02:36 +00:00
Ioi Lam
b8965318c1 8360164: AOT cache creation crashes in ~ThreadTotalCPUTimeClosure()
Reviewed-by: shade, kvn
Backport-of: 7d7e60c8ae
2025-07-08 17:36:10 +00:00
Ioi Lam
afe6bd6910 8336147: Clarify CDS documentation about static vs dynamic archive
Reviewed-by: shade
Backport-of: 854de8c9c6
2025-07-08 17:34:39 +00:00
Erik Gahlin
b3b5595362 8361338: JFR: Min and max time in MethodTime event is confusing
Reviewed-by: shade
Backport-of: f3e0588d0b
2025-07-08 14:03:56 +00:00
Jan Lahoda
5e716fd7d1 8359596: Behavior change when both -Xlint:options and -Xlint:-options flags are given
Reviewed-by: liach
Backport-of: 3525a40f39
2025-07-08 07:16:25 +00:00
Roger Riggs
3e93b98baf 8354872: Clarify java.lang.Process resource cleanup
Reviewed-by: iris
Backport-of: afb4a1be9e
2025-07-07 22:18:03 +00:00
Manukumar V S
9a73987f9b 8359889: java/awt/MenuItem/SetLabelTest.java inadvertently triggers clicks on items pinned to the taskbar
Reviewed-by: abhiscxk, aivanov
Backport-of: b7fcd0b235
2025-07-07 13:14:30 +00:00
Erik Gahlin
8707167ef3 8358750: JFR: EventInstrumentation MASK_THROTTLE* constants should be computed in longs
Reviewed-by: mgronlun
Backport-of: 77e69e02eb
2025-07-04 15:07:32 +00:00
Erik Gahlin
e3bd9c6e1c 8360287: JFR: PlatformTracer class should be loaded lazily
Reviewed-by: mgronlun
Backport-of: 8ea544c33f
2025-07-03 18:34:38 +00:00
Martin Doerr
993215f3dd 8361259: JDK25: Backout JDK-8258229
Reviewed-by: mhaessig, thartmann, dlong
2025-07-03 08:52:23 +00:00
Martin Doerr
8a98738f44 8361183: JDK-8360887 needs fixes to avoid cycles and better tests (aix)
Reviewed-by: mbaesken
Backport-of: c460f842bf
2025-07-03 08:46:22 +00:00
Ashutosh Mehra
ab01396209 8361101: AOTCodeAddressTable::_stubs_addr not initialized/freed properly
Reviewed-by: shade
Backport-of: 3066a67e62
2025-07-02 17:49:52 +00:00
Kevin Walls
92268e17be 8359870: JVM crashes in AccessInternal::PostRuntimeDispatch
Reviewed-by: alanb, sspitsyn
Backport-of: 13a3927855
2025-07-02 16:59:29 +00:00
Martin Doerr
a98a5e54fc 8360887: (fs) Files.getFileAttributeView returns unusable FileAttributeView if UserDefinedFileAttributeView unavailable (aix)
Reviewed-by: mbaesken
Backport-of: 0572b6ece7
2025-07-02 15:34:12 +00:00
Aleksey Shipilev
b245c517e3 8359436: AOTCompileEagerly should not be diagnostic
Reviewed-by: kvn
Backport-of: e138297323
2025-07-02 11:52:28 +00:00
Tobias Hartmann
0a151c68d6 8358179: Performance regression in Math.cbrt
Reviewed-by: epeter
Backport-of: 38f59f84c9
2025-07-02 08:23:19 +00:00
Jaikiran Pai
554e38dd5a 8359337: XML/JAXP tests that make network connections should ensure that no proxy is selected
Reviewed-by: dfuchs, iris, joehw
Backport-of: 7583a7b857
2025-07-02 01:36:10 +00:00
Aleksey Shipilev
b5b0b3a33a 8360201: JFR: Initialize JfrThreadLocal::_sampling_critical_section
Reviewed-by: zgu
Backport-of: 5c1f77fab1
2025-06-30 13:28:03 +00:00
David Holmes
0dc9e8447b 8358645: Access violation in ThreadsSMRSupport::print_info_on during thread dump
Reviewed-by: shade, dcubed
Backport-of: 334683e634
2025-06-30 01:06:46 +00:00
Alisen Chung
12ffb0c131 8359761: JDK 25 RDP1 L10n resource files update
Reviewed-by: jlu, aivanov
Backport-of: da7080fffb
2025-06-27 19:28:15 +00:00
Roland Westrelin
eaaaae5be9 8356708: C2: loop strip mining expansion doesn't take sunk stores into account
Reviewed-by: thartmann, epeter
Backport-of: c11f36e620
2025-06-27 16:27:33 +00:00
Jaikiran Pai
926c900efa 8359830: Incorrect os.version reported on macOS Tahoe 26 (Beta)
Reviewed-by: rriggs
Backport-of: 8df6b2c4a3
2025-06-27 02:18:57 +00:00
Roman Kennke
658f80e392 8355319: Update Manpage for Compact Object Headers (Production)
Reviewed-by: coleenp
Backport-of: 75ce44aa84
2025-06-26 12:32:36 +00:00
Martin Doerr
274a2dd729 8360405: [PPC64] some environments don't support mfdscr instruction
Reviewed-by: haosun, rrich
Backport-of: f71d64fbeb
2025-06-26 09:14:18 +00:00
Michael McMahon
a84946dde4 8359268: 3 JNI exception pending defect groups in 2 files
Reviewed-by: dfuchs, djelinski
Backport-of: 1fa090524a
2025-06-25 16:17:18 +00:00
Igor Veresov
fdb3e37c71 8359788: Internal Error: assert(get_instanceKlass()->is_loaded()) failed: must be at least loaded
Reviewed-by: shade
Backport-of: 5c4f92ba9a
2025-06-25 16:12:45 +00:00
Hannes Wallnöfer
80cb773b7e 8328848: Inaccuracy in the documentation of the -group option
Reviewed-by: liach
Backport-of: f8de5bc582
2025-06-25 05:40:18 +00:00
Hannes Wallnöfer
a576952039 8359024: Accessibility bugs in API documentation
Reviewed-by: liach
Backport-of: 9a726df373
2025-06-25 05:36:31 +00:00
Anthony Scarpino
b89f364842 8358099: PEM spec updates
Reviewed-by: weijun
Backport-of: 78158f30ae
2025-06-24 19:32:07 +00:00
Coleen Phillimore
0694cc1d52 8352075: Perf regression accessing fields
Reviewed-by: shade, iklam
Backport-of: e18277b470
2025-06-24 17:10:28 +00:00
Markus Grönlund
a3abaadc15 8360403: Disable constant pool ID assert during troubleshooting
Reviewed-by: egahlin
Backport-of: cbcf401170
2025-06-24 16:49:43 +00:00
Aleksey Shipilev
7cc1f82b84 8360042: GHA: Bump MSVC to 14.44
Reviewed-by: serb
Backport-of: 72679c94ee
2025-06-24 05:48:20 +00:00
William Kemper
636b56374e 8357550: GenShen crashes during freeze: assert(!chunk->requires_barriers()) failed
Reviewed-by: shade
Backport-of: 17cf49746d
2025-06-23 21:03:04 +00:00
Phil Race
fe9efb75b0 8358526: Clarify behavior of java.awt.HeadlessException constructed with no-args
Reviewed-by: honkar, tr, azvegint
Backport-of: 81985d422d
2025-06-23 17:05:48 +00:00
Erik Gahlin
ca6b165003 8359895: JFR: method-timing view doesn't work
Reviewed-by: mgronlun
Backport-of: 984d7f9cdf
2025-06-23 13:09:03 +00:00
Erik Gahlin
d5aa225451 8359242: JFR: Missing help text for method trace and timing
Reviewed-by: mgronlun
Backport-of: e57a214e2a
2025-06-23 12:22:30 +00:00
Matthias Bläsing
79a85df074 8353950: Clipboard interaction on Windows is unstable
8332271: Reading data from the clipboard from multiple threads crashes the JVM

Reviewed-by: prr
Backport-of: 92be7821f5
2025-06-20 21:49:26 +00:00
Jaikiran Pai
41928aed7d 8359709: java.net.HttpURLConnection sends unexpected "Host" request header in some cases after JDK-8344190
Reviewed-by: dfuchs
Backport-of: 57266064a7
2025-06-20 09:47:26 +00:00
Tobias Hartmann
3f6b0c69c3 8359386: Fix incorrect value for max_size of C2CodeStub when APX is used
Reviewed-by: mhaessig, epeter
Backport-of: b52af182c4
2025-06-20 08:29:10 +00:00
SendaoYan
36b185a930 8359402: Test CloseDescriptors.java should throw SkippedException when there is no lsof/sctp
Reviewed-by: jpai
Backport-of: a16d23557b
2025-06-20 06:26:52 +00:00
Erik Gahlin
c832f001e4 8359593: JFR: Instrumentation of java.lang.String corrupts recording
Reviewed-by: mgronlun
Backport-of: 2f2acb2e3f
2025-06-19 14:19:16 +00:00
Vladimir Kozlov
e5ac75a35b 8359646: C1 crash in AOTCodeAddressTable::add_C_string
Reviewed-by: shade, thartmann
Backport-of: 96070212ad
2025-06-19 13:41:06 +00:00
Erik Gahlin
b79ca5f03b 8359248: JFR: Help text for-XX:StartFlightRecording:report-on-exit should explain option can be repeated
Reviewed-by: mgronlun
Backport-of: fedd0a0ee3
2025-06-19 12:56:19 +00:00
Stuart Marks
5bcea92eaa 8338140: (str) Add notes to String.trim and String.isEmpty pointing to newer APIs
Reviewed-by: naoto, bpb, liach
Backport-of: 06d804a0f0
2025-06-17 20:45:27 +00:00
Damon Fenacci
cc4e9716ac 8358129: compiler/startup/StartupOutput.java runs into out of memory on Windows after JDK-8347406
Reviewed-by: shade
Backport-of: 534a8605e5
2025-06-17 13:10:06 +00:00
Roland Westrelin
46cfc1e194 8358334: C2/Shenandoah: incorrect execution with Unsafe
Reviewed-by: thartmann
Backport-of: 1fcede053c
2025-06-17 08:06:58 +00:00
Rajan Halade
ae71782e77 8359170: Add 2 TLS and 2 CS Sectigo roots
Reviewed-by: mullan
Backport-of: 9586817cea
2025-06-17 06:10:35 +00:00
Ioi Lam
753700182d 8355556: JVM crash because archived method handle intrinsics are not restored
Reviewed-by: shade
Backport-of: 366650a438
2025-06-17 04:36:41 +00:00
SendaoYan
eb727dcb51 8359272: Several vmTestbase/compact tests timed out on large memory machine
Reviewed-by: ayang
Backport-of: a0fb35c837
2025-06-17 00:43:52 +00:00
Johannes Bechberger
b6cacfcbc8 8359135: New test TestCPUTimeSampleThrottling fails intermittently
Reviewed-by: mdoerr
Backport-of: 3f0fef2c9c
2025-06-16 16:20:54 +00:00
Hamlin Li
d870a48880 8358892: RISC-V: jvm crash when running dacapo sunflow after JDK-8352504
8359045: RISC-V: construct test to verify invocation of C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::ge/gt

Reviewed-by: fyang
Backport-of: 9d060574e5
2025-06-16 11:18:32 +00:00
Fernando Guallini
2ea2f74f92 8358171: Additional code coverage for PEM API
Reviewed-by: rhalade, ascarpino
Backport-of: b2e7cda6a0
2025-06-16 09:54:18 +00:00
Alan Bateman
077ce2edc7 8358764: (sc) SocketChannel.close when thread blocked in read causes connection to be reset (win)
Reviewed-by: iris, jpai
Backport-of: e5196fc24d
2025-06-16 09:19:56 +00:00
Tobias Hartmann
2a3294571a 8359327: Incorrect AVX3Threshold results into code buffer overflows on APX targets
Reviewed-by: chagedorn
Backport-of: e7f63ba310
2025-06-16 08:48:49 +00:00
SendaoYan
3877746eb9 8359181: Error messages generated by configure --help after 8301197
Reviewed-by: ihse
Backport-of: 7b7136b4ec
2025-06-15 12:25:17 +00:00
Tobias Hartmann
3bd80fe3ba 8357782: JVM JIT Causes Static Initialization Order Issue
Reviewed-by: shade
Backport-of: e8ef93ae9d
2025-06-15 09:05:56 +00:00
Tobias Hartmann
03232d4a5d 8359200: Memory corruption in MStack::push
Reviewed-by: epeter, shade
Backport-of: ed39e17e34
2025-06-15 09:04:55 +00:00
Daniel Fuchs
4111730845 8359364: java/net/URL/EarlyOrDelayedParsing test fails intermittently
Reviewed-by: alanb
Backport-of: 57cabc6d74
2025-06-13 16:54:40 +00:00
Kevin Walls
74ea38e406 8358701: Remove misleading javax.management.remote API doc wording about JMX spec, and historic link to JMXMP
Reviewed-by: alanb
Backport-of: 66535fe26d
2025-06-13 14:28:14 +00:00
Tobias Hartmann
839a91e14b 8357982: Fix several failing BMI tests with -XX:+UseAPX
Reviewed-by: chagedorn
Backport-of: c98dffa186
2025-06-12 11:11:41 +00:00
Daniel Fuchs
aa4f79eaec 8358617: java/net/HttpURLConnection/HttpURLConnectionExpectContinueTest.java fails with 403 due to system proxies
Reviewed-by: jpai
Backport-of: a377773fa7
2025-06-11 16:22:34 +00:00
Stuart Marks
c7df72ff0f 8358809: Improve link to stdin.encoding from java.lang.IO
Reviewed-by: naoto
Backport-of: d024f58e61
2025-06-07 00:56:45 +00:00
Rajan Halade
80e066e733 8345414: Google CAInterop test failures
Reviewed-by: weijun
Backport-of: 8e9ba788ae
2025-06-06 21:31:33 +00:00
261 changed files with 7052 additions and 1459 deletions

View File

@@ -310,7 +310,7 @@ jobs:
uses: ./.github/workflows/build-windows.yml
with:
platform: windows-x64
msvc-toolset-version: '14.43'
msvc-toolset-version: '14.44'
msvc-toolset-architecture: 'x86.x64'
configure-arguments: ${{ github.event.inputs.configure-arguments }}
make-arguments: ${{ github.event.inputs.make-arguments }}
@@ -322,7 +322,7 @@ jobs:
uses: ./.github/workflows/build-windows.yml
with:
platform: windows-aarch64
msvc-toolset-version: '14.43'
msvc-toolset-version: '14.44'
msvc-toolset-architecture: 'arm64'
make-target: 'hotspot'
extra-conf-options: '--openjdk-target=aarch64-unknown-cygwin'

View File

@@ -1,6 +1,6 @@
#!/bin/bash
#
# Copyright (c) 2012, 2023, 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
@@ -366,7 +366,7 @@ EOT
# Print additional help, e.g. a list of toolchains and JVM features.
# This must be done by the autoconf script.
( CONFIGURE_PRINT_ADDITIONAL_HELP=true . $generated_script PRINTF=printf )
( CONFIGURE_PRINT_ADDITIONAL_HELP=true . $generated_script PRINTF=printf ECHO=echo )
cat <<EOT

View File

@@ -456,13 +456,13 @@ SliderDemo.horizontal=Horizontal
SliderDemo.vertical=Vertikal
SliderDemo.plain=Einfach
SliderDemo.a_plain_slider=Ein einfacher Schieberegler
SliderDemo.majorticks=Grobteilungen
SliderDemo.majorticksdescription=Ein Schieberegler mit Grobteilungsmarkierungen
SliderDemo.ticks=Feinteilungen, Teilungen zum Einrasten und Labels
SliderDemo.minorticks=Feinteilungen
SliderDemo.minorticksdescription=Ein Schieberegler mit Grob- und Feinteilungen, mit Teilungen, in die der Schieberegler einrastet, wobei einige Teilungen mit einem sichtbaren Label versehen sind
SliderDemo.majorticks=Hauptteilstriche
SliderDemo.majorticksdescription=Ein Schieberegler mit Hauptteilstrichen
SliderDemo.ticks=Hilfsteilstriche, zum Einrasten und Beschriften
SliderDemo.minorticks=Hilfsteilstriche
SliderDemo.minorticksdescription=Ein Schieberegler mit Haupt- und Hilfsteilstrichen, in die der Schieberegler einrastet, wobei einige Teilstriche mit einer sichtbaren Beschriftung versehen sind
SliderDemo.disabled=Deaktiviert
SliderDemo.disableddescription=Ein Schieberegler mit Grob- und Feinteilungen, der nicht aktiviert ist (kann nicht bearbeitet werden)
SliderDemo.disableddescription=Ein Schieberegler mit Haupt- und Hilfsteilstrichen, der nicht aktiviert ist (kann nicht bearbeitet werden)
### SplitPane Demo ###

View File

@@ -3928,8 +3928,10 @@ void MacroAssembler::kernel_crc32_vpmsum_aligned(Register crc, Register buf, Reg
Label L_outer_loop, L_inner_loop, L_last;
// Set DSCR pre-fetch to deepest.
load_const_optimized(t0, VM_Version::_dscr_val | 7);
mtdscr(t0);
if (VM_Version::has_mfdscr()) {
load_const_optimized(t0, VM_Version::_dscr_val | 7);
mtdscr(t0);
}
mtvrwz(VCRC, crc); // crc lives in VCRC, now
@@ -4073,8 +4075,10 @@ void MacroAssembler::kernel_crc32_vpmsum_aligned(Register crc, Register buf, Reg
// ********** Main loop end **********
// Restore DSCR pre-fetch value.
load_const_optimized(t0, VM_Version::_dscr_val);
mtdscr(t0);
if (VM_Version::has_mfdscr()) {
load_const_optimized(t0, VM_Version::_dscr_val);
mtdscr(t0);
}
// ********** Simple loop for remaining 16 byte blocks **********
{

View File

@@ -952,8 +952,10 @@ class StubGenerator: public StubCodeGenerator {
address start_pc = __ pc();
Register tmp1 = R6_ARG4;
// probably copy stub would have changed value reset it.
__ load_const_optimized(tmp1, VM_Version::_dscr_val);
__ mtdscr(tmp1);
if (VM_Version::has_mfdscr()) {
__ load_const_optimized(tmp1, VM_Version::_dscr_val);
__ mtdscr(tmp1);
}
__ li(R3_RET, 0); // return 0
__ blr();
return start_pc;
@@ -1070,9 +1072,10 @@ class StubGenerator: public StubCodeGenerator {
__ dcbt(R3_ARG1, 0);
// If supported set DSCR pre-fetch to deepest.
__ load_const_optimized(tmp2, VM_Version::_dscr_val | 7);
__ mtdscr(tmp2);
if (VM_Version::has_mfdscr()) {
__ load_const_optimized(tmp2, VM_Version::_dscr_val | 7);
__ mtdscr(tmp2);
}
__ li(tmp1, 16);
// Backbranch target aligned to 32-byte. Not 16-byte align as
@@ -1092,8 +1095,10 @@ class StubGenerator: public StubCodeGenerator {
__ bdnz(l_10); // Dec CTR and loop if not zero.
// Restore DSCR pre-fetch value.
__ load_const_optimized(tmp2, VM_Version::_dscr_val);
__ mtdscr(tmp2);
if (VM_Version::has_mfdscr()) {
__ load_const_optimized(tmp2, VM_Version::_dscr_val);
__ mtdscr(tmp2);
}
} // FasterArrayCopy
@@ -1344,8 +1349,10 @@ class StubGenerator: public StubCodeGenerator {
__ dcbt(R3_ARG1, 0);
// If supported set DSCR pre-fetch to deepest.
__ load_const_optimized(tmp2, VM_Version::_dscr_val | 7);
__ mtdscr(tmp2);
if (VM_Version::has_mfdscr()) {
__ load_const_optimized(tmp2, VM_Version::_dscr_val | 7);
__ mtdscr(tmp2);
}
__ li(tmp1, 16);
// Backbranch target aligned to 32-byte. It's not aligned 16-byte
@@ -1365,8 +1372,11 @@ class StubGenerator: public StubCodeGenerator {
__ bdnz(l_9); // Dec CTR and loop if not zero.
// Restore DSCR pre-fetch value.
__ load_const_optimized(tmp2, VM_Version::_dscr_val);
__ mtdscr(tmp2);
if (VM_Version::has_mfdscr()) {
__ load_const_optimized(tmp2, VM_Version::_dscr_val);
__ mtdscr(tmp2);
}
} // FasterArrayCopy
__ bind(l_6);
@@ -1527,9 +1537,10 @@ class StubGenerator: public StubCodeGenerator {
__ dcbt(R3_ARG1, 0);
// Set DSCR pre-fetch to deepest.
__ load_const_optimized(tmp2, VM_Version::_dscr_val | 7);
__ mtdscr(tmp2);
if (VM_Version::has_mfdscr()) {
__ load_const_optimized(tmp2, VM_Version::_dscr_val | 7);
__ mtdscr(tmp2);
}
__ li(tmp1, 16);
// Backbranch target aligned to 32-byte. Not 16-byte align as
@@ -1549,9 +1560,10 @@ class StubGenerator: public StubCodeGenerator {
__ bdnz(l_7); // Dec CTR and loop if not zero.
// Restore DSCR pre-fetch value.
__ load_const_optimized(tmp2, VM_Version::_dscr_val);
__ mtdscr(tmp2);
if (VM_Version::has_mfdscr()) {
__ load_const_optimized(tmp2, VM_Version::_dscr_val);
__ mtdscr(tmp2);
}
} // FasterArrayCopy
@@ -1672,9 +1684,10 @@ class StubGenerator: public StubCodeGenerator {
__ dcbt(R3_ARG1, 0);
// Set DSCR pre-fetch to deepest.
__ load_const_optimized(tmp2, VM_Version::_dscr_val | 7);
__ mtdscr(tmp2);
if (VM_Version::has_mfdscr()) {
__ load_const_optimized(tmp2, VM_Version::_dscr_val | 7);
__ mtdscr(tmp2);
}
__ li(tmp1, 16);
// Backbranch target aligned to 32-byte. Not 16-byte align as
@@ -1694,8 +1707,10 @@ class StubGenerator: public StubCodeGenerator {
__ bdnz(l_4);
// Restore DSCR pre-fetch value.
__ load_const_optimized(tmp2, VM_Version::_dscr_val);
__ mtdscr(tmp2);
if (VM_Version::has_mfdscr()) {
__ load_const_optimized(tmp2, VM_Version::_dscr_val);
__ mtdscr(tmp2);
}
__ cmpwi(CR0, R5_ARG3, 0);
__ beq(CR0, l_6);
@@ -1788,9 +1803,10 @@ class StubGenerator: public StubCodeGenerator {
__ dcbt(R3_ARG1, 0);
// Set DSCR pre-fetch to deepest.
__ load_const_optimized(tmp2, VM_Version::_dscr_val | 7);
__ mtdscr(tmp2);
if (VM_Version::has_mfdscr()) {
__ load_const_optimized(tmp2, VM_Version::_dscr_val | 7);
__ mtdscr(tmp2);
}
__ li(tmp1, 16);
// Backbranch target aligned to 32-byte. Not 16-byte align as
@@ -1810,8 +1826,10 @@ class StubGenerator: public StubCodeGenerator {
__ bdnz(l_5); // Dec CTR and loop if not zero.
// Restore DSCR pre-fetch value.
__ load_const_optimized(tmp2, VM_Version::_dscr_val);
__ mtdscr(tmp2);
if (VM_Version::has_mfdscr()) {
__ load_const_optimized(tmp2, VM_Version::_dscr_val);
__ mtdscr(tmp2);
}
} // FasterArrayCopy
@@ -1910,9 +1928,10 @@ class StubGenerator: public StubCodeGenerator {
__ dcbt(R3_ARG1, 0);
// Set DSCR pre-fetch to deepest.
__ load_const_optimized(tmp2, VM_Version::_dscr_val | 7);
__ mtdscr(tmp2);
if (VM_Version::has_mfdscr()) {
__ load_const_optimized(tmp2, VM_Version::_dscr_val | 7);
__ mtdscr(tmp2);
}
__ li(tmp1, 16);
// Backbranch target aligned to 32-byte. Not 16-byte align as
@@ -1932,8 +1951,10 @@ class StubGenerator: public StubCodeGenerator {
__ bdnz(l_4);
// Restore DSCR pre-fetch value.
__ load_const_optimized(tmp2, VM_Version::_dscr_val);
__ mtdscr(tmp2);
if (VM_Version::has_mfdscr()) {
__ load_const_optimized(tmp2, VM_Version::_dscr_val);
__ mtdscr(tmp2);
}
__ cmpwi(CR0, R5_ARG3, 0);
__ beq(CR0, l_1);

View File

@@ -80,7 +80,9 @@ void VM_Version::initialize() {
"%zu on this machine", PowerArchitecturePPC64);
// Power 8: Configure Data Stream Control Register.
config_dscr();
if (VM_Version::has_mfdscr()) {
config_dscr();
}
if (!UseSIGTRAP) {
MSG(TrapBasedICMissChecks);
@@ -170,7 +172,8 @@ void VM_Version::initialize() {
// Create and print feature-string.
char buf[(num_features+1) * 16]; // Max 16 chars per feature.
jio_snprintf(buf, sizeof(buf),
"ppc64 sha aes%s%s",
"ppc64 sha aes%s%s%s",
(has_mfdscr() ? " mfdscr" : ""),
(has_darn() ? " darn" : ""),
(has_brw() ? " brw" : "")
// Make sure number of %s matches num_features!
@@ -488,6 +491,7 @@ void VM_Version::determine_features() {
uint32_t *code = (uint32_t *)a->pc();
// Keep R3_ARG1 unmodified, it contains &field (see below).
// Keep R4_ARG2 unmodified, it contains offset = 0 (see below).
a->mfdscr(R0);
a->darn(R7);
a->brw(R5, R6);
a->blr();
@@ -524,6 +528,7 @@ void VM_Version::determine_features() {
// determine which instructions are legal.
int feature_cntr = 0;
if (code[feature_cntr++]) features |= mfdscr_m;
if (code[feature_cntr++]) features |= darn_m;
if (code[feature_cntr++]) features |= brw_m;

View File

@@ -32,12 +32,14 @@
class VM_Version: public Abstract_VM_Version {
protected:
enum Feature_Flag {
mfdscr,
darn,
brw,
num_features // last entry to count features
};
enum Feature_Flag_Set {
unknown_m = 0,
mfdscr_m = (1 << mfdscr ),
darn_m = (1 << darn ),
brw_m = (1 << brw ),
all_features_m = (unsigned long)-1
@@ -67,8 +69,9 @@ public:
static bool is_determine_features_test_running() { return _is_determine_features_test_running; }
// CPU instruction support
static bool has_darn() { return (_features & darn_m) != 0; }
static bool has_brw() { return (_features & brw_m) != 0; }
static bool has_mfdscr() { return (_features & mfdscr_m) != 0; } // Power8, but may be unavailable (QEMU)
static bool has_darn() { return (_features & darn_m) != 0; }
static bool has_brw() { return (_features & brw_m) != 0; }
// Assembler testing
static void allow_all();

View File

@@ -2170,15 +2170,13 @@ void C2_MacroAssembler::enc_cmove_cmp_fp(int cmpFlag, FloatRegister op1, FloatRe
cmov_cmp_fp_le(op1, op2, dst, src, is_single);
break;
case BoolTest::ge:
assert(false, "Should go to BoolTest::le case");
ShouldNotReachHere();
cmov_cmp_fp_ge(op1, op2, dst, src, is_single);
break;
case BoolTest::lt:
cmov_cmp_fp_lt(op1, op2, dst, src, is_single);
break;
case BoolTest::gt:
assert(false, "Should go to BoolTest::lt case");
ShouldNotReachHere();
cmov_cmp_fp_gt(op1, op2, dst, src, is_single);
break;
default:
assert(false, "unsupported compare condition");

View File

@@ -1268,12 +1268,19 @@ void MacroAssembler::cmov_gtu(Register cmp1, Register cmp2, Register dst, Regist
}
// ----------- cmove, compare float -----------
//
// For CmpF/D + CMoveI/L, ordered ones are quite straight and simple,
// so, just list behaviour of unordered ones as follow.
//
// Set dst (CMoveI (Binary cop (CmpF/D op1 op2)) (Binary dst src))
// (If one or both inputs to the compare are NaN, then)
// 1. (op1 lt op2) => true => CMove: dst = src
// 2. (op1 le op2) => true => CMove: dst = src
// 3. (op1 gt op2) => false => CMove: dst = dst
// 4. (op1 ge op2) => false => CMove: dst = dst
// 5. (op1 eq op2) => false => CMove: dst = dst
// 6. (op1 ne op2) => true => CMove: dst = src
// Move src to dst only if cmp1 == cmp2,
// otherwise leave dst unchanged, including the case where one of them is NaN.
// Clarification:
// java code : cmp1 != cmp2 ? dst : src
// transformed to : CMove dst, (cmp1 eq cmp2), dst, src
void MacroAssembler::cmov_cmp_fp_eq(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single) {
if (UseZicond) {
if (is_single) {
@@ -1289,7 +1296,7 @@ void MacroAssembler::cmov_cmp_fp_eq(FloatRegister cmp1, FloatRegister cmp2, Regi
Label no_set;
if (is_single) {
// jump if cmp1 != cmp2, including the case of NaN
// not jump (i.e. move src to dst) if cmp1 == cmp2
// fallthrough (i.e. move src to dst) if cmp1 == cmp2
float_bne(cmp1, cmp2, no_set);
} else {
double_bne(cmp1, cmp2, no_set);
@@ -1298,11 +1305,6 @@ void MacroAssembler::cmov_cmp_fp_eq(FloatRegister cmp1, FloatRegister cmp2, Regi
bind(no_set);
}
// Keep dst unchanged only if cmp1 == cmp2,
// otherwise move src to dst, including the case where one of them is NaN.
// Clarification:
// java code : cmp1 == cmp2 ? dst : src
// transformed to : CMove dst, (cmp1 ne cmp2), dst, src
void MacroAssembler::cmov_cmp_fp_ne(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single) {
if (UseZicond) {
if (is_single) {
@@ -1318,7 +1320,7 @@ void MacroAssembler::cmov_cmp_fp_ne(FloatRegister cmp1, FloatRegister cmp2, Regi
Label no_set;
if (is_single) {
// jump if cmp1 == cmp2
// not jump (i.e. move src to dst) if cmp1 != cmp2, including the case of NaN
// fallthrough (i.e. move src to dst) if cmp1 != cmp2, including the case of NaN
float_beq(cmp1, cmp2, no_set);
} else {
double_beq(cmp1, cmp2, no_set);
@@ -1327,14 +1329,6 @@ void MacroAssembler::cmov_cmp_fp_ne(FloatRegister cmp1, FloatRegister cmp2, Regi
bind(no_set);
}
// When cmp1 <= cmp2 or any of them is NaN then dst = src, otherwise, dst = dst
// Clarification
// scenario 1:
// java code : cmp2 < cmp1 ? dst : src
// transformed to : CMove dst, (cmp1 le cmp2), dst, src
// scenario 2:
// java code : cmp1 > cmp2 ? dst : src
// transformed to : CMove dst, (cmp1 le cmp2), dst, src
void MacroAssembler::cmov_cmp_fp_le(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single) {
if (UseZicond) {
if (is_single) {
@@ -1350,7 +1344,7 @@ void MacroAssembler::cmov_cmp_fp_le(FloatRegister cmp1, FloatRegister cmp2, Regi
Label no_set;
if (is_single) {
// jump if cmp1 > cmp2
// not jump (i.e. move src to dst) if cmp1 <= cmp2 or either is NaN
// fallthrough (i.e. move src to dst) if cmp1 <= cmp2 or either is NaN
float_bgt(cmp1, cmp2, no_set);
} else {
double_bgt(cmp1, cmp2, no_set);
@@ -1359,14 +1353,30 @@ void MacroAssembler::cmov_cmp_fp_le(FloatRegister cmp1, FloatRegister cmp2, Regi
bind(no_set);
}
// When cmp1 < cmp2 or any of them is NaN then dst = src, otherwise, dst = dst
// Clarification
// scenario 1:
// java code : cmp2 <= cmp1 ? dst : src
// transformed to : CMove dst, (cmp1 lt cmp2), dst, src
// scenario 2:
// java code : cmp1 >= cmp2 ? dst : src
// transformed to : CMove dst, (cmp1 lt cmp2), dst, src
void MacroAssembler::cmov_cmp_fp_ge(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single) {
if (UseZicond) {
if (is_single) {
fle_s(t0, cmp2, cmp1);
} else {
fle_d(t0, cmp2, cmp1);
}
czero_nez(dst, dst, t0);
czero_eqz(t0 , src, t0);
orr(dst, dst, t0);
return;
}
Label no_set;
if (is_single) {
// jump if cmp1 < cmp2 or either is NaN
// fallthrough (i.e. move src to dst) if cmp1 >= cmp2
float_blt(cmp1, cmp2, no_set, false, true);
} else {
double_blt(cmp1, cmp2, no_set, false, true);
}
mv(dst, src);
bind(no_set);
}
void MacroAssembler::cmov_cmp_fp_lt(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single) {
if (UseZicond) {
if (is_single) {
@@ -1382,7 +1392,7 @@ void MacroAssembler::cmov_cmp_fp_lt(FloatRegister cmp1, FloatRegister cmp2, Regi
Label no_set;
if (is_single) {
// jump if cmp1 >= cmp2
// not jump (i.e. move src to dst) if cmp1 < cmp2 or either is NaN
// fallthrough (i.e. move src to dst) if cmp1 < cmp2 or either is NaN
float_bge(cmp1, cmp2, no_set);
} else {
double_bge(cmp1, cmp2, no_set);
@@ -1391,6 +1401,30 @@ void MacroAssembler::cmov_cmp_fp_lt(FloatRegister cmp1, FloatRegister cmp2, Regi
bind(no_set);
}
void MacroAssembler::cmov_cmp_fp_gt(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single) {
if (UseZicond) {
if (is_single) {
flt_s(t0, cmp2, cmp1);
} else {
flt_d(t0, cmp2, cmp1);
}
czero_nez(dst, dst, t0);
czero_eqz(t0 , src, t0);
orr(dst, dst, t0);
return;
}
Label no_set;
if (is_single) {
// jump if cmp1 <= cmp2 or either is NaN
// fallthrough (i.e. move src to dst) if cmp1 > cmp2
float_ble(cmp1, cmp2, no_set, false, true);
} else {
double_ble(cmp1, cmp2, no_set, false, true);
}
mv(dst, src);
bind(no_set);
}
// Float compare branch instructions
#define INSN(NAME, FLOATCMP, BRANCH) \

View File

@@ -660,7 +660,9 @@ class MacroAssembler: public Assembler {
void cmov_cmp_fp_eq(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single);
void cmov_cmp_fp_ne(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single);
void cmov_cmp_fp_le(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single);
void cmov_cmp_fp_ge(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single);
void cmov_cmp_fp_lt(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single);
void cmov_cmp_fp_gt(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single);
public:
// We try to follow risc-v asm menomics.

View File

@@ -4655,6 +4655,7 @@ static void convertF2I_slowpath(C2_MacroAssembler& masm, C2GeneralStub<Register,
__ subptr(rsp, 8);
__ movdbl(Address(rsp), src);
__ call(RuntimeAddress(target));
// APX REX2 encoding for pop(dst) increases the stub size by 1 byte.
__ pop(dst);
__ jmp(stub.continuation());
#undef __
@@ -4687,7 +4688,9 @@ void C2_MacroAssembler::convertF2I(BasicType dst_bt, BasicType src_bt, Register
}
}
auto stub = C2CodeStub::make<Register, XMMRegister, address>(dst, src, slowpath_target, 23, convertF2I_slowpath);
// Using the APX extended general purpose registers increases the instruction encoding size by 1 byte.
int max_size = 23 + (UseAPX ? 1 : 0);
auto stub = C2CodeStub::make<Register, XMMRegister, address>(dst, src, slowpath_target, max_size, convertF2I_slowpath);
jcc(Assembler::equal, stub->entry());
bind(stub->continuation());
}

View File

@@ -239,7 +239,7 @@
do_arch_blob, \
do_arch_entry, \
do_arch_entry_init) \
do_arch_blob(final, 31000 \
do_arch_blob(final, 33000 \
WINDOWS_ONLY(+22000) ZGC_ONLY(+20000)) \
#endif // CPU_X86_STUBDECLARATIONS_HPP

View File

@@ -46,6 +46,12 @@
//
/******************************************************************************/
/* Represents 0x7FFFFFFFFFFFFFFF double precision in lower 64 bits*/
ATTRIBUTE_ALIGNED(16) static const juint _ABS_MASK[] =
{
4294967295, 2147483647, 0, 0
};
ATTRIBUTE_ALIGNED(4) static const juint _SIG_MASK[] =
{
0, 1032192
@@ -188,10 +194,10 @@ address StubGenerator::generate_libmCbrt() {
StubCodeMark mark(this, stub_id);
address start = __ pc();
Label L_2TAG_PACKET_0_0_1, L_2TAG_PACKET_1_0_1, L_2TAG_PACKET_2_0_1, L_2TAG_PACKET_3_0_1;
Label L_2TAG_PACKET_4_0_1, L_2TAG_PACKET_5_0_1, L_2TAG_PACKET_6_0_1;
Label L_2TAG_PACKET_0_0_1, L_2TAG_PACKET_1_0_1, L_2TAG_PACKET_2_0_1;
Label B1_1, B1_2, B1_4;
address ABS_MASK = (address)_ABS_MASK;
address SIG_MASK = (address)_SIG_MASK;
address EXP_MASK = (address)_EXP_MASK;
address EXP_MSK2 = (address)_EXP_MSK2;
@@ -208,8 +214,12 @@ address StubGenerator::generate_libmCbrt() {
__ enter(); // required for proper stackwalking of RuntimeStub frame
__ bind(B1_1);
__ subq(rsp, 24);
__ movsd(Address(rsp), xmm0);
__ ucomisd(xmm0, ExternalAddress(ZERON), r11 /*rscratch*/);
__ jcc(Assembler::equal, L_2TAG_PACKET_1_0_1); // Branch only if x is +/- zero or NaN
__ movq(xmm1, xmm0);
__ andpd(xmm1, ExternalAddress(ABS_MASK), r11 /*rscratch*/);
__ ucomisd(xmm1, ExternalAddress(INF), r11 /*rscratch*/);
__ jcc(Assembler::equal, B1_4); // Branch only if x is +/- INF
__ bind(B1_2);
__ movq(xmm7, xmm0);
@@ -228,8 +238,6 @@ address StubGenerator::generate_libmCbrt() {
__ andl(rdx, rax);
__ cmpl(rdx, 0);
__ jcc(Assembler::equal, L_2TAG_PACKET_0_0_1); // Branch only if |x| is denormalized
__ cmpl(rdx, 524032);
__ jcc(Assembler::equal, L_2TAG_PACKET_1_0_1); // Branch only if |x| is INF or NaN
__ shrl(rdx, 8);
__ shrq(r9, 8);
__ andpd(xmm2, xmm0);
@@ -297,8 +305,6 @@ address StubGenerator::generate_libmCbrt() {
__ andl(rdx, rax);
__ shrl(rdx, 8);
__ shrq(r9, 8);
__ cmpl(rdx, 0);
__ jcc(Assembler::equal, L_2TAG_PACKET_3_0_1); // Branch only if |x| is zero
__ andpd(xmm2, xmm0);
__ andpd(xmm0, xmm5);
__ orpd(xmm3, xmm2);
@@ -322,41 +328,10 @@ address StubGenerator::generate_libmCbrt() {
__ psllq(xmm7, 52);
__ jmp(L_2TAG_PACKET_2_0_1);
__ bind(L_2TAG_PACKET_3_0_1);
__ cmpq(r9, 0);
__ jcc(Assembler::notEqual, L_2TAG_PACKET_4_0_1); // Branch only if x is negative zero
__ xorpd(xmm0, xmm0);
__ jmp(B1_4);
__ bind(L_2TAG_PACKET_4_0_1);
__ movsd(xmm0, ExternalAddress(ZERON), r11 /*rscratch*/);
__ jmp(B1_4);
__ bind(L_2TAG_PACKET_1_0_1);
__ movl(rax, Address(rsp, 4));
__ movl(rdx, Address(rsp));
__ movl(rcx, rax);
__ andl(rcx, 2147483647);
__ cmpl(rcx, 2146435072);
__ jcc(Assembler::above, L_2TAG_PACKET_5_0_1); // Branch only if |x| is NaN
__ cmpl(rdx, 0);
__ jcc(Assembler::notEqual, L_2TAG_PACKET_5_0_1); // Branch only if |x| is NaN
__ cmpl(rax, 2146435072);
__ jcc(Assembler::notEqual, L_2TAG_PACKET_6_0_1); // Branch only if x is negative INF
__ movsd(xmm0, ExternalAddress(INF), r11 /*rscratch*/);
__ jmp(B1_4);
__ bind(L_2TAG_PACKET_6_0_1);
__ movsd(xmm0, ExternalAddress(NEG_INF), r11 /*rscratch*/);
__ jmp(B1_4);
__ bind(L_2TAG_PACKET_5_0_1);
__ movsd(xmm0, Address(rsp));
__ addsd(xmm0, xmm0);
__ movq(Address(rsp, 8), xmm0);
__ bind(B1_4);
__ addq(rsp, 24);
__ leave(); // required for proper stackwalking of RuntimeStub frame
__ ret(0);

View File

@@ -2111,7 +2111,7 @@ bool VM_Version::is_intel_cascade_lake() {
// has improved implementation of 64-byte load/stores and so the default
// threshold is set to 0 for these platforms.
int VM_Version::avx3_threshold() {
return (is_intel_family_core() &&
return (is_intel_server_family() &&
supports_serialize() &&
FLAG_IS_DEFAULT(AVX3Threshold)) ? 0 : AVX3Threshold;
}

View File

@@ -10527,7 +10527,8 @@ instruct xorI_rReg_im1_ndd(rRegI dst, rRegI src, immI_M1 imm)
// Xor Register with Immediate
instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
%{
predicate(!UseAPX);
// Strict predicate check to make selection of xorI_rReg_im1 cost agnostic if immI src is -1.
predicate(!UseAPX && n->in(2)->bottom_type()->is_int()->get_con() != -1);
match(Set dst (XorI dst src));
effect(KILL cr);
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
@@ -10541,7 +10542,8 @@ instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
instruct xorI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr)
%{
predicate(UseAPX);
// Strict predicate check to make selection of xorI_rReg_im1_ndd cost agnostic if immI src2 is -1.
predicate(UseAPX && n->in(2)->bottom_type()->is_int()->get_con() != -1);
match(Set dst (XorI src1 src2));
effect(KILL cr);
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
@@ -10559,6 +10561,7 @@ instruct xorI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr)
predicate(UseAPX);
match(Set dst (XorI (LoadI src1) src2));
effect(KILL cr);
ins_cost(150);
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
format %{ "exorl $dst, $src1, $src2\t# int ndd" %}
@@ -11201,7 +11204,8 @@ instruct xorL_rReg_im1_ndd(rRegL dst,rRegL src, immL_M1 imm)
// Xor Register with Immediate
instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr)
%{
predicate(!UseAPX);
// Strict predicate check to make selection of xorL_rReg_im1 cost agnostic if immL32 src is -1.
predicate(!UseAPX && n->in(2)->bottom_type()->is_long()->get_con() != -1L);
match(Set dst (XorL dst src));
effect(KILL cr);
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
@@ -11215,7 +11219,8 @@ instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr)
instruct xorL_rReg_rReg_imm(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr)
%{
predicate(UseAPX);
// Strict predicate check to make selection of xorL_rReg_im1_ndd cost agnostic if immL32 src2 is -1.
predicate(UseAPX && n->in(2)->bottom_type()->is_long()->get_con() != -1L);
match(Set dst (XorL src1 src2));
effect(KILL cr);
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
@@ -11234,6 +11239,7 @@ instruct xorL_rReg_mem_imm(rRegL dst, memory src1, immL32 src2, rFlagsReg cr)
match(Set dst (XorL (LoadL src1) src2));
effect(KILL cr);
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
ins_cost(150);
format %{ "exorq $dst, $src1, $src2\t# long ndd" %}
ins_encode %{

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2023, 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
@@ -187,7 +187,13 @@ class ValueNumberingVisitor: public InstructionVisitor {
void do_Convert (Convert* x) { /* nothing to do */ }
void do_NullCheck (NullCheck* x) { /* nothing to do */ }
void do_TypeCast (TypeCast* x) { /* nothing to do */ }
void do_NewInstance (NewInstance* x) { /* nothing to do */ }
void do_NewInstance (NewInstance* x) {
ciInstanceKlass* c = x->klass();
if (c != nullptr && !c->is_initialized() &&
(!c->is_loaded() || c->has_class_initializer())) {
kill_memory();
}
}
void do_NewTypeArray (NewTypeArray* x) { /* nothing to do */ }
void do_NewObjectArray (NewObjectArray* x) { /* nothing to do */ }
void do_NewMultiArray (NewMultiArray* x) { /* nothing to do */ }

View File

@@ -147,7 +147,7 @@
product(bool, AOTVerifyTrainingData, trueInDebug, DIAGNOSTIC, \
"Verify archived training data") \
\
product(bool, AOTCompileEagerly, false, DIAGNOSTIC, \
product(bool, AOTCompileEagerly, false, EXPERIMENTAL, \
"Compile methods as soon as possible") \
\
/* AOT Code flags */ \

View File

@@ -837,11 +837,10 @@ void MetaspaceShared::preload_and_dump(TRAPS) {
struct stat st;
if (os::stat(AOTCache, &st) != 0) {
tty->print_cr("AOTCache creation failed: %s", AOTCache);
vm_exit(0);
} else {
tty->print_cr("AOTCache creation is complete: %s " INT64_FORMAT " bytes", AOTCache, (int64_t)(st.st_size));
vm_exit(0);
}
vm_direct_exit(0);
}
}
}

View File

@@ -549,6 +549,11 @@ bool ciInstanceKlass::compute_has_trusted_loader() {
return java_lang_ClassLoader::is_trusted_loader(loader_oop);
}
bool ciInstanceKlass::has_class_initializer() {
VM_ENTRY_MARK;
return get_instanceKlass()->class_initializer() != nullptr;
}
// ------------------------------------------------------------------
// ciInstanceKlass::find_method
//

View File

@@ -231,6 +231,8 @@ public:
ciInstanceKlass* unique_concrete_subklass();
bool has_finalizable_subclass();
bool has_class_initializer();
bool contains_field_offset(int offset);
// Get the instance of java.lang.Class corresponding to

View File

@@ -3738,6 +3738,7 @@ void ClassFileParser::apply_parsed_class_metadata(
_cp->set_pool_holder(this_klass);
this_klass->set_constants(_cp);
this_klass->set_fieldinfo_stream(_fieldinfo_stream);
this_klass->set_fieldinfo_search_table(_fieldinfo_search_table);
this_klass->set_fields_status(_fields_status);
this_klass->set_methods(_methods);
this_klass->set_inner_classes(_inner_classes);
@@ -3747,6 +3748,8 @@ void ClassFileParser::apply_parsed_class_metadata(
this_klass->set_permitted_subclasses(_permitted_subclasses);
this_klass->set_record_components(_record_components);
DEBUG_ONLY(FieldInfoStream::validate_search_table(_cp, _fieldinfo_stream, _fieldinfo_search_table));
// Delay the setting of _local_interfaces and _transitive_interfaces until after
// initialize_supers() in fill_instance_klass(). It is because the _local_interfaces could
// be shared with _transitive_interfaces and _transitive_interfaces may be shared with
@@ -5054,6 +5057,7 @@ void ClassFileParser::fill_instance_klass(InstanceKlass* ik,
// note that is not safe to use the fields in the parser from this point on
assert(nullptr == _cp, "invariant");
assert(nullptr == _fieldinfo_stream, "invariant");
assert(nullptr == _fieldinfo_search_table, "invariant");
assert(nullptr == _fields_status, "invariant");
assert(nullptr == _methods, "invariant");
assert(nullptr == _inner_classes, "invariant");
@@ -5274,6 +5278,7 @@ ClassFileParser::ClassFileParser(ClassFileStream* stream,
_super_klass(),
_cp(nullptr),
_fieldinfo_stream(nullptr),
_fieldinfo_search_table(nullptr),
_fields_status(nullptr),
_methods(nullptr),
_inner_classes(nullptr),
@@ -5350,6 +5355,7 @@ void ClassFileParser::clear_class_metadata() {
// deallocated if classfile parsing returns an error.
_cp = nullptr;
_fieldinfo_stream = nullptr;
_fieldinfo_search_table = nullptr;
_fields_status = nullptr;
_methods = nullptr;
_inner_classes = nullptr;
@@ -5372,6 +5378,7 @@ ClassFileParser::~ClassFileParser() {
if (_fieldinfo_stream != nullptr) {
MetadataFactory::free_array<u1>(_loader_data, _fieldinfo_stream);
}
MetadataFactory::free_array<u1>(_loader_data, _fieldinfo_search_table);
if (_fields_status != nullptr) {
MetadataFactory::free_array<FieldStatus>(_loader_data, _fields_status);
@@ -5772,6 +5779,7 @@ void ClassFileParser::post_process_parsed_stream(const ClassFileStream* const st
_fieldinfo_stream =
FieldInfoStream::create_FieldInfoStream(_temp_field_info, _java_fields_count,
injected_fields_count, loader_data(), CHECK);
_fieldinfo_search_table = FieldInfoStream::create_search_table(_cp, _fieldinfo_stream, _loader_data, CHECK);
_fields_status =
MetadataFactory::new_array<FieldStatus>(_loader_data, _temp_field_info->length(),
FieldStatus(0), CHECK);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 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
@@ -123,6 +123,7 @@ class ClassFileParser {
const InstanceKlass* _super_klass;
ConstantPool* _cp;
Array<u1>* _fieldinfo_stream;
Array<u1>* _fieldinfo_search_table;
Array<FieldStatus>* _fields_status;
Array<Method*>* _methods;
Array<u2>* _inner_classes;

View File

@@ -301,7 +301,7 @@ void FieldLayout::reconstruct_layout(const InstanceKlass* ik, bool& has_instance
BasicType last_type;
int last_offset = -1;
while (ik != nullptr) {
for (AllFieldStream fs(ik->fieldinfo_stream(), ik->constants()); !fs.done(); fs.next()) {
for (AllFieldStream fs(ik); !fs.done(); fs.next()) {
BasicType type = Signature::basic_type(fs.signature());
// distinction between static and non-static fields is missing
if (fs.access_flags().is_static()) continue;
@@ -461,7 +461,7 @@ void FieldLayout::print(outputStream* output, bool is_static, const InstanceKlas
bool found = false;
const InstanceKlass* ik = super;
while (!found && ik != nullptr) {
for (AllFieldStream fs(ik->fieldinfo_stream(), ik->constants()); !fs.done(); fs.next()) {
for (AllFieldStream fs(ik); !fs.done(); fs.next()) {
if (fs.offset() == b->offset()) {
output->print_cr(" @%d \"%s\" %s %d/%d %s",
b->offset(),

View File

@@ -967,6 +967,13 @@ void java_lang_Class::fixup_mirror(Klass* k, TRAPS) {
Array<u1>* new_fis = FieldInfoStream::create_FieldInfoStream(fields, java_fields, injected_fields, k->class_loader_data(), CHECK);
ik->set_fieldinfo_stream(new_fis);
MetadataFactory::free_array<u1>(k->class_loader_data(), old_stream);
Array<u1>* old_table = ik->fieldinfo_search_table();
Array<u1>* search_table = FieldInfoStream::create_search_table(ik->constants(), new_fis, k->class_loader_data(), CHECK);
ik->set_fieldinfo_search_table(search_table);
MetadataFactory::free_array<u1>(k->class_loader_data(), old_table);
DEBUG_ONLY(FieldInfoStream::validate_search_table(ik->constants(), new_fis, search_table));
}
}

View File

@@ -32,6 +32,7 @@
#include "classfile/javaClasses.inline.hpp"
#include "classfile/stringTable.hpp"
#include "classfile/vmClasses.hpp"
#include "compiler/compileBroker.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "gc/shared/oopStorage.inline.hpp"
#include "gc/shared/oopStorageSet.hpp"
@@ -115,6 +116,7 @@ OopStorage* StringTable::_oop_storage;
static size_t _current_size = 0;
static volatile size_t _items_count = 0;
DEBUG_ONLY(static bool _disable_interning_during_cds_dump = false);
volatile bool _alt_hash = false;
@@ -346,6 +348,10 @@ bool StringTable::has_work() {
return Atomic::load_acquire(&_has_work);
}
size_t StringTable::items_count_acquire() {
return Atomic::load_acquire(&_items_count);
}
void StringTable::trigger_concurrent_work() {
// Avoid churn on ServiceThread
if (!has_work()) {
@@ -504,6 +510,9 @@ oop StringTable::intern(const char* utf8_string, TRAPS) {
}
oop StringTable::intern(const StringWrapper& name, TRAPS) {
assert(!Atomic::load_acquire(&_disable_interning_during_cds_dump),
"All threads that may intern strings should have been stopped before CDS starts copying the interned string table");
// shared table always uses java_lang_String::hash_code
unsigned int hash = hash_wrapped_string(name);
oop found_string = lookup_shared(name, hash);
@@ -793,7 +802,7 @@ void StringTable::verify() {
}
// Verification and comp
class VerifyCompStrings : StackObj {
class StringTable::VerifyCompStrings : StackObj {
static unsigned string_hash(oop const& str) {
return java_lang_String::hash_code_noupdate(str);
}
@@ -805,7 +814,7 @@ class VerifyCompStrings : StackObj {
string_hash, string_equals> _table;
public:
size_t _errors;
VerifyCompStrings() : _table(unsigned(_items_count / 8) + 1, 0 /* do not resize */), _errors(0) {}
VerifyCompStrings() : _table(unsigned(items_count_acquire() / 8) + 1, 0 /* do not resize */), _errors(0) {}
bool operator()(WeakHandle* val) {
oop s = val->resolve();
if (s == nullptr) {
@@ -939,20 +948,31 @@ oop StringTable::lookup_shared(const jchar* name, int len) {
return _shared_table.lookup(wrapped_name, java_lang_String::hash_code(name, len), 0);
}
// This is called BEFORE we enter the CDS safepoint. We can allocate heap objects.
// This should be called when we know no more strings will be added (which will be easy
// to guarantee because CDS runs with a single Java thread. See JDK-8253495.)
// This is called BEFORE we enter the CDS safepoint. We can still allocate Java object arrays to
// be used by the shared strings table.
void StringTable::allocate_shared_strings_array(TRAPS) {
if (!CDSConfig::is_dumping_heap()) {
return;
}
assert(CDSConfig::allow_only_single_java_thread(), "No more interned strings can be added");
if (_items_count > (size_t)max_jint) {
fatal("Too many strings to be archived: %zu", _items_count);
CompileBroker::wait_for_no_active_tasks();
precond(CDSConfig::allow_only_single_java_thread());
// At this point, no more strings will be added:
// - There's only a single Java thread (this thread). It no longer executes Java bytecodes
// so JIT compilation will eventually stop.
// - CompileBroker has no more active tasks, so all JIT requests have been processed.
// This flag will be cleared after intern table dumping has completed, so we can run the
// compiler again (for future AOT method compilation, etc).
DEBUG_ONLY(Atomic::release_store(&_disable_interning_during_cds_dump, true));
if (items_count_acquire() > (size_t)max_jint) {
fatal("Too many strings to be archived: %zu", items_count_acquire());
}
int total = (int)_items_count;
int total = (int)items_count_acquire();
size_t single_array_size = objArrayOopDesc::object_size(total);
log_info(aot)("allocated string table for %d strings", total);
@@ -972,7 +992,7 @@ void StringTable::allocate_shared_strings_array(TRAPS) {
// This can only happen if you have an extremely large number of classes that
// refer to more than 16384 * 16384 = 26M interned strings! Not a practical concern
// but bail out for safety.
log_error(aot)("Too many strings to be archived: %zu", _items_count);
log_error(aot)("Too many strings to be archived: %zu", items_count_acquire());
MetaspaceShared::unrecoverable_writing_error();
}
@@ -1070,7 +1090,7 @@ oop StringTable::init_shared_strings_array() {
void StringTable::write_shared_table() {
_shared_table.reset();
CompactHashtableWriter writer((int)_items_count, ArchiveBuilder::string_stats());
CompactHashtableWriter writer((int)items_count_acquire(), ArchiveBuilder::string_stats());
int index = 0;
auto copy_into_shared_table = [&] (WeakHandle* val) {
@@ -1084,6 +1104,8 @@ void StringTable::write_shared_table() {
};
_local_table->do_safepoint_scan(copy_into_shared_table);
writer.dump(&_shared_table, "string");
DEBUG_ONLY(Atomic::release_store(&_disable_interning_during_cds_dump, false));
}
void StringTable::set_shared_strings_array_index(int root_index) {

View File

@@ -40,7 +40,7 @@ class StringTableConfig;
class StringTable : AllStatic {
friend class StringTableConfig;
class VerifyCompStrings;
static volatile bool _has_work;
// Set if one bucket is out of balance due to hash algorithm deficiency
@@ -74,6 +74,7 @@ private:
static void item_added();
static void item_removed();
static size_t items_count_acquire();
static oop intern(const StringWrapper& name, TRAPS);
static oop do_intern(const StringWrapper& name, uintx hash, TRAPS);

View File

@@ -344,6 +344,7 @@ AOTCodeCache::~AOTCodeCache() {
_store_buffer = nullptr;
}
if (_table != nullptr) {
MutexLocker ml(AOTCodeCStrings_lock, Mutex::_no_safepoint_check_flag);
delete _table;
_table = nullptr;
}
@@ -774,6 +775,9 @@ bool AOTCodeCache::store_code_blob(CodeBlob& blob, AOTCodeEntry::Kind entry_kind
// we need to take a lock to prevent race between compiler threads generating AOT code
// and the main thread generating adapter
MutexLocker ml(Compile_lock);
if (!is_on()) {
return false; // AOT code cache was already dumped and closed.
}
if (!cache->align_write()) {
return false;
}
@@ -1434,6 +1438,9 @@ AOTCodeAddressTable::~AOTCodeAddressTable() {
if (_extrs_addr != nullptr) {
FREE_C_HEAP_ARRAY(address, _extrs_addr);
}
if (_stubs_addr != nullptr) {
FREE_C_HEAP_ARRAY(address, _stubs_addr);
}
if (_shared_blobs_addr != nullptr) {
FREE_C_HEAP_ARRAY(address, _shared_blobs_addr);
}
@@ -1485,6 +1492,7 @@ void AOTCodeCache::load_strings() {
int AOTCodeCache::store_strings() {
if (_C_strings_used > 0) {
MutexLocker ml(AOTCodeCStrings_lock, Mutex::_no_safepoint_check_flag);
uint offset = _write_position;
uint length = 0;
uint* lengths = (uint *)reserve_bytes(sizeof(uint) * _C_strings_used);
@@ -1510,15 +1518,17 @@ int AOTCodeCache::store_strings() {
const char* AOTCodeCache::add_C_string(const char* str) {
if (is_on_for_dump() && str != nullptr) {
return _cache->_table->add_C_string(str);
MutexLocker ml(AOTCodeCStrings_lock, Mutex::_no_safepoint_check_flag);
AOTCodeAddressTable* table = addr_table();
if (table != nullptr) {
return table->add_C_string(str);
}
}
return str;
}
const char* AOTCodeAddressTable::add_C_string(const char* str) {
if (_extrs_complete) {
LogStreamHandle(Trace, aot, codecache, stringtable) log; // ctor outside lock
MutexLocker ml(AOTCodeCStrings_lock, Mutex::_no_safepoint_check_flag);
// Check previous strings address
for (int i = 0; i < _C_strings_count; i++) {
if (_C_strings_in[i] == str) {
@@ -1535,9 +1545,7 @@ const char* AOTCodeAddressTable::add_C_string(const char* str) {
_C_strings_in[_C_strings_count] = str;
const char* dup = os::strdup(str);
_C_strings[_C_strings_count++] = dup;
if (log.is_enabled()) {
log.print_cr("add_C_string: [%d] " INTPTR_FORMAT " '%s'", _C_strings_count, p2i(dup), dup);
}
log_trace(aot, codecache, stringtable)("add_C_string: [%d] " INTPTR_FORMAT " '%s'", _C_strings_count, p2i(dup), dup);
return dup;
} else {
assert(false, "Number of C strings >= MAX_STR_COUNT");

View File

@@ -136,6 +136,7 @@ private:
public:
AOTCodeAddressTable() :
_extrs_addr(nullptr),
_stubs_addr(nullptr),
_shared_blobs_addr(nullptr),
_C1_blobs_addr(nullptr),
_extrs_length(0),

View File

@@ -28,7 +28,6 @@
#include "code/dependencies.hpp"
#include "code/nativeInst.hpp"
#include "code/nmethod.inline.hpp"
#include "code/relocInfo.hpp"
#include "code/scopeDesc.hpp"
#include "compiler/abstractCompiler.hpp"
#include "compiler/compilationLog.hpp"
@@ -1653,10 +1652,6 @@ void nmethod::maybe_print_nmethod(const DirectiveSet* directive) {
}
void nmethod::print_nmethod(bool printmethod) {
// Enter a critical section to prevent a race with deopts that patch code and updates the relocation info.
// Unfortunately, we have to lock the NMethodState_lock before the tty lock due to the deadlock rules and
// cannot lock in a more finely grained manner.
ConditionalMutexLocker ml(NMethodState_lock, !NMethodState_lock->owned_by_self(), Mutex::_no_safepoint_check_flag);
ttyLocker ttyl; // keep the following output all in one block
if (xtty != nullptr) {
xtty->begin_head("print_nmethod");
@@ -2046,17 +2041,6 @@ bool nmethod::make_not_entrant(const char* reason) {
// cache call.
NativeJump::patch_verified_entry(entry_point(), verified_entry_point(),
SharedRuntime::get_handle_wrong_method_stub());
// Update the relocation info for the patched entry.
// First, get the old relocation info...
RelocIterator iter(this, verified_entry_point(), verified_entry_point() + 8);
if (iter.next() && iter.addr() == verified_entry_point()) {
Relocation* old_reloc = iter.reloc();
// ...then reset the iterator to update it.
RelocIterator iter(this, verified_entry_point(), verified_entry_point() + 8);
relocInfo::change_reloc_info_for_address(&iter, verified_entry_point(), old_reloc->type(),
relocInfo::relocType::runtime_call_type);
}
}
if (update_recompile_counts()) {

View File

@@ -1750,6 +1750,10 @@ void CompileBroker::wait_for_completion(CompileTask* task) {
}
}
void CompileBroker::wait_for_no_active_tasks() {
CompileTask::wait_for_no_active_tasks();
}
/**
* Initialize compiler thread(s) + compiler object(s). The postcondition
* of this function is that the compiler runtimes are initialized and that

View File

@@ -383,6 +383,9 @@ public:
static bool is_compilation_disabled_forever() {
return _should_compile_new_jobs == shutdown_compilation;
}
static void wait_for_no_active_tasks();
static void handle_full_code_cache(CodeBlobType code_blob_type);
// Ensures that warning is only printed once.
static bool should_print_compiler_warning() {

View File

@@ -37,12 +37,13 @@
#include "runtime/mutexLocker.hpp"
CompileTask* CompileTask::_task_free_list = nullptr;
int CompileTask::_active_tasks = 0;
/**
* Allocate a CompileTask, from the free list if possible.
*/
CompileTask* CompileTask::allocate() {
MutexLocker locker(CompileTaskAlloc_lock);
MonitorLocker locker(CompileTaskAlloc_lock);
CompileTask* task = nullptr;
if (_task_free_list != nullptr) {
@@ -56,6 +57,7 @@ CompileTask* CompileTask::allocate() {
}
assert(task->is_free(), "Task must be free.");
task->set_is_free(false);
_active_tasks++;
return task;
}
@@ -63,7 +65,7 @@ CompileTask* CompileTask::allocate() {
* Add a task to the free list.
*/
void CompileTask::free(CompileTask* task) {
MutexLocker locker(CompileTaskAlloc_lock);
MonitorLocker locker(CompileTaskAlloc_lock);
if (!task->is_free()) {
if ((task->_method_holder != nullptr && JNIHandles::is_weak_global_handle(task->_method_holder))) {
JNIHandles::destroy_weak_global(task->_method_holder);
@@ -79,6 +81,17 @@ void CompileTask::free(CompileTask* task) {
task->set_is_free(true);
task->set_next(_task_free_list);
_task_free_list = task;
_active_tasks--;
if (_active_tasks == 0) {
locker.notify_all();
}
}
}
void CompileTask::wait_for_no_active_tasks() {
MonitorLocker locker(CompileTaskAlloc_lock);
while (_active_tasks > 0) {
locker.wait();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 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
@@ -83,6 +83,7 @@ class CompileTask : public CHeapObj<mtCompiler> {
private:
static CompileTask* _task_free_list;
static int _active_tasks;
int _compile_id;
Method* _method;
jobject _method_holder;
@@ -123,6 +124,7 @@ class CompileTask : public CHeapObj<mtCompiler> {
static CompileTask* allocate();
static void free(CompileTask* task);
static void wait_for_no_active_tasks();
int compile_id() const { return _compile_id; }
Method* method() const { return _method; }

View File

@@ -625,6 +625,34 @@ void ShenandoahBarrierC2Support::verify(RootNode* root) {
}
#endif
bool ShenandoahBarrierC2Support::is_anti_dependent_load_at_control(PhaseIdealLoop* phase, Node* maybe_load, Node* store,
Node* control) {
return maybe_load->is_Load() && phase->C->can_alias(store->adr_type(), phase->C->get_alias_index(maybe_load->adr_type())) &&
phase->ctrl_or_self(maybe_load) == control;
}
void ShenandoahBarrierC2Support::maybe_push_anti_dependent_loads(PhaseIdealLoop* phase, Node* maybe_store, Node* control, Unique_Node_List &wq) {
if (!maybe_store->is_Store() && !maybe_store->is_LoadStore()) {
return;
}
Node* mem = maybe_store->in(MemNode::Memory);
for (DUIterator_Fast imax, i = mem->fast_outs(imax); i < imax; i++) {
Node* u = mem->fast_out(i);
if (is_anti_dependent_load_at_control(phase, u, maybe_store, control)) {
wq.push(u);
}
}
}
void ShenandoahBarrierC2Support::push_data_inputs_at_control(PhaseIdealLoop* phase, Node* n, Node* ctrl, Unique_Node_List &wq) {
for (uint i = 0; i < n->req(); i++) {
Node* in = n->in(i);
if (in != nullptr && phase->has_ctrl(in) && phase->get_ctrl(in) == ctrl) {
wq.push(in);
}
}
}
bool ShenandoahBarrierC2Support::is_dominator_same_ctrl(Node* c, Node* d, Node* n, PhaseIdealLoop* phase) {
// That both nodes have the same control is not sufficient to prove
// domination, verify that there's no path from d to n
@@ -639,22 +667,9 @@ bool ShenandoahBarrierC2Support::is_dominator_same_ctrl(Node* c, Node* d, Node*
if (m->is_Phi() && m->in(0)->is_Loop()) {
assert(phase->ctrl_or_self(m->in(LoopNode::EntryControl)) != c, "following loop entry should lead to new control");
} else {
if (m->is_Store() || m->is_LoadStore()) {
// Take anti-dependencies into account
Node* mem = m->in(MemNode::Memory);
for (DUIterator_Fast imax, i = mem->fast_outs(imax); i < imax; i++) {
Node* u = mem->fast_out(i);
if (u->is_Load() && phase->C->can_alias(m->adr_type(), phase->C->get_alias_index(u->adr_type())) &&
phase->ctrl_or_self(u) == c) {
wq.push(u);
}
}
}
for (uint i = 0; i < m->req(); i++) {
if (m->in(i) != nullptr && phase->ctrl_or_self(m->in(i)) == c) {
wq.push(m->in(i));
}
}
// Take anti-dependencies into account
maybe_push_anti_dependent_loads(phase, m, c, wq);
push_data_inputs_at_control(phase, m, c, wq);
}
}
return true;
@@ -1006,7 +1021,20 @@ void ShenandoahBarrierC2Support::call_lrb_stub(Node*& ctrl, Node*& val, Node* lo
phase->register_new_node(val, ctrl);
}
void ShenandoahBarrierC2Support::fix_ctrl(Node* barrier, Node* region, const MemoryGraphFixer& fixer, Unique_Node_List& uses, Unique_Node_List& uses_to_ignore, uint last, PhaseIdealLoop* phase) {
void ShenandoahBarrierC2Support::collect_nodes_above_barrier(Unique_Node_List &nodes_above_barrier, PhaseIdealLoop* phase, Node* ctrl, Node* init_raw_mem) {
nodes_above_barrier.clear();
if (phase->has_ctrl(init_raw_mem) && phase->get_ctrl(init_raw_mem) == ctrl && !init_raw_mem->is_Phi()) {
nodes_above_barrier.push(init_raw_mem);
}
for (uint next = 0; next < nodes_above_barrier.size(); next++) {
Node* n = nodes_above_barrier.at(next);
// Take anti-dependencies into account
maybe_push_anti_dependent_loads(phase, n, ctrl, nodes_above_barrier);
push_data_inputs_at_control(phase, n, ctrl, nodes_above_barrier);
}
}
void ShenandoahBarrierC2Support::fix_ctrl(Node* barrier, Node* region, const MemoryGraphFixer& fixer, Unique_Node_List& uses, Unique_Node_List& nodes_above_barrier, uint last, PhaseIdealLoop* phase) {
Node* ctrl = phase->get_ctrl(barrier);
Node* init_raw_mem = fixer.find_mem(ctrl, barrier);
@@ -1017,30 +1045,17 @@ void ShenandoahBarrierC2Support::fix_ctrl(Node* barrier, Node* region, const Mem
// control will be after the expanded barrier. The raw memory (if
// its memory is control dependent on the barrier's input control)
// must stay above the barrier.
uses_to_ignore.clear();
if (phase->has_ctrl(init_raw_mem) && phase->get_ctrl(init_raw_mem) == ctrl && !init_raw_mem->is_Phi()) {
uses_to_ignore.push(init_raw_mem);
}
for (uint next = 0; next < uses_to_ignore.size(); next++) {
Node *n = uses_to_ignore.at(next);
for (uint i = 0; i < n->req(); i++) {
Node* in = n->in(i);
if (in != nullptr && phase->has_ctrl(in) && phase->get_ctrl(in) == ctrl) {
uses_to_ignore.push(in);
}
}
}
collect_nodes_above_barrier(nodes_above_barrier, phase, ctrl, init_raw_mem);
for (DUIterator_Fast imax, i = ctrl->fast_outs(imax); i < imax; i++) {
Node* u = ctrl->fast_out(i);
if (u->_idx < last &&
u != barrier &&
!u->depends_only_on_test() && // preserve dependency on test
!uses_to_ignore.member(u) &&
!nodes_above_barrier.member(u) &&
(u->in(0) != ctrl || (!u->is_Region() && !u->is_Phi())) &&
(ctrl->Opcode() != Op_CatchProj || u->Opcode() != Op_CreateEx)) {
Node* old_c = phase->ctrl_or_self(u);
Node* c = old_c;
if (c != ctrl ||
if (old_c != ctrl ||
is_dominator_same_ctrl(old_c, barrier, u, phase) ||
ShenandoahBarrierSetC2::is_shenandoah_state_load(u)) {
phase->igvn().rehash_node_delayed(u);
@@ -1315,7 +1330,7 @@ void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) {
// Expand load-reference-barriers
MemoryGraphFixer fixer(Compile::AliasIdxRaw, true, phase);
Unique_Node_List uses_to_ignore;
Unique_Node_List nodes_above_barriers;
for (int i = state->load_reference_barriers_count() - 1; i >= 0; i--) {
ShenandoahLoadReferenceBarrierNode* lrb = state->load_reference_barrier(i);
uint last = phase->C->unique();
@@ -1410,7 +1425,7 @@ void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) {
Node* out_val = val_phi;
phase->register_new_node(val_phi, region);
fix_ctrl(lrb, region, fixer, uses, uses_to_ignore, last, phase);
fix_ctrl(lrb, region, fixer, uses, nodes_above_barriers, last, phase);
ctrl = orig_ctrl;

View File

@@ -62,8 +62,12 @@ private:
PhaseIdealLoop* phase, int flags);
static void call_lrb_stub(Node*& ctrl, Node*& val, Node* load_addr,
DecoratorSet decorators, PhaseIdealLoop* phase);
static void collect_nodes_above_barrier(Unique_Node_List &nodes_above_barrier, PhaseIdealLoop* phase, Node* ctrl,
Node* init_raw_mem);
static void test_in_cset(Node*& ctrl, Node*& not_cset_ctrl, Node* val, Node* raw_mem, PhaseIdealLoop* phase);
static void fix_ctrl(Node* barrier, Node* region, const MemoryGraphFixer& fixer, Unique_Node_List& uses, Unique_Node_List& uses_to_ignore, uint last, PhaseIdealLoop* phase);
static void fix_ctrl(Node* barrier, Node* region, const MemoryGraphFixer& fixer, Unique_Node_List& uses, Unique_Node_List& nodes_above_barrier, uint last, PhaseIdealLoop* phase);
static Node* get_load_addr(PhaseIdealLoop* phase, VectorSet& visited, Node* lrb);
public:
@@ -76,6 +80,11 @@ public:
static bool expand(Compile* C, PhaseIterGVN& igvn);
static void pin_and_expand(PhaseIdealLoop* phase);
static void push_data_inputs_at_control(PhaseIdealLoop* phase, Node* n, Node* ctrl,
Unique_Node_List &wq);
static bool is_anti_dependent_load_at_control(PhaseIdealLoop* phase, Node* maybe_load, Node* store, Node* control);
static void maybe_push_anti_dependent_loads(PhaseIdealLoop* phase, Node* maybe_store, Node* control, Unique_Node_List &wq);
#ifdef ASSERT
static void verify(RootNode* root);
#endif

View File

@@ -183,6 +183,29 @@ void ShenandoahGenerationalHeap::stop() {
regulator_thread()->stop();
}
bool ShenandoahGenerationalHeap::requires_barriers(stackChunkOop obj) const {
if (is_idle()) {
return false;
}
if (is_concurrent_young_mark_in_progress() && is_in_young(obj) && !marking_context()->allocated_after_mark_start(obj)) {
// We are marking young, this object is in young, and it is below the TAMS
return true;
}
if (is_in_old(obj)) {
// Card marking barriers are required for objects in the old generation
return true;
}
if (has_forwarded_objects()) {
// Object may have pointers that need to be updated
return true;
}
return false;
}
void ShenandoahGenerationalHeap::evacuate_collection_set(bool concurrent) {
ShenandoahRegionIterator regions;
ShenandoahGenerationalEvacuationTask task(this, &regions, concurrent, false /* only promote regions */);

View File

@@ -128,6 +128,8 @@ public:
void stop() override;
bool requires_barriers(stackChunkOop obj) const override;
// Used for logging the result of a region transfer outside the heap lock
struct TransferResult {
bool success;

View File

@@ -948,22 +948,24 @@
<Field type="long" contentType="bytes" name="freeSize" label="Free Size" description="Free swap space" />
</Event>
<Event name="ExecutionSample" category="Java Virtual Machine, Profiling" label="Method Profiling Sample" description="Snapshot of a threads state"
<Event name="ExecutionSample" category="Java Virtual Machine, Profiling" label="Java Execution Sample"
description="Snapshot of a thread executing Java code. Threads that are not executing Java code, including those waiting or executing native code, are not included."
period="everyChunk">
<Field type="Thread" name="sampledThread" label="Thread" />
<Field type="StackTrace" name="stackTrace" label="Stack Trace" />
<Field type="ThreadState" name="state" label="Thread State" />
</Event>
<Event name="NativeMethodSample" category="Java Virtual Machine, Profiling" label="Method Profiling Sample Native" description="Snapshot of a threads state when in native"
<Event name="NativeMethodSample" category="Java Virtual Machine, Profiling" label="Native Sample"
description="Snapshot of a thread in native code, executing or waiting. Threads that are executing Java code are not included."
period="everyChunk">
<Field type="Thread" name="sampledThread" label="Thread" />
<Field type="StackTrace" name="stackTrace" label="Stack Trace" />
<Field type="ThreadState" name="state" label="Thread State" />
</Event>
<Event name="CPUTimeSample" category="Java Virtual Machine, Profiling" label="CPU Time Method Sample"
description="Snapshot of a threads state from the CPU time sampler. The throttle can be either an upper bound for the event emission rate, e.g. 100/s, or the cpu-time period, e.g. 10ms, with s, ms, us and ns supported as time units."
<Event name="CPUTimeSample" category="Java Virtual Machine, Profiling" label="CPU Time Sample"
description="Snapshot of a threads state from the CPU time sampler, both threads executing native and Java code are included. The throttle setting can be either an upper bound for the event emission rate, e.g. 100/s, or the cpu-time period, e.g. 10ms, with s, ms, us and ns supported as time units."
throttle="true" thread="false" experimental="true" startTime="false">
<Field type="StackTrace" name="stackTrace" label="Stack Trace" />
<Field type="Thread" name="eventThread" label="Thread" />
@@ -972,7 +974,7 @@
<Field type="boolean" name="biased" label="Biased" description="The sample is safepoint-biased" />
</Event>
<Event name="CPUTimeSamplesLost" category="Java Virtual Machine, Profiling" label="CPU Time Method Profiling Lost Samples" description="Records that the CPU time sampler lost samples"
<Event name="CPUTimeSamplesLost" category="Java Virtual Machine, Profiling" label="CPU Time Samples Lost" description="Records that the CPU time sampler lost samples"
thread="false" stackTrace="false" startTime="false" experimental="true">
<Field type="int" name="lostSamples" label="Lost Samples" />
<Field type="Thread" name="eventThread" label="Thread" />

View File

@@ -79,7 +79,8 @@ JfrThreadLocal::JfrThreadLocal() :
_enqueued_requests(false),
_vthread(false),
_notified(false),
_dead(false)
_dead(false),
_sampling_critical_section(false)
#ifdef LINUX
,_cpu_timer(nullptr),
_cpu_time_jfr_locked(UNLOCKED),

View File

@@ -47,7 +47,6 @@ void VectorSet::init(Arena* arena) {
// Expand the existing set to a bigger size
void VectorSet::grow(uint new_word_capacity) {
_nesting.check(_set_arena); // Check if a potential reallocation in the arena is safe
assert(new_word_capacity >= _size, "Should have been checked before, use maybe_grow?");
assert(new_word_capacity < (1U << 30), "");
uint x = next_power_of_2(new_word_capacity);

View File

@@ -52,6 +52,7 @@ private:
// Grow vector to required word capacity
void maybe_grow(uint new_word_capacity) {
_nesting.check(_set_arena); // Check if a potential reallocation in the arena is safe
if (new_word_capacity >= _size) {
grow(new_word_capacity);
}

View File

@@ -22,8 +22,11 @@
*
*/
#include "memory/resourceArea.hpp"
#include "cds/cdsConfig.hpp"
#include "oops/fieldInfo.inline.hpp"
#include "runtime/atomic.hpp"
#include "utilities/packedTable.hpp"
void FieldInfo::print(outputStream* os, ConstantPool* cp) {
os->print_cr("index=%d name_index=%d name=%s signature_index=%d signature=%s offset=%d "
@@ -37,8 +40,10 @@ void FieldInfo::print(outputStream* os, ConstantPool* cp) {
field_flags().as_uint(),
initializer_index(),
generic_signature_index(),
_field_flags.is_injected() ? lookup_symbol(generic_signature_index())->as_utf8() : cp->symbol_at(generic_signature_index())->as_utf8(),
contended_group());
_field_flags.is_generic() ? (_field_flags.is_injected() ?
lookup_symbol(generic_signature_index())->as_utf8() : cp->symbol_at(generic_signature_index())->as_utf8()
) : "",
is_contended() ? contended_group() : 0);
}
void FieldInfo::print_from_growable_array(outputStream* os, GrowableArray<FieldInfo>* array, ConstantPool* cp) {
@@ -62,13 +67,17 @@ Array<u1>* FieldInfoStream::create_FieldInfoStream(GrowableArray<FieldInfo>* fie
StreamSizer s;
StreamFieldSizer sizer(&s);
assert(fields->length() == java_fields + injected_fields, "must be");
sizer.consumer()->accept_uint(java_fields);
sizer.consumer()->accept_uint(injected_fields);
for (int i = 0; i < fields->length(); i++) {
FieldInfo* fi = fields->adr_at(i);
sizer.map_field_info(*fi);
}
int storage_size = sizer.consumer()->position() + 1;
// Originally there was an extra byte with 0 terminating the reading;
// now we check limits instead.
int storage_size = sizer.consumer()->position();
Array<u1>* const fis = MetadataFactory::new_array<u1>(loader_data, storage_size, CHECK_NULL);
using StreamWriter = UNSIGNED5::Writer<Array<u1>*, int, ArrayHelper<Array<u1>*, int>>;
@@ -79,15 +88,14 @@ Array<u1>* FieldInfoStream::create_FieldInfoStream(GrowableArray<FieldInfo>* fie
writer.consumer()->accept_uint(java_fields);
writer.consumer()->accept_uint(injected_fields);
for (int i = 0; i < fields->length(); i++) {
FieldInfo* fi = fields->adr_at(i);
writer.map_field_info(*fi);
writer.map_field_info(fields->at(i));
}
#ifdef ASSERT
FieldInfoReader r(fis);
int jfc = r.next_uint();
int jfc, ifc;
r.read_field_counts(&jfc, &ifc);
assert(jfc == java_fields, "Must be");
int ifc = r.next_uint();
assert(ifc == injected_fields, "Must be");
for (int i = 0; i < jfc + ifc; i++) {
FieldInfo fi;
@@ -113,30 +121,221 @@ Array<u1>* FieldInfoStream::create_FieldInfoStream(GrowableArray<FieldInfo>* fie
return fis;
}
GrowableArray<FieldInfo>* FieldInfoStream::create_FieldInfoArray(const Array<u1>* fis, int* java_fields_count, int* injected_fields_count) {
int length = FieldInfoStream::num_total_fields(fis);
GrowableArray<FieldInfo>* array = new GrowableArray<FieldInfo>(length);
int FieldInfoStream::compare_name_and_sig(const Symbol* n1, const Symbol* s1, const Symbol* n2, const Symbol* s2) {
int cmp = n1->fast_compare(n2);
return cmp != 0 ? cmp : s1->fast_compare(s2);
}
// We use both name and signature during the comparison; while JLS require unique
// names for fields, JVMS requires only unique name + signature combination.
struct field_pos {
Symbol* _name;
Symbol* _signature;
int _index;
int _position;
};
class FieldInfoSupplier: public PackedTableBuilder::Supplier {
const field_pos* _positions;
size_t _elements;
public:
FieldInfoSupplier(const field_pos* positions, size_t elements): _positions(positions), _elements(elements) {}
bool next(uint32_t* key, uint32_t* value) override {
if (_elements == 0) {
return false;
}
*key = _positions->_position;
*value = _positions->_index;
++_positions;
--_elements;
return true;
}
};
Array<u1>* FieldInfoStream::create_search_table(ConstantPool* cp, const Array<u1>* fis, ClassLoaderData* loader_data, TRAPS) {
if (CDSConfig::is_dumping_dynamic_archive()) {
// We cannot use search table; in case of dynamic archives it should be sorted by "requested" addresses,
// but Symbol* addresses are coming from _constants, which has "buffered" addresses.
// For background, see new comments inside allocate_node_impl in symbolTable.cpp
return nullptr;
}
FieldInfoReader r(fis);
*java_fields_count = r.next_uint();
*injected_fields_count = r.next_uint();
int java_fields;
int injected_fields;
r.read_field_counts(&java_fields, &injected_fields);
assert(java_fields >= 0, "must be");
if (java_fields == 0 || fis->length() == 0 || static_cast<uint>(java_fields) < BinarySearchThreshold) {
return nullptr;
}
ResourceMark rm;
field_pos* positions = NEW_RESOURCE_ARRAY(field_pos, java_fields);
for (int i = 0; i < java_fields; ++i) {
assert(r.has_next(), "number of fields must match");
positions[i]._position = r.position();
FieldInfo fi;
r.read_field_info(fi);
positions[i]._name = fi.name(cp);
positions[i]._signature = fi.signature(cp);
positions[i]._index = i;
}
auto compare_pair = [](const void* v1, const void* v2) {
const field_pos* p1 = reinterpret_cast<const field_pos*>(v1);
const field_pos* p2 = reinterpret_cast<const field_pos*>(v2);
return compare_name_and_sig(p1->_name, p1->_signature, p2->_name, p2->_signature);
};
qsort(positions, java_fields, sizeof(field_pos), compare_pair);
PackedTableBuilder builder(fis->length() - 1, java_fields - 1);
Array<u1>* table = MetadataFactory::new_array<u1>(loader_data, java_fields * builder.element_bytes(), CHECK_NULL);
FieldInfoSupplier supplier(positions, java_fields);
builder.fill(table->data(), static_cast<size_t>(table->length()), supplier);
return table;
}
GrowableArray<FieldInfo>* FieldInfoStream::create_FieldInfoArray(const Array<u1>* fis, int* java_fields_count, int* injected_fields_count) {
FieldInfoReader r(fis);
r.read_field_counts(java_fields_count, injected_fields_count);
int length = *java_fields_count + *injected_fields_count;
GrowableArray<FieldInfo>* array = new GrowableArray<FieldInfo>(length);
while (r.has_next()) {
FieldInfo fi;
r.read_field_info(fi);
array->append(fi);
}
assert(array->length() == length, "Must be");
assert(array->length() == *java_fields_count + *injected_fields_count, "Must be");
return array;
}
void FieldInfoStream::print_from_fieldinfo_stream(Array<u1>* fis, outputStream* os, ConstantPool* cp) {
int length = FieldInfoStream::num_total_fields(fis);
FieldInfoReader r(fis);
int java_field_count = r.next_uint();
int injected_fields_count = r.next_uint();
int java_fields_count;
int injected_fields_count;
r.read_field_counts(&java_fields_count, &injected_fields_count);
while (r.has_next()) {
FieldInfo fi;
r.read_field_info(fi);
fi.print(os, cp);
}
}
class FieldInfoComparator: public PackedTableLookup::Comparator {
const FieldInfoReader* _reader;
ConstantPool* _cp;
const Symbol* _name;
const Symbol* _signature;
public:
FieldInfoComparator(const FieldInfoReader* reader, ConstantPool* cp, const Symbol* name, const Symbol* signature):
_reader(reader), _cp(cp), _name(name), _signature(signature) {}
int compare_to(uint32_t position) override {
FieldInfoReader r2(*_reader);
r2.set_position_and_next_index(position, -1);
u2 name_index, sig_index;
r2.read_name_and_signature(&name_index, &sig_index);
Symbol* mid_name = _cp->symbol_at(name_index);
Symbol* mid_sig = _cp->symbol_at(sig_index);
return FieldInfoStream::compare_name_and_sig(_name, _signature, mid_name, mid_sig);
}
#ifdef ASSERT
void reset(uint32_t position) override {
FieldInfoReader r2(*_reader);
r2.set_position_and_next_index(position, -1);
u2 name_index, signature_index;
r2.read_name_and_signature(&name_index, &signature_index);
_name = _cp->symbol_at(name_index);
_signature = _cp->symbol_at(signature_index);
}
#endif // ASSERT
};
#ifdef ASSERT
void FieldInfoStream::validate_search_table(ConstantPool* cp, const Array<u1>* fis, const Array<u1>* search_table) {
if (search_table == nullptr) {
return;
}
FieldInfoReader reader(fis);
int java_fields, injected_fields;
reader.read_field_counts(&java_fields, &injected_fields);
assert(java_fields > 0, "must be");
PackedTableLookup lookup(fis->length() - 1, java_fields - 1, search_table);
assert(lookup.element_bytes() * java_fields == static_cast<unsigned int>(search_table->length()), "size does not match");
FieldInfoComparator comparator(&reader, cp, nullptr, nullptr);
// Check 1: assert that elements have the correct order based on the comparison function
lookup.validate_order(comparator);
// Check 2: Iterate through the original stream (not just search_table) and try if lookup works as expected
reader.set_position_and_next_index(0, 0);
reader.read_field_counts(&java_fields, &injected_fields);
while (reader.has_next()) {
int field_start = reader.position();
FieldInfo fi;
reader.read_field_info(fi);
if (fi.field_flags().is_injected()) {
// checking only java fields that precede injected ones
break;
}
FieldInfoReader r2(fis);
int index = r2.search_table_lookup(search_table, fi.name(cp), fi.signature(cp), cp, java_fields);
assert(index == static_cast<int>(fi.index()), "wrong index: %d != %u", index, fi.index());
assert(index == r2.next_index(), "index should match");
assert(field_start == r2.position(), "must find the same position");
}
}
#endif // ASSERT
void FieldInfoStream::print_search_table(outputStream* st, ConstantPool* cp, const Array<u1>* fis, const Array<u1>* search_table) {
if (search_table == nullptr) {
return;
}
FieldInfoReader reader(fis);
int java_fields, injected_fields;
reader.read_field_counts(&java_fields, &injected_fields);
assert(java_fields > 0, "must be");
PackedTableLookup lookup(fis->length() - 1, java_fields - 1, search_table);
auto printer = [&] (size_t offset, uint32_t position, uint32_t index) {
reader.set_position_and_next_index(position, -1);
u2 name_index, sig_index;
reader.read_name_and_signature(&name_index, &sig_index);
Symbol* name = cp->symbol_at(name_index);
Symbol* sig = cp->symbol_at(sig_index);
st->print(" [%zu] #%d,#%d = ", offset, name_index, sig_index);
name->print_symbol_on(st);
st->print(":");
sig->print_symbol_on(st);
st->print(" @ %p,%p", name, sig);
st->cr();
};
lookup.iterate(printer);
}
int FieldInfoReader::search_table_lookup(const Array<u1>* search_table, const Symbol* name, const Symbol* signature, ConstantPool* cp, int java_fields) {
assert(java_fields >= 0, "must be");
if (java_fields == 0) {
return -1;
}
FieldInfoComparator comp(this, cp, name, signature);
PackedTableLookup lookup(_r.limit() - 1, java_fields - 1, search_table);
uint32_t position;
static_assert(sizeof(uint32_t) == sizeof(_next_index), "field size assert");
if (lookup.search(comp, &position, reinterpret_cast<uint32_t*>(&_next_index))) {
_r.set_position(static_cast<int>(position));
return _next_index;
} else {
return -1;
}
}

View File

@@ -222,29 +222,28 @@ public:
void map_field_info(const FieldInfo& fi);
};
// Gadget for decoding and reading the stream of field records.
class FieldInfoReader {
friend class FieldInfoStream;
friend class ClassFileParser;
friend class FieldStreamBase;
friend class FieldInfo;
UNSIGNED5::Reader<const u1*, int> _r;
int _next_index;
public:
public:
FieldInfoReader(const Array<u1>* fi);
private:
uint32_t next_uint() { return _r.next_uint(); }
private:
inline uint32_t next_uint() { return _r.next_uint(); }
void skip(int n) { int s = _r.try_skip(n); assert(s == n,""); }
public:
int has_next() { return _r.has_next(); }
int position() { return _r.position(); }
int next_index() { return _next_index; }
void read_field_counts(int* java_fields, int* injected_fields);
int has_next() const { return _r.position() < _r.limit(); }
int position() const { return _r.position(); }
int next_index() const { return _next_index; }
void read_name_and_signature(u2* name_index, u2* signature_index);
void read_field_info(FieldInfo& fi);
int search_table_lookup(const Array<u1>* search_table, const Symbol* name, const Symbol* signature, ConstantPool* cp, int java_fields);
// skip a whole field record, both required and optional bits
FieldInfoReader& skip_field_info();
@@ -271,6 +270,11 @@ class FieldInfoStream : AllStatic {
friend class JavaFieldStream;
friend class FieldStreamBase;
friend class ClassFileParser;
friend class FieldInfoReader;
friend class FieldInfoComparator;
private:
static int compare_name_and_sig(const Symbol* n1, const Symbol* s1, const Symbol* n2, const Symbol* s2);
public:
static int num_java_fields(const Array<u1>* fis);
@@ -278,9 +282,14 @@ class FieldInfoStream : AllStatic {
static int num_total_fields(const Array<u1>* fis);
static Array<u1>* create_FieldInfoStream(GrowableArray<FieldInfo>* fields, int java_fields, int injected_fields,
ClassLoaderData* loader_data, TRAPS);
ClassLoaderData* loader_data, TRAPS);
static Array<u1>* create_search_table(ConstantPool* cp, const Array<u1>* fis, ClassLoaderData* loader_data, TRAPS);
static GrowableArray<FieldInfo>* create_FieldInfoArray(const Array<u1>* fis, int* java_fields_count, int* injected_fields_count);
static void print_from_fieldinfo_stream(Array<u1>* fis, outputStream* os, ConstantPool* cp);
DEBUG_ONLY(static void validate_search_table(ConstantPool* cp, const Array<u1>* fis, const Array<u1>* search_table);)
static void print_search_table(outputStream* st, ConstantPool* cp, const Array<u1>* fis, const Array<u1>* search_table);
};
class FieldStatus {

View File

@@ -56,16 +56,27 @@ inline Symbol* FieldInfo::lookup_symbol(int symbol_index) const {
inline int FieldInfoStream::num_injected_java_fields(const Array<u1>* fis) {
FieldInfoReader fir(fis);
fir.skip(1);
return fir.next_uint();
int java_fields_count;
int injected_fields_count;
fir.read_field_counts(&java_fields_count, &injected_fields_count);
return injected_fields_count;
}
inline int FieldInfoStream::num_total_fields(const Array<u1>* fis) {
FieldInfoReader fir(fis);
return fir.next_uint() + fir.next_uint();
int java_fields_count;
int injected_fields_count;
fir.read_field_counts(&java_fields_count, &injected_fields_count);
return java_fields_count + injected_fields_count;
}
inline int FieldInfoStream::num_java_fields(const Array<u1>* fis) { return FieldInfoReader(fis).next_uint(); }
inline int FieldInfoStream::num_java_fields(const Array<u1>* fis) {
FieldInfoReader fir(fis);
int java_fields_count;
int injected_fields_count;
fir.read_field_counts(&java_fields_count, &injected_fields_count);
return java_fields_count;
}
template<typename CON>
inline void Mapper<CON>::map_field_info(const FieldInfo& fi) {
@@ -94,13 +105,22 @@ inline void Mapper<CON>::map_field_info(const FieldInfo& fi) {
inline FieldInfoReader::FieldInfoReader(const Array<u1>* fi)
: _r(fi->data(), 0),
: _r(fi->data(), fi->length()),
_next_index(0) { }
inline void FieldInfoReader::read_field_counts(int* java_fields, int* injected_fields) {
*java_fields = next_uint();
*injected_fields = next_uint();
}
inline void FieldInfoReader::read_name_and_signature(u2* name_index, u2* signature_index) {
*name_index = checked_cast<u2>(next_uint());
*signature_index = checked_cast<u2>(next_uint());
}
inline void FieldInfoReader::read_field_info(FieldInfo& fi) {
fi._index = _next_index++;
fi._name_index = checked_cast<u2>(next_uint());
fi._signature_index = checked_cast<u2>(next_uint());
read_name_and_signature(&fi._name_index, &fi._signature_index);
fi._offset = next_uint();
fi._access_flags = AccessFlags(checked_cast<u2>(next_uint()));
fi._field_flags = FieldInfo::FieldFlags(next_uint());

View File

@@ -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
@@ -56,17 +56,23 @@ class FieldStreamBase : public StackObj {
inline FieldStreamBase(const Array<u1>* fieldinfo_stream, ConstantPool* constants, int start, int limit);
inline FieldStreamBase(Array<u1>* fieldinfo_stream, ConstantPool* constants);
inline FieldStreamBase(const Array<u1>* fieldinfo_stream, ConstantPool* constants);
private:
private:
void initialize() {
int java_fields_count = _reader.next_uint();
int injected_fields_count = _reader.next_uint();
assert( _limit <= java_fields_count + injected_fields_count, "Safety check");
int java_fields_count;
int injected_fields_count;
_reader.read_field_counts(&java_fields_count, &injected_fields_count);
if (_limit < _index) {
_limit = java_fields_count + injected_fields_count;
} else {
assert( _limit <= java_fields_count + injected_fields_count, "Safety check");
}
if (_limit != 0) {
_reader.read_field_info(_fi_buf);
}
}
public:
inline FieldStreamBase(InstanceKlass* klass);
@@ -138,8 +144,11 @@ class FieldStreamBase : public StackObj {
// Iterate over only the Java fields
class JavaFieldStream : public FieldStreamBase {
Array<u1>* _search_table;
public:
JavaFieldStream(const InstanceKlass* k): FieldStreamBase(k->fieldinfo_stream(), k->constants(), 0, k->java_fields_count()) {}
JavaFieldStream(const InstanceKlass* k): FieldStreamBase(k->fieldinfo_stream(), k->constants(), 0, k->java_fields_count()),
_search_table(k->fieldinfo_search_table()) {}
u2 name_index() const {
assert(!field()->field_flags().is_injected(), "regular only");
@@ -149,7 +158,6 @@ class JavaFieldStream : public FieldStreamBase {
u2 signature_index() const {
assert(!field()->field_flags().is_injected(), "regular only");
return field()->signature_index();
return -1;
}
u2 generic_signature_index() const {
@@ -164,6 +172,10 @@ class JavaFieldStream : public FieldStreamBase {
assert(!field()->field_flags().is_injected(), "regular only");
return field()->initializer_index();
}
// Performs either a linear search or binary search through the stream
// looking for a matching name/signature combo
bool lookup(const Symbol* name, const Symbol* signature);
};
@@ -176,7 +188,6 @@ class InternalFieldStream : public FieldStreamBase {
class AllFieldStream : public FieldStreamBase {
public:
AllFieldStream(Array<u1>* fieldinfo, ConstantPool* constants): FieldStreamBase(fieldinfo, constants) {}
AllFieldStream(const InstanceKlass* k): FieldStreamBase(k->fieldinfo_stream(), k->constants()) {}
};

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2023, 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
@@ -33,22 +33,18 @@
FieldStreamBase::FieldStreamBase(const Array<u1>* fieldinfo_stream, ConstantPool* constants, int start, int limit) :
_fieldinfo_stream(fieldinfo_stream),
_reader(FieldInfoReader(_fieldinfo_stream)),
_constants(constantPoolHandle(Thread::current(), constants)), _index(start) {
_index = start;
if (limit < start) {
_limit = FieldInfoStream::num_total_fields(_fieldinfo_stream);
} else {
_limit = limit;
}
_constants(constantPoolHandle(Thread::current(), constants)),
_index(start),
_limit(limit) {
initialize();
}
FieldStreamBase::FieldStreamBase(Array<u1>* fieldinfo_stream, ConstantPool* constants) :
FieldStreamBase::FieldStreamBase(const Array<u1>* fieldinfo_stream, ConstantPool* constants) :
_fieldinfo_stream(fieldinfo_stream),
_reader(FieldInfoReader(_fieldinfo_stream)),
_constants(constantPoolHandle(Thread::current(), constants)),
_index(0),
_limit(FieldInfoStream::num_total_fields(_fieldinfo_stream)) {
_limit(-1) {
initialize();
}
@@ -57,9 +53,28 @@ FieldStreamBase::FieldStreamBase(InstanceKlass* klass) :
_reader(FieldInfoReader(_fieldinfo_stream)),
_constants(constantPoolHandle(Thread::current(), klass->constants())),
_index(0),
_limit(FieldInfoStream::num_total_fields(_fieldinfo_stream)) {
_limit(-1) {
assert(klass == field_holder(), "");
initialize();
}
inline bool JavaFieldStream::lookup(const Symbol* name, const Symbol* signature) {
if (_search_table != nullptr) {
int index = _reader.search_table_lookup(_search_table, name, signature, _constants(), _limit);
if (index >= 0) {
assert(index < _limit, "must be");
_index = index;
_reader.read_field_info(_fi_buf);
return true;
}
} else {
for (; !done(); next()) {
if (this->name() == name && this->signature() == signature) {
return true;
}
}
}
return false;
}
#endif // SHARE_OOPS_FIELDSTREAMS_INLINE_HPP

View File

@@ -686,6 +686,11 @@ void InstanceKlass::deallocate_contents(ClassLoaderData* loader_data) {
}
set_fieldinfo_stream(nullptr);
if (fieldinfo_search_table() != nullptr && !fieldinfo_search_table()->is_shared()) {
MetadataFactory::free_array<u1>(loader_data, fieldinfo_search_table());
}
set_fieldinfo_search_table(nullptr);
if (fields_status() != nullptr && !fields_status()->is_shared()) {
MetadataFactory::free_array<FieldStatus>(loader_data, fields_status());
}
@@ -1786,13 +1791,12 @@ FieldInfo InstanceKlass::field(int index) const {
}
bool InstanceKlass::find_local_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const {
for (JavaFieldStream fs(this); !fs.done(); fs.next()) {
Symbol* f_name = fs.name();
Symbol* f_sig = fs.signature();
if (f_name == name && f_sig == sig) {
fd->reinitialize(const_cast<InstanceKlass*>(this), fs.to_FieldInfo());
return true;
}
JavaFieldStream fs(this);
if (fs.lookup(name, sig)) {
assert(fs.name() == name, "name must match");
assert(fs.signature() == sig, "signature must match");
fd->reinitialize(const_cast<InstanceKlass*>(this), fs.to_FieldInfo());
return true;
}
return false;
}
@@ -2610,6 +2614,7 @@ void InstanceKlass::metaspace_pointers_do(MetaspaceClosure* it) {
}
it->push(&_fieldinfo_stream);
it->push(&_fieldinfo_search_table);
// _fields_status might be written into by Rewriter::scan_method() -> fd.set_has_initialized_final_update()
it->push(&_fields_status, MetaspaceClosure::_writable);
@@ -2710,6 +2715,8 @@ void InstanceKlass::remove_unshareable_info() {
DEBUG_ONLY(_shared_class_load_count = 0);
remove_unshareable_flags();
DEBUG_ONLY(FieldInfoStream::validate_search_table(_constants, _fieldinfo_stream, _fieldinfo_search_table));
}
void InstanceKlass::remove_unshareable_flags() {
@@ -2816,6 +2823,8 @@ void InstanceKlass::restore_unshareable_info(ClassLoaderData* loader_data, Handl
if (DiagnoseSyncOnValueBasedClasses && has_value_based_class_annotation() && !is_value_based()) {
set_is_value_based();
}
DEBUG_ONLY(FieldInfoStream::validate_search_table(_constants, _fieldinfo_stream, _fieldinfo_search_table));
}
// Check if a class or any of its supertypes has a version older than 50.
@@ -3760,6 +3769,11 @@ void InstanceKlass::print_on(outputStream* st) const {
map++;
}
st->cr();
if (fieldinfo_search_table() != nullptr) {
st->print_cr(BULLET"---- field info search table:");
FieldInfoStream::print_search_table(st, _constants, _fieldinfo_stream, _fieldinfo_search_table);
}
}
void InstanceKlass::print_value_on(outputStream* st) const {

View File

@@ -276,6 +276,7 @@ class InstanceKlass: public Klass {
// Fields information is stored in an UNSIGNED5 encoded stream (see fieldInfo.hpp)
Array<u1>* _fieldinfo_stream;
Array<u1>* _fieldinfo_search_table;
Array<FieldStatus>* _fields_status;
// embedded Java vtable follows here
@@ -398,6 +399,9 @@ class InstanceKlass: public Klass {
Array<u1>* fieldinfo_stream() const { return _fieldinfo_stream; }
void set_fieldinfo_stream(Array<u1>* fis) { _fieldinfo_stream = fis; }
Array<u1>* fieldinfo_search_table() const { return _fieldinfo_search_table; }
void set_fieldinfo_search_table(Array<u1>* table) { _fieldinfo_search_table = table; }
Array<FieldStatus>* fields_status() const {return _fields_status; }
void set_fields_status(Array<FieldStatus>* array) { _fields_status = array; }

View File

@@ -34,6 +34,7 @@
#include "memory/metaspaceClosure.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/method.hpp"
#include "oops/objArrayKlass.hpp"
#include "runtime/handles.hpp"
#include "runtime/mutexLocker.hpp"
#include "utilities/resizeableResourceHash.hpp"
@@ -286,7 +287,12 @@ private:
static bool is_klass_loaded(Klass* k) {
if (have_data()) {
// If we're running in AOT mode some classes may not be loaded yet
return !k->is_instance_klass() || InstanceKlass::cast(k)->is_loaded();
if (k->is_objArray_klass()) {
k = ObjArrayKlass::cast(k)->bottom_klass();
}
if (k->is_instance_klass()) {
return InstanceKlass::cast(k)->is_loaded();
}
}
return true;
}

View File

@@ -37,11 +37,8 @@
#include "utilities/copy.hpp"
#include "utilities/powerOfTwo.hpp"
void Block_Array::grow( uint i ) {
_nesting.check(_arena); // Check if a potential reallocation in the arena is safe
if (i < Max()) {
return; // No need to grow
}
void Block_Array::grow(uint i) {
assert(i >= Max(), "Should have been checked before, use maybe_grow?");
DEBUG_ONLY(_limit = i+1);
if( i < _size ) return;
if( !_size ) {

View File

@@ -53,7 +53,13 @@ class Block_Array : public ArenaObj {
ReallocMark _nesting; // Safety checks for arena reallocation
protected:
Block **_blocks;
void grow( uint i ); // Grow array node to fit
void maybe_grow(uint i) {
_nesting.check(_arena); // Check if a potential reallocation in the arena is safe
if (i >= Max()) {
grow(i);
}
}
void grow(uint i); // Grow array node to fit
public:
Block_Array(Arena *a) : _size(OptoBlockListSize), _arena(a) {
@@ -68,7 +74,7 @@ public:
Block *operator[] ( uint i ) const // Lookup, or assert for not mapped
{ assert( i < Max(), "oob" ); return _blocks[i]; }
// Extend the mapping: index i maps to Block *n.
void map( uint i, Block *n ) { grow(i); _blocks[i] = n; }
void map( uint i, Block *n ) { maybe_grow(i); _blocks[i] = n; }
uint Max() const { DEBUG_ONLY(return _limit); return _size; }
};

View File

@@ -298,19 +298,52 @@ IdealLoopTree* PhaseIdealLoop::insert_outer_loop(IdealLoopTree* loop, LoopNode*
return outer_ilt;
}
// Create a skeleton strip mined outer loop: a Loop head before the
// inner strip mined loop, a safepoint and an exit condition guarded
// by an opaque node after the inner strip mined loop with a backedge
// to the loop head. The inner strip mined loop is left as it is. Only
// once loop optimizations are over, do we adjust the inner loop exit
// condition to limit its number of iterations, set the outer loop
// exit condition and add Phis to the outer loop head. Some loop
// optimizations that operate on the inner strip mined loop need to be
// aware of the outer strip mined loop: loop unswitching needs to
// clone the outer loop as well as the inner, unrolling needs to only
// clone the inner loop etc. No optimizations need to change the outer
// strip mined loop as it is only a skeleton.
IdealLoopTree* PhaseIdealLoop::create_outer_strip_mined_loop(BoolNode *test, Node *cmp, Node *init_control,
// Create a skeleton strip mined outer loop: an OuterStripMinedLoop head before the inner strip mined CountedLoop, a
// SafePoint on exit of the inner CountedLoopEnd and an OuterStripMinedLoopEnd test that can't constant fold until loop
// optimizations are over. The inner strip mined loop is left as it is. Only once loop optimizations are over, do we
// adjust the inner loop exit condition to limit its number of iterations, set the outer loop exit condition and add
// Phis to the outer loop head. Some loop optimizations that operate on the inner strip mined loop need to be aware of
// the outer strip mined loop: loop unswitching needs to clone the outer loop as well as the inner, unrolling needs to
// only clone the inner loop etc. No optimizations need to change the outer strip mined loop as it is only a skeleton.
//
// Schematically:
//
// OuterStripMinedLoop -------|
// | |
// CountedLoop ----------- | |
// \- Phi (iv) -| | |
// / \ | | |
// CmpI AddI --| | |
// \ | |
// Bool | |
// \ | |
// CountedLoopEnd | |
// / \ | |
// IfFalse IfTrue--------| |
// | |
// SafePoint |
// | |
// OuterStripMinedLoopEnd |
// / \ |
// IfFalse IfTrue-----------|
// |
//
//
// As loop optimizations transform the inner loop, the outer strip mined loop stays mostly unchanged. The only exception
// is nodes referenced from the SafePoint and sunk from the inner loop: they end up in the outer strip mined loop.
//
// Not adding Phis to the outer loop head from the beginning, and only adding them after loop optimizations does not
// conform to C2's IR rules: any variable or memory slice that is mutated in a loop should have a Phi. The main
// motivation for such a design that doesn't conform to C2's IR rules is to allow existing loop optimizations to be
// mostly unaffected by the outer strip mined loop: the only extra step needed in most cases is to step over the
// OuterStripMinedLoop. The main drawback is that once loop optimizations are over, an extra step is needed to finish
// constructing the outer loop. This is handled by OuterStripMinedLoopNode::adjust_strip_mined_loop().
//
// Adding Phis to the outer loop is largely straightforward: there needs to be one Phi in the outer loop for every Phi
// in the inner loop. Things may be more complicated for sunk Store nodes: there may not be any inner loop Phi left
// after sinking for a particular memory slice but the outer loop needs a Phi. See
// OuterStripMinedLoopNode::handle_sunk_stores_when_finishing_construction()
IdealLoopTree* PhaseIdealLoop::create_outer_strip_mined_loop(Node* init_control,
IdealLoopTree* loop, float cl_prob, float le_fcnt,
Node*& entry_control, Node*& iffalse) {
Node* outer_test = intcon(0);
@@ -2255,9 +2288,8 @@ bool PhaseIdealLoop::is_counted_loop(Node* x, IdealLoopTree*&loop, BasicType iv_
is_deleteable_safept(sfpt);
IdealLoopTree* outer_ilt = nullptr;
if (strip_mine_loop) {
outer_ilt = create_outer_strip_mined_loop(test, cmp, init_control, loop,
cl_prob, le->_fcnt, entry_control,
iffalse);
outer_ilt = create_outer_strip_mined_loop(init_control, loop, cl_prob, le->_fcnt,
entry_control, iffalse);
}
// Now setup a new CountedLoopNode to replace the existing LoopNode
@@ -2870,10 +2902,11 @@ BaseCountedLoopNode* BaseCountedLoopNode::make(Node* entry, Node* backedge, Basi
return new LongCountedLoopNode(entry, backedge);
}
void OuterStripMinedLoopNode::fix_sunk_stores(CountedLoopEndNode* inner_cle, LoopNode* inner_cl, PhaseIterGVN* igvn,
PhaseIdealLoop* iloop) {
Node* cle_out = inner_cle->proj_out(false);
Node* cle_tail = inner_cle->proj_out(true);
void OuterStripMinedLoopNode::fix_sunk_stores_when_back_to_counted_loop(PhaseIterGVN* igvn,
PhaseIdealLoop* iloop) const {
CountedLoopNode* inner_cl = inner_counted_loop();
IfFalseNode* cle_out = inner_loop_exit();
if (cle_out->outcnt() > 1) {
// Look for chains of stores that were sunk
// out of the inner loop and are in the outer loop
@@ -2988,11 +3021,90 @@ void OuterStripMinedLoopNode::fix_sunk_stores(CountedLoopEndNode* inner_cle, Loo
}
}
// The outer strip mined loop is initially only partially constructed. In particular Phis are omitted.
// See comment above: PhaseIdealLoop::create_outer_strip_mined_loop()
// We're now in the process of finishing the construction of the outer loop. For each Phi in the inner loop, a Phi in
// the outer loop was just now created. However, Sunk Stores cause an extra challenge:
// 1) If all Stores in the inner loop were sunk for a particular memory slice, there's no Phi left for that memory slice
// in the inner loop anymore, and hence we did not yet add a Phi for the outer loop. So an extra Phi must now be
// added for each chain of sunk Stores for a particular memory slice.
// 2) If some Stores were sunk and some left in the inner loop, a Phi was already created in the outer loop but
// its backedge input wasn't wired correctly to the last Store of the chain: the backedge input was set to the
// backedge of the inner loop Phi instead, but it needs to be the last Store of the chain in the outer loop. We now
// have to fix that too.
void OuterStripMinedLoopNode::handle_sunk_stores_when_finishing_construction(PhaseIterGVN* igvn) {
IfFalseNode* cle_exit_proj = inner_loop_exit();
// Find Sunk stores: Sunk stores are pinned on the loop exit projection of the inner loop. Indeed, because Sunk Stores
// modify the memory state captured by the SafePoint in the outer strip mined loop, they must be above it. The
// SafePoint's control input is the loop exit projection. It's also the only control out of the inner loop above the
// SafePoint.
#ifdef ASSERT
int stores_in_outer_loop_cnt = 0;
for (DUIterator_Fast imax, i = cle_exit_proj->fast_outs(imax); i < imax; i++) {
Node* u = cle_exit_proj->fast_out(i);
if (u->is_Store()) {
stores_in_outer_loop_cnt++;
}
}
#endif
// Sunk stores are reachable from the memory state of the outer loop safepoint
SafePointNode* safepoint = outer_safepoint();
MergeMemNode* mm = safepoint->in(TypeFunc::Memory)->isa_MergeMem();
if (mm == nullptr) {
// There is no MergeMem, which should only happen if there was no memory node
// sunk out of the loop.
assert(stores_in_outer_loop_cnt == 0, "inconsistent");
return;
}
DEBUG_ONLY(int stores_in_outer_loop_cnt2 = 0);
for (MergeMemStream mms(mm); mms.next_non_empty();) {
Node* mem = mms.memory();
// Traverse up the chain of stores to find the first store pinned
// at the loop exit projection.
Node* last = mem;
Node* first = nullptr;
while (mem->is_Store() && mem->in(0) == cle_exit_proj) {
DEBUG_ONLY(stores_in_outer_loop_cnt2++);
first = mem;
mem = mem->in(MemNode::Memory);
}
if (first != nullptr) {
// Found a chain of Stores that were sunk
// Do we already have a memory Phi for that slice on the outer loop? If that is the case, that Phi was created
// by cloning an inner loop Phi. The inner loop Phi should have mem, the memory state of the first Store out of
// the inner loop, as input on the backedge. So does the outer loop Phi given it's a clone.
Node* phi = nullptr;
for (DUIterator_Fast imax, i = mem->fast_outs(imax); i < imax; i++) {
Node* u = mem->fast_out(i);
if (u->is_Phi() && u->in(0) == this && u->in(LoopBackControl) == mem) {
assert(phi == nullptr, "there should be only one");
phi = u;
PRODUCT_ONLY(break);
}
}
if (phi == nullptr) {
// No outer loop Phi? create one
phi = PhiNode::make(this, last);
phi->set_req(EntryControl, mem);
phi = igvn->transform(phi);
igvn->replace_input_of(first, MemNode::Memory, phi);
} else {
// Fix memory state along the backedge: it should be the last sunk Store of the chain
igvn->replace_input_of(phi, LoopBackControl, last);
}
}
}
assert(stores_in_outer_loop_cnt == stores_in_outer_loop_cnt2, "inconsistent");
}
void OuterStripMinedLoopNode::adjust_strip_mined_loop(PhaseIterGVN* igvn) {
verify_strip_mined(1);
// Look for the outer & inner strip mined loop, reduce number of
// iterations of the inner loop, set exit condition of outer loop,
// construct required phi nodes for outer loop.
CountedLoopNode* inner_cl = unique_ctrl_out()->as_CountedLoop();
CountedLoopNode* inner_cl = inner_counted_loop();
assert(inner_cl->is_strip_mined(), "inner loop should be strip mined");
if (LoopStripMiningIter == 0) {
remove_outer_loop_and_safepoint(igvn);
@@ -3010,7 +3122,7 @@ void OuterStripMinedLoopNode::adjust_strip_mined_loop(PhaseIterGVN* igvn) {
inner_cl->clear_strip_mined();
return;
}
CountedLoopEndNode* inner_cle = inner_cl->loopexit();
CountedLoopEndNode* inner_cle = inner_counted_loop_end();
int stride = inner_cl->stride_con();
// For a min int stride, LoopStripMiningIter * stride overflows the int range for all values of LoopStripMiningIter
@@ -3091,8 +3203,9 @@ void OuterStripMinedLoopNode::adjust_strip_mined_loop(PhaseIterGVN* igvn) {
}
Node* iv_phi = nullptr;
// Make a clone of each phi in the inner loop
// for the outer loop
// Make a clone of each phi in the inner loop for the outer loop
// When Stores were Sunk, after this step, a Phi may still be missing or its backedge incorrectly wired. See
// handle_sunk_stores_when_finishing_construction()
for (uint i = 0; i < inner_cl->outcnt(); i++) {
Node* u = inner_cl->raw_out(i);
if (u->is_Phi()) {
@@ -3111,6 +3224,8 @@ void OuterStripMinedLoopNode::adjust_strip_mined_loop(PhaseIterGVN* igvn) {
}
}
handle_sunk_stores_when_finishing_construction(igvn);
if (iv_phi != nullptr) {
// Now adjust the inner loop's exit condition
Node* limit = inner_cl->limit();
@@ -3166,7 +3281,7 @@ void OuterStripMinedLoopNode::transform_to_counted_loop(PhaseIterGVN* igvn, Phas
CountedLoopEndNode* inner_cle = inner_cl->loopexit();
Node* safepoint = outer_safepoint();
fix_sunk_stores(inner_cle, inner_cl, igvn, iloop);
fix_sunk_stores_when_back_to_counted_loop(igvn, iloop);
// make counted loop exit test always fail
ConINode* zero = igvn->intcon(0);

View File

@@ -573,7 +573,8 @@ class LoopLimitNode : public Node {
// Support for strip mining
class OuterStripMinedLoopNode : public LoopNode {
private:
static void fix_sunk_stores(CountedLoopEndNode* inner_cle, LoopNode* inner_cl, PhaseIterGVN* igvn, PhaseIdealLoop* iloop);
void fix_sunk_stores_when_back_to_counted_loop(PhaseIterGVN* igvn, PhaseIdealLoop* iloop) const;
void handle_sunk_stores_when_finishing_construction(PhaseIterGVN* igvn);
public:
OuterStripMinedLoopNode(Compile* C, Node *entry, Node *backedge)
@@ -589,6 +590,10 @@ public:
virtual OuterStripMinedLoopEndNode* outer_loop_end() const;
virtual IfFalseNode* outer_loop_exit() const;
virtual SafePointNode* outer_safepoint() const;
CountedLoopNode* inner_counted_loop() const { return unique_ctrl_out()->as_CountedLoop(); }
CountedLoopEndNode* inner_counted_loop_end() const { return inner_counted_loop()->loopexit(); }
IfFalseNode* inner_loop_exit() const { return inner_counted_loop_end()->proj_out(false)->as_IfFalse(); }
void adjust_strip_mined_loop(PhaseIterGVN* igvn);
void remove_outer_loop_and_safepoint(PhaseIterGVN* igvn) const;
@@ -1293,7 +1298,7 @@ public:
void add_parse_predicate(Deoptimization::DeoptReason reason, Node* inner_head, IdealLoopTree* loop, SafePointNode* sfpt);
SafePointNode* find_safepoint(Node* back_control, Node* x, IdealLoopTree* loop);
IdealLoopTree* insert_outer_loop(IdealLoopTree* loop, LoopNode* outer_l, Node* outer_ift);
IdealLoopTree* create_outer_strip_mined_loop(BoolNode *test, Node *cmp, Node *init_control,
IdealLoopTree* create_outer_strip_mined_loop(Node* init_control,
IdealLoopTree* loop, float cl_prob, float le_fcnt,
Node*& entry_control, Node*& iffalse);

View File

@@ -65,13 +65,8 @@ public:
Node_Stack::push(n, (uint)ns);
}
void push(Node *n, Node_State ns, Node *parent, int indx) {
++_inode_top;
if ((_inode_top + 1) >= _inode_max) grow();
_inode_top->node = parent;
_inode_top->indx = (uint)indx;
++_inode_top;
_inode_top->node = n;
_inode_top->indx = (uint)ns;
Node_Stack::push(parent, (uint)indx);
Node_Stack::push(n, (uint)ns);
}
Node *parent() {
pop();

View File

@@ -2798,7 +2798,6 @@ const RegMask &Node::in_RegMask(uint) const {
}
void Node_Array::grow(uint i) {
_nesting.check(_a); // Check if a potential reallocation in the arena is safe
assert(i >= _max, "Should have been checked before, use maybe_grow?");
assert(_max > 0, "invariant");
uint old = _max;
@@ -3038,10 +3037,6 @@ void Unique_Node_List::remove_useless_nodes(VectorSet &useful) {
//=============================================================================
void Node_Stack::grow() {
_nesting.check(_a); // Check if a potential reallocation in the arena is safe
if (_inode_top < _inode_max) {
return; // No need to grow
}
size_t old_top = pointer_delta(_inode_top,_inodes,sizeof(INode)); // save _top
size_t old_max = pointer_delta(_inode_max,_inodes,sizeof(INode));
size_t max = old_max << 1; // max * 2

View File

@@ -1633,6 +1633,7 @@ protected:
// Grow array to required capacity
void maybe_grow(uint i) {
_nesting.check(_a); // Check if a potential reallocation in the arena is safe
if (i >= _max) {
grow(i);
}
@@ -1884,7 +1885,15 @@ protected:
INode *_inodes; // Array storage for the stack
Arena *_a; // Arena to allocate in
ReallocMark _nesting; // Safety checks for arena reallocation
void maybe_grow() {
_nesting.check(_a); // Check if a potential reallocation in the arena is safe
if (_inode_top >= _inode_max) {
grow();
}
}
void grow();
public:
Node_Stack(int size) {
size_t max = (size > OptoNodeListSize) ? size : OptoNodeListSize;
@@ -1907,7 +1916,7 @@ public:
}
void push(Node *n, uint i) {
++_inode_top;
grow();
maybe_grow();
INode *top = _inode_top; // optimization
top->node = n;
top->indx = i;

View File

@@ -2966,7 +2966,7 @@ JVM_ENTRY(jobject, JVM_CreateThreadSnapshot(JNIEnv* env, jobject jthread))
oop snapshot = ThreadSnapshotFactory::get_thread_snapshot(jthread, THREAD);
return JNIHandles::make_local(THREAD, snapshot);
#else
return nullptr;
THROW_NULL(vmSymbols::java_lang_UnsupportedOperationException());
#endif
JVM_END

View File

@@ -3550,6 +3550,13 @@ void VM_RedefineClasses::set_new_constant_pool(
Array<u1>* new_fis = FieldInfoStream::create_FieldInfoStream(fields, java_fields, injected_fields, scratch_class->class_loader_data(), CHECK);
scratch_class->set_fieldinfo_stream(new_fis);
MetadataFactory::free_array<u1>(scratch_class->class_loader_data(), old_stream);
Array<u1>* old_table = scratch_class->fieldinfo_search_table();
Array<u1>* search_table = FieldInfoStream::create_search_table(scratch_class->constants(), new_fis, scratch_class->class_loader_data(), CHECK);
scratch_class->set_fieldinfo_search_table(search_table);
MetadataFactory::free_array<u1>(scratch_class->class_loader_data(), old_table);
DEBUG_ONLY(FieldInfoStream::validate_search_table(scratch_class->constants(), new_fis, search_table));
}
// Update constant pool indices in the inner classes info to use

View File

@@ -2005,6 +2005,10 @@ const int ObjectAlignmentInBytes = 8;
product(bool, UseThreadsLockThrottleLock, true, DIAGNOSTIC, \
"Use an extra lock during Thread start and exit to alleviate" \
"contention on Threads_lock.") \
\
develop(uint, BinarySearchThreshold, 16, \
"Minimal number of elements in a sorted collection to prefer" \
"binary search over simple linear search." ) \
// end of RUNTIME_FLAGS

View File

@@ -83,7 +83,7 @@ Monitor* CompileTaskWait_lock = nullptr;
Monitor* MethodCompileQueue_lock = nullptr;
Monitor* CompileThread_lock = nullptr;
Monitor* Compilation_lock = nullptr;
Mutex* CompileTaskAlloc_lock = nullptr;
Monitor* CompileTaskAlloc_lock = nullptr;
Mutex* CompileStatistics_lock = nullptr;
Mutex* DirectivesStack_lock = nullptr;
Monitor* Terminator_lock = nullptr;
@@ -343,7 +343,7 @@ void mutex_init() {
MUTEX_DEFL(G1RareEvent_lock , PaddedMutex , Threads_lock, true);
}
MUTEX_DEFL(CompileTaskAlloc_lock , PaddedMutex , MethodCompileQueue_lock);
MUTEX_DEFL(CompileTaskAlloc_lock , PaddedMonitor, MethodCompileQueue_lock);
MUTEX_DEFL(CompileTaskWait_lock , PaddedMonitor, MethodCompileQueue_lock);
#if INCLUDE_PARALLELGC

View File

@@ -85,7 +85,7 @@ extern Monitor* CompileThread_lock; // a lock held by compile threa
extern Monitor* Compilation_lock; // a lock used to pause compilation
extern Mutex* TrainingData_lock; // a lock used when accessing training records
extern Monitor* TrainingReplayQueue_lock; // a lock held when class are added/removed to the training replay queue
extern Mutex* CompileTaskAlloc_lock; // a lock held when CompileTasks are allocated
extern Monitor* CompileTaskAlloc_lock; // a lock held when CompileTasks are allocated
extern Monitor* CompileTaskWait_lock; // a lock held when CompileTasks are waited/notified
extern Mutex* CompileStatistics_lock; // a lock held when updating compilation statistics
extern Mutex* DirectivesStack_lock; // a lock held when mutating the dirstack and ref counting directives

View File

@@ -1168,9 +1168,10 @@ void ThreadsSMRSupport::print_info_on(const Thread* thread, outputStream* st) {
// The count is only interesting if we have a _threads_list_ptr.
st->print(", _nested_threads_hazard_ptr_cnt=%u", thread->_nested_threads_hazard_ptr_cnt);
}
if (SafepointSynchronize::is_at_safepoint() || Thread::current() == thread) {
// It is only safe to walk the list if we're at a safepoint or the
// calling thread is walking its own list.
if ((SafepointSynchronize::is_at_safepoint() && thread->is_Java_thread()) ||
Thread::current() == thread) {
// It is only safe to walk the list if we're at a safepoint and processing a JavaThread,
// or the calling thread is walking its own list.
SafeThreadsListPtr* current = thread->_threads_list_ptr;
if (current != nullptr) {
// Skip the top nesting level as it is always printed above.

View File

@@ -771,8 +771,8 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
#endif
if (CDSConfig::is_using_aot_linked_classes()) {
AOTLinkedClassBulkLoader::finish_loading_javabase_classes(CHECK_JNI_ERR);
SystemDictionary::restore_archived_method_handle_intrinsics();
AOTLinkedClassBulkLoader::finish_loading_javabase_classes(CHECK_JNI_ERR);
}
// Start string deduplication thread if requested.

View File

@@ -1439,7 +1439,17 @@ oop ThreadSnapshotFactory::get_thread_snapshot(jobject jthread, TRAPS) {
ResourceMark rm(THREAD);
HandleMark hm(THREAD);
Handle thread_h(THREAD, JNIHandles::resolve(jthread));
JavaThread* java_thread = nullptr;
oop thread_oop;
bool has_javathread = tlh.cv_internal_thread_to_JavaThread(jthread, &java_thread, &thread_oop);
assert((has_javathread && thread_oop != nullptr) || !has_javathread, "Missing Thread oop");
Handle thread_h(THREAD, thread_oop);
bool is_virtual = java_lang_VirtualThread::is_instance(thread_h()); // Deals with null
if (!has_javathread && !is_virtual) {
return nullptr; // thread terminated so not of interest
}
// wrapper to auto delete JvmtiVTMSTransitionDisabler
class TransitionDisabler {
@@ -1460,8 +1470,6 @@ oop ThreadSnapshotFactory::get_thread_snapshot(jobject jthread, TRAPS) {
}
} transition_disabler;
JavaThread* java_thread = nullptr;
bool is_virtual = java_lang_VirtualThread::is_instance(thread_h());
Handle carrier_thread;
if (is_virtual) {
// 1st need to disable mount/unmount transitions

View File

@@ -0,0 +1,113 @@
/*
* 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.
*
*/
#include <cstring>
#include "utilities/align.hpp"
#include "utilities/count_leading_zeros.hpp"
#include "utilities/packedTable.hpp"
// The thresholds are inclusive, and in practice the limits are rounded
// to the nearest power-of-two - 1.
// Based on the max_key and max_value we figure out the number of bits required to store
// key and value; imagine that only as bits (not aligned to byte boundary... yet).
// Then we concatenate the bits for key and value, and 'add' 1-7 padding zeroes
// (high-order bits) to align on bytes.
// In the end we have each element in the table consuming 1-8 bytes (case with 0 bits for key
// is ruled out).
PackedTableBase::PackedTableBase(uint32_t max_key, uint32_t max_value) {
unsigned int key_bits = max_key == 0 ? 0 : 32 - count_leading_zeros(max_key);
unsigned int value_bits = max_value == 0 ? 0 : 32 - count_leading_zeros(max_value);
_element_bytes = align_up(key_bits + value_bits, 8) / 8;
// shifting left by 32 is undefined behaviour, and in practice returns 1
_key_mask = key_bits >= 32 ? -1 : (1U << key_bits) - 1;
_value_shift = key_bits;
_value_mask = value_bits >= 32 ? -1 : (1U << value_bits) - 1;
guarantee(_element_bytes > 0, "wouldn't work");
assert(_element_bytes <= sizeof(uint64_t), "shouldn't happen");
}
// Note: we require the supplier to provide the elements in the final order as we can't easily sort
// within this method - qsort() accepts only pure function as comparator.
void PackedTableBuilder::fill(u1* table, size_t table_length, Supplier &supplier) const {
uint32_t key, value;
size_t offset = 0;
for (; offset <= table_length && supplier.next(&key, &value); offset += _element_bytes) {
assert((key & ~_key_mask) == 0, "key out of bounds");
assert((value & ~_value_mask) == 0, "value out of bounds: %x vs. %x (%x)", value, _value_mask, ~_value_mask);
uint64_t element = static_cast<uint64_t>(key) | (static_cast<uint64_t>(value) << _value_shift);
for (unsigned int i = 0; i < _element_bytes; ++i) {
table[offset + i] = static_cast<u1>(0xFF & element);
element >>= 8;
}
}
assert(offset == table_length, "Did not fill whole array");
assert(!supplier.next(&key, &value), "Supplier has more elements");
}
uint64_t PackedTableLookup::read_element(size_t offset) const {
uint64_t element = 0;
for (unsigned int i = 0; i < _element_bytes; ++i) {
element |= static_cast<uint64_t>(_table[offset + i]) << (8 * i);
}
assert((element & ~((uint64_t) _key_mask | ((uint64_t) _value_mask << _value_shift))) == 0, "read too much");
return element;
}
bool PackedTableLookup::search(Comparator& comparator, uint32_t* found_key, uint32_t* found_value) const {
unsigned int low = 0, high = checked_cast<unsigned int>(_table_length / _element_bytes);
assert(low < high, "must be");
while (low < high) {
unsigned int mid = low + (high - low) / 2;
assert(mid >= low && mid < high, "integer overflow?");
uint64_t element = read_element(_element_bytes * mid);
// Ignoring high 32 bits in element on purpose
uint32_t key = static_cast<uint32_t>(element) & _key_mask;
int cmp = comparator.compare_to(key);
if (cmp == 0) {
*found_key = key;
// Since __builtin_memcpy in read_element does not copy bits outside the element
// anything above _value_mask << _value_shift should be zero.
*found_value = checked_cast<uint32_t>(element >> _value_shift) & _value_mask;
return true;
} else if (cmp < 0) {
high = mid;
} else {
low = mid + 1;
}
}
return false;
}
#ifdef ASSERT
void PackedTableLookup::validate_order(Comparator &comparator) const {
auto validator = [&] (size_t offset, uint32_t key, uint32_t value) {
if (offset != 0) {
assert(comparator.compare_to(key) < 0, "not sorted");
}
comparator.reset(key);
};
iterate(validator);
}
#endif

View File

@@ -0,0 +1,123 @@
/*
* 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.
*
*/
#include "oops/array.hpp"
#include "utilities/globalDefinitions.hpp"
// Base for space-optimized structure supporting binary search. Each element
// consists of up to 32-bit key, and up to 32-bit value; these are packed
// into a bit-record with 1-byte alignment.
// The keys are ordered according to a custom comparator.
class PackedTableBase {
protected:
unsigned int _element_bytes;
uint32_t _key_mask;
unsigned int _value_shift;
uint32_t _value_mask;
public:
PackedTableBase(uint32_t max_key, uint32_t max_value);
// Returns number of bytes each element will occupy.
inline unsigned int element_bytes(void) const { return _element_bytes; }
};
// Helper class for constructing a packed table in the provided array.
class PackedTableBuilder: public PackedTableBase {
public:
class Supplier {
public:
// Returns elements with already ordered keys.
// This function should return true when the key and value was set,
// and false when there's no more elements.
// Packed table does NOT support duplicate keys.
virtual bool next(uint32_t* key, uint32_t* value) = 0;
};
// The thresholds are inclusive, and in practice the limits are rounded
// to the nearest power-of-two - 1.
// See PackedTableBase constructor for details.
PackedTableBuilder(uint32_t max_key, uint32_t max_value): PackedTableBase(max_key, max_value) {}
// Constructs a packed table in the provided array, filling it with elements
// from the supplier. Note that no comparator is requied by this method -
// the supplier must return elements with already ordered keys.
// The table_length (in bytes) should match number of elements provided
// by the supplier (when Supplier::next() returns false the whole array should
// be filled).
void fill(u1* table, size_t table_length, Supplier &supplier) const;
};
// Helper class for lookup in a packed table.
class PackedTableLookup: public PackedTableBase {
const u1* const _table;
const size_t _table_length;
uint64_t read_element(size_t offset) const;
public:
// The comparator implementation does not have to store a key (uint32_t);
// the idea is that key can point into a different structure that hosts data
// suitable for the actual comparison. That's why PackedTableLookup::search(...)
// returns the key it found as well as the value.
class Comparator {
public:
// Returns negative/0/positive if the target referred to by this comparator
// is lower/equal/higher than the target referred to by the key.
virtual int compare_to(uint32_t key) = 0;
// Changes the target this comparator refers to.
DEBUG_ONLY(virtual void reset(uint32_t key) = 0);
};
// The thresholds are inclusive, and in practice the limits are rounded
// to the nearest power-of-two - 1.
// See PackedTableBase constructor for details.
PackedTableLookup(uint32_t max_key, uint32_t max_value, const u1 *table, size_t table_length):
PackedTableBase(max_key, max_value), _table(table), _table_length(table_length) {}
PackedTableLookup(uint32_t max_key, uint32_t max_value, const Array<u1> *table):
PackedTableLookup(max_key, max_value, table->data(), static_cast<size_t>(table->length())) {}
// Performs a binary search in the packed table, looking for an element with key
// referring to a target equal according to the comparator.
// When the element is found, found_key and found_value are updated from the element
// and the function returns true.
// When the element is not found, found_key and found_value are not changed and
// the function returns false.
bool search(Comparator& comparator, uint32_t* found_key, uint32_t* found_value) const;
// Asserts that elements in the packed table follow the order defined by the comparator.
DEBUG_ONLY(void validate_order(Comparator &comparator) const);
template<typename Function>
void iterate(Function func) const {
for (size_t offset = 0; offset < _table_length; offset += _element_bytes) {
uint64_t element = read_element(offset);
uint32_t key = static_cast<uint32_t>(element) & _key_mask;
uint32_t value = checked_cast<uint32_t>(element >> _value_shift) & _value_mask;
func(offset, key, value);
}
}
};

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 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
@@ -261,7 +261,7 @@ class UNSIGNED5 : AllStatic {
ARR _array;
OFF _limit;
OFF _position;
int next_length() {
int next_length() const {
return UNSIGNED5::check_length(_array, _position, _limit, GET());
}
public:
@@ -270,7 +270,7 @@ class UNSIGNED5 : AllStatic {
uint32_t next_uint() {
return UNSIGNED5::read_uint(_array, _position, _limit, GET());
}
bool has_next() {
bool has_next() const {
return next_length() != 0;
}
// tries to skip count logical entries; returns actual number skipped
@@ -284,8 +284,9 @@ class UNSIGNED5 : AllStatic {
return actual;
}
ARR array() { return _array; }
OFF limit() { return _limit; }
OFF position() { return _position; }
OFF limit() const { return _limit; }
OFF position() const { return _position; }
void set_limit(OFF limit) { _limit = limit; }
void set_position(OFF position) { _position = position; }
// For debugging, even in product builds (see debug.cpp).

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013 SAP SE. All rights reserved.
* Copyright (c) 2013, 2025 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -52,6 +52,15 @@ class AixFileSystemProvider extends UnixFileSystemProvider {
return new AixFileStore(path);
}
private static boolean supportsUserDefinedFileAttributeView(UnixPath file) {
try {
FileStore store = new AixFileStore(file);
return store.supportsFileAttributeView(UserDefinedFileAttributeView.class);
} catch (IOException e) {
return false;
}
}
@Override
@SuppressWarnings("unchecked")
public <V extends FileAttributeView> V getFileAttributeView(Path obj,
@@ -59,8 +68,10 @@ class AixFileSystemProvider extends UnixFileSystemProvider {
LinkOption... options)
{
if (type == UserDefinedFileAttributeView.class) {
return (V) new AixUserDefinedFileAttributeView(UnixPath.toUnixPath(obj),
Util.followLinks(options));
UnixPath file = UnixPath.toUnixPath(obj);
return supportsUserDefinedFileAttributeView(file) ?
(V) new AixUserDefinedFileAttributeView(file, Util.followLinks(options))
: null;
}
return super.getFileAttributeView(obj, type, options);
}
@@ -71,8 +82,10 @@ class AixFileSystemProvider extends UnixFileSystemProvider {
LinkOption... options)
{
if (name.equals("user")) {
return new AixUserDefinedFileAttributeView(UnixPath.toUnixPath(obj),
Util.followLinks(options));
UnixPath file = UnixPath.toUnixPath(obj);
return supportsUserDefinedFileAttributeView(file) ?
new AixUserDefinedFileAttributeView(file, Util.followLinks(options))
: null;
}
return super.getFileAttributeView(obj, name, options);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 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
@@ -23,6 +23,7 @@
* questions.
*/
#include <stdbool.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
@@ -229,33 +230,50 @@ void setOSNameAndVersion(java_props_t *sprops) {
NSString *nsVerStr = NULL;
char* osVersionCStr = NULL;
NSOperatingSystemVersion osVer = [[NSProcessInfo processInfo] operatingSystemVersion];
// Copy out the char* if running on version other than 10.16 Mac OS (10.16 == 11.x)
// or explicitly requesting version compatibility
if (!((long)osVer.majorVersion == 10 && (long)osVer.minorVersion >= 16) ||
(getenv("SYSTEM_VERSION_COMPAT") != NULL)) {
if (osVer.patchVersion == 0) { // Omit trailing ".0"
// Some macOS versions require special handling. For example,
// when the NSOperatingSystemVersion reports 10.16 as the version
// then it should be treated as 11. Similarly, when it reports 16.0
// as the version then it should be treated as 26.
// If the SYSTEM_VERSION_COMPAT environment variable (a macOS construct)
// is set to 1, then we don't do any special handling for any versions
// and just literally use the value that NSOperatingSystemVersion reports.
const char* envVal = getenv("SYSTEM_VERSION_COMPAT");
const bool versionCompatEnabled = envVal != NULL
&& strncmp(envVal, "1", 1) == 0;
const bool requiresSpecialHandling =
((long) osVer.majorVersion == 10 && (long) osVer.minorVersion >= 16)
|| ((long) osVer.majorVersion == 16 && (long) osVer.minorVersion >= 0);
if (!requiresSpecialHandling || versionCompatEnabled) {
// no special handling - just use the version reported
// by NSOperatingSystemVersion
if (osVer.patchVersion == 0) {
// Omit trailing ".0"
nsVerStr = [NSString stringWithFormat:@"%ld.%ld",
(long)osVer.majorVersion, (long)osVer.minorVersion];
} else {
nsVerStr = [NSString stringWithFormat:@"%ld.%ld.%ld",
(long)osVer.majorVersion, (long)osVer.minorVersion, (long)osVer.patchVersion];
(long)osVer.majorVersion, (long)osVer.minorVersion,
(long)osVer.patchVersion];
}
} else {
// Version 10.16, without explicit env setting of SYSTEM_VERSION_COMPAT
// AKA 11+ Read the *real* ProductVersion from the hidden link to avoid SYSTEM_VERSION_COMPAT
// If not found, fallback below to the SystemVersion.plist
NSDictionary *version = [NSDictionary dictionaryWithContentsOfFile :
@"/System/Library/CoreServices/.SystemVersionPlatform.plist"];
// Requires special handling. We ignore the version reported
// by the NSOperatingSystemVersion API and instead read the
// *real* ProductVersion from
// /System/Library/CoreServices/.SystemVersionPlatform.plist.
// If not found there, then as a last resort we fallback to
// /System/Library/CoreServices/SystemVersion.plist
NSDictionary *version = [NSDictionary dictionaryWithContentsOfFile:
@"/System/Library/CoreServices/.SystemVersionPlatform.plist"];
if (version != NULL) {
nsVerStr = [version objectForKey : @"ProductVersion"];
nsVerStr = [version objectForKey: @"ProductVersion"];
}
}
// Fallback to reading the SystemVersion.plist
// Last resort - fallback to reading the SystemVersion.plist
if (nsVerStr == NULL) {
NSDictionary *version = [NSDictionary dictionaryWithContentsOfFile :
@"/System/Library/CoreServices/SystemVersion.plist"];
NSDictionary *version = [NSDictionary dictionaryWithContentsOfFile:
@"/System/Library/CoreServices/SystemVersion.plist"];
if (version != NULL) {
nsVerStr = [version objectForKey : @"ProductVersion"];
nsVerStr = [version objectForKey: @"ProductVersion"];
}
}

View File

@@ -38,7 +38,7 @@ import java.nio.charset.StandardCharsets;
* <p>
* The {@link #readln()} and {@link #readln(String)} methods decode bytes read from
* {@code System.in} into characters. The charset used for decoding is specified by the
* {@link System#getProperties stdin.encoding} property. If this property is not present,
* {@link System##stdin.encoding stdin.encoding} property. If this property is not present,
* or if the charset it names cannot be loaded, then UTF-8 is used instead. Decoding
* always replaces malformed and unmappable byte sequences with the charset's default
* replacement string.

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 1995, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1995, 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
@@ -41,7 +41,7 @@ import java.util.stream.Stream;
/**
* {@code Process} provides control of native processes started by
* ProcessBuilder.start and Runtime.exec.
* {@code ProcessBuilder.start} and {@code Runtime.exec}.
* The class provides methods for performing input from the process, performing
* output to the process, waiting for the process to complete,
* checking the exit status of the process, and destroying (killing)
@@ -78,10 +78,6 @@ import java.util.stream.Stream;
* process I/O can also be redirected</a>
* using methods of the {@link ProcessBuilder} class.
*
* <p>The process is not killed when there are no more references to
* the {@code Process} object, but rather the process
* continues executing asynchronously.
*
* <p>There is no requirement that the process represented by a {@code
* Process} object execute asynchronously or concurrently with respect
* to the Java process that owns the {@code Process} object.
@@ -98,6 +94,49 @@ import java.util.stream.Stream;
* Delegating to the underlying Process or ProcessHandle is typically
* easiest and most efficient.
*
* <h2>Resource Usage</h2>
* {@linkplain ProcessBuilder#start() Starting a process} uses resources in both the invoking process and the invoked
* process and for the communication streams between them.
* The resources to control the process and for communication between the processes are retained
* until there are no longer any references to the Process or the input, error, and output streams
* or readers, or they have been closed.
*
* <p>The process is not killed when there are no more references to the {@code Process} object,
* but rather the process continues executing asynchronously.
* The process implementation closes file descriptors and handles for streams
* that are no longer referenced to prevent leaking operating system resources.
* Processes that have terminated or been terminated are monitored and their resources released.
*
* <p>Streams should be {@code closed} when they are no longer needed, to avoid delaying
* releasing the operating system resources.
* {@code Try-with-resources} can be used to open and close the streams.
* <p>For example, to capture the output of a program known to produce some output and then exit:
* {@snippet lang = "java" :
* List<String> capture(List<String> args) throws Exception {
* ProcessBuilder pb = new ProcessBuilder(args);
* Process process = pb.start();
* try (BufferedReader in = process.inputReader()) {
* List<String> captured = in.readAllLines();
* int status = process.waitFor();
* if (status != 0) {
* throw new RuntimeException("Process %d: %s failed with %d"
* .formatted(process.pid(), args, status));
* }
* return captured;
* }
* }
* }
* <p>Stream resources (file descriptor or handle) are always paired; one in the invoking process
* and the other end of that connection in the invoked process.
* Closing a stream at either end terminates communication but does not have any direct effect
* on the other Process. The closing of the stream typically results in the other process exiting.
*
* <p> {@linkplain #destroy Destroying a process} signals the operating system to terminate the process.
* It is up to the operating system to clean up and release the resources of that process.
* Typically, file descriptors and handles are closed. When they are closed, any connections to
* other processes are terminated and file descriptors and handles in the invoking process signal
* end-of-file or closed. Usually, that is seen as an end-of-file or an exception.
*
* @since 1.0
*/
public abstract class Process {
@@ -127,6 +166,9 @@ public abstract class Process {
* then this method will return a
* <a href="ProcessBuilder.html#redirect-input">null output stream</a>.
*
* <p>The output stream should be {@linkplain OutputStream#close closed}
* when it is no longer needed.
*
* @apiNote
* When writing to both {@link #getOutputStream()} and either {@link #outputWriter()}
* or {@link #outputWriter(Charset)}, {@link BufferedWriter#flush BufferedWriter.flush}
@@ -159,9 +201,15 @@ public abstract class Process {
* then the input stream returned by this method will receive the
* merged standard output and the standard error of the process.
*
* <p>The input stream should be {@linkplain InputStream#close closed}
* when it is no longer needed.
*
* @apiNote
* Use {@link #getInputStream()} and {@link #inputReader()} with extreme care.
* The {@code BufferedReader} may have buffered input from the input stream.
* Use either this method or an {@linkplain #inputReader() input reader}
* but not both on the same {@code Process}.
* The input reader consumes and buffers bytes from the input stream.
* Bytes read from the input stream would not be seen by the reader and
* buffer contents are unpredictable.
*
* @implNote
* Implementation note: It is a good idea for the returned
@@ -185,9 +233,15 @@ public abstract class Process {
* then this method will return a
* <a href="ProcessBuilder.html#redirect-output">null input stream</a>.
*
* <p>The error stream should be {@linkplain InputStream#close closed}
* when it is no longer needed.
*
* @apiNote
* Use {@link #getErrorStream()} and {@link #errorReader()} with extreme care.
* The {@code BufferedReader} may have buffered input from the error stream.
* Use either this method or an {@linkplain #errorReader() error reader}
* but not both on the same {@code Process}.
* The error reader consumes and buffers bytes from the error stream.
* Bytes read from the error stream would not be seen by the reader and the
* buffer contents are unpredictable.
*
* @implNote
* Implementation note: It is a good idea for the returned
@@ -208,6 +262,16 @@ public abstract class Process {
* If the {@code native.encoding} is not a valid charset name or not supported
* the {@link Charset#defaultCharset()} is used.
*
* <p>The reader should be {@linkplain BufferedReader#close closed}
* when it is no longer needed.
*
* @apiNote
* Use either this method or the {@linkplain #getInputStream input stream}
* but not both on the same {@code Process}.
* The input reader consumes and buffers bytes from the input stream.
* Bytes read from the input stream would not be seen by the reader and the
* buffer contents are unpredictable.
*
* @return a {@link BufferedReader BufferedReader} using the
* {@code native.encoding} if supported, otherwise, the
* {@link Charset#defaultCharset()}
@@ -238,6 +302,9 @@ public abstract class Process {
* then the {@code InputStreamReader} will be reading from a
* <a href="ProcessBuilder.html#redirect-output">null input stream</a>.
*
* <p>The reader should be {@linkplain BufferedReader#close closed}
* when it is no longer needed.
*
* <p>Otherwise, if the standard error of the process has been redirected using
* {@link ProcessBuilder#redirectErrorStream(boolean)
* ProcessBuilder.redirectErrorStream} then the input reader returned by
@@ -245,9 +312,11 @@ public abstract class Process {
* of the process.
*
* @apiNote
* Using both {@link #getInputStream} and {@link #inputReader(Charset)} has
* unpredictable behavior since the buffered reader reads ahead from the
* input stream.
* Use either this method or the {@linkplain #getInputStream input stream}
* but not both on the same {@code Process}.
* The input reader consumes and buffers bytes from the input stream.
* Bytes read from the input stream would not be seen by the reader and the
* buffer contents are unpredictable.
*
* <p>When the process has terminated, and the standard input has not been redirected,
* reading of the bytes available from the underlying stream is on a best effort basis and
@@ -283,6 +352,16 @@ public abstract class Process {
* If the {@code native.encoding} is not a valid charset name or not supported
* the {@link Charset#defaultCharset()} is used.
*
* <p>The error reader should be {@linkplain BufferedReader#close closed}
* when it is no longer needed.
*
* @apiNote
* Use either this method or the {@linkplain #getErrorStream error stream}
* but not both on the same {@code Process}.
* The error reader consumes and buffers bytes from the error stream.
* Bytes read from the error stream would not be seen by the reader and the
* buffer contents are unpredictable.
*
* @return a {@link BufferedReader BufferedReader} using the
* {@code native.encoding} if supported, otherwise, the
* {@link Charset#defaultCharset()}
@@ -314,10 +393,15 @@ public abstract class Process {
* then the {@code InputStreamReader} will be reading from a
* <a href="ProcessBuilder.html#redirect-output">null input stream</a>.
*
* <p>The error reader should be {@linkplain BufferedReader#close closed}
* when it is no longer needed.
*
* @apiNote
* Using both {@link #getErrorStream} and {@link #errorReader(Charset)} has
* unpredictable behavior since the buffered reader reads ahead from the
* error stream.
* Use either this method or the {@linkplain #getErrorStream error stream}
* but not both on the same {@code Process}.
* The error reader consumes and buffers bytes from the error stream.
* Bytes read from the error stream would not be seen by the reader and the
* buffer contents are unpredictable.
*
* <p>When the process has terminated, and the standard error has not been redirected,
* reading of the bytes available from the underlying stream is on a best effort basis and
@@ -346,7 +430,7 @@ public abstract class Process {
/**
* Returns a {@code BufferedWriter} connected to the normal input of the process
* using the native encoding.
* Writes text to a character-output stream, buffering characters so as to provide
* Writes text to a character-output stream, buffering characters to provide
* for the efficient writing of single characters, arrays, and strings.
*
* <p>This method delegates to {@link #outputWriter(Charset)} using the
@@ -354,6 +438,9 @@ public abstract class Process {
* If the {@code native.encoding} is not a valid charset name or not supported
* the {@link Charset#defaultCharset()} is used.
*
* <p>The output writer should be {@linkplain BufferedWriter#close closed}
* when it is no longer needed.
*
* @return a {@code BufferedWriter} to the standard input of the process using the charset
* for the {@code native.encoding} system property
* @since 17
@@ -365,7 +452,7 @@ public abstract class Process {
/**
* Returns a {@code BufferedWriter} connected to the normal input of the process
* using a Charset.
* Writes text to a character-output stream, buffering characters so as to provide
* Writes text to a character-output stream, buffering characters to provide
* for the efficient writing of single characters, arrays, and strings.
*
* <p>Characters written by the writer are encoded to bytes using {@link OutputStreamWriter}
@@ -383,6 +470,9 @@ public abstract class Process {
* ProcessBuilder.redirectInput} then the {@code OutputStreamWriter} writes to a
* <a href="ProcessBuilder.html#redirect-input">null output stream</a>.
*
* <p>The output writer should be {@linkplain BufferedWriter#close closed}
* when it is no longer needed.
*
* @apiNote
* A {@linkplain BufferedWriter} writes characters, arrays of characters, and strings.
* Wrapping the {@link BufferedWriter} with a {@link PrintWriter} provides
@@ -674,11 +764,12 @@ public abstract class Process {
* free the current thread and block only if and when the value is needed.
* <br>
* For example, launching a process to compare two files and get a boolean if they are identical:
* <pre> {@code Process p = new ProcessBuilder("cmp", "f1", "f2").start();
* Future<Boolean> identical = p.onExit().thenApply(p1 -> p1.exitValue() == 0);
* ...
* if (identical.get()) { ... }
* }</pre>
* {@snippet lang = "java" :
* Process p = new ProcessBuilder("cmp", "f1", "f2").start();
* Future<Boolean> identical = p.onExit().thenApply(p1 -> p1.exitValue() == 0);
* ...
* if (identical.get()) { ... }
* }
*
* @implSpec
* This implementation executes {@link #waitFor()} in a separate thread
@@ -695,11 +786,11 @@ public abstract class Process {
* External implementations should override this method and provide
* a more efficient implementation. For example, to delegate to the underlying
* process, it can do the following:
* <pre>{@code
* {@snippet lang = "java" :
* public CompletableFuture<Process> onExit() {
* return delegate.onExit().thenApply(p -> this);
* }
* }</pre>
* }
* @apiNote
* The process may be observed to have terminated with {@link #isAlive}
* before the ComputableFuture is completed and dependent actions are invoked.

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 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
@@ -150,30 +150,33 @@ import jdk.internal.event.ProcessStartEvent;
* <p>Starting a new process which uses the default working directory
* and environment is easy:
*
* <pre> {@code
* {@snippet lang = "java" :
* Process p = new ProcessBuilder("myCommand", "myArg").start();
* }</pre>
* }
*
* <p>Here is an example that starts a process with a modified working
* directory and environment, and redirects standard output and error
* to be appended to a log file:
*
* <pre> {@code
* ProcessBuilder pb =
* new ProcessBuilder("myCommand", "myArg1", "myArg2");
* Map<String, String> env = pb.environment();
* env.put("VAR1", "myValue");
* env.remove("OTHERVAR");
* env.put("VAR2", env.get("VAR1") + "suffix");
* pb.directory(new File("myDir"));
* File log = new File("log");
* pb.redirectErrorStream(true);
* pb.redirectOutput(Redirect.appendTo(log));
* Process p = pb.start();
* assert pb.redirectInput() == Redirect.PIPE;
* assert pb.redirectOutput().file() == log;
* assert p.getInputStream().read() == -1;
* }</pre>
* {@snippet lang = "java":
* ProcessBuilder pb = new ProcessBuilder("myCommand", "myArg1", "myArg2");
* Map<String, String> env = pb.environment();
* env.put("VAR1", "myValue");
* env.remove("OTHERVAR");
* env.put("VAR2", env.get("VAR1") + "suffix");
*
* pb.directory(new File("myDir"));
* File log = new File("log");
* pb.redirectErrorStream(true);
* pb.redirectOutput(Redirect.appendTo(log));
*
* Process p = pb.start();
* assert pb.redirectInput() == Redirect.PIPE;
* assert pb.redirectOutput().file() == log;
* assert p.getInputStream().read() == -1;
* }
*
* <p>To start a process with an explicit set of environment
* variables, first call {@link java.util.Map#clear() Map.clear()}
@@ -506,10 +509,10 @@ public final class ProcessBuilder
* This is the default handling of subprocess standard I/O.
*
* <p>It will always be true that
* <pre> {@code
* Redirect.PIPE.file() == null &&
* Redirect.PIPE.type() == Redirect.Type.PIPE
* }</pre>
* {@snippet lang = "java" :
* Redirect.PIPE.file() == null &&
* Redirect.PIPE.type() == Redirect.Type.PIPE
* }
*/
public static final Redirect PIPE = new Redirect() {
public Type type() { return Type.PIPE; }
@@ -521,10 +524,10 @@ public final class ProcessBuilder
* behavior of most operating system command interpreters (shells).
*
* <p>It will always be true that
* <pre> {@code
* Redirect.INHERIT.file() == null &&
* Redirect.INHERIT.type() == Redirect.Type.INHERIT
* }</pre>
* {@snippet lang = "java" :
* Redirect.INHERIT.file() == null &&
* Redirect.INHERIT.type() == Redirect.Type.INHERIT
* }
*/
public static final Redirect INHERIT = new Redirect() {
public Type type() { return Type.INHERIT; }
@@ -537,11 +540,10 @@ public final class ProcessBuilder
* an operating system specific "null file".
*
* <p>It will always be true that
* <pre> {@code
* Redirect.DISCARD.file() is the filename appropriate for the operating system
* and may be null &&
* Redirect.DISCARD.type() == Redirect.Type.WRITE
* }</pre>
* {@snippet lang = "java" :
* Redirect.DISCARD.file() != null && // is the filename appropriate for the operating system
* Redirect.DISCARD.type() == Redirect.Type.WRITE;
* }
* @since 9
*/
public static final Redirect DISCARD = new Redirect() {
@@ -572,10 +574,10 @@ public final class ProcessBuilder
* Returns a redirect to read from the specified file.
*
* <p>It will always be true that
* <pre> {@code
* Redirect.from(file).file() == file &&
* Redirect.from(file).type() == Redirect.Type.READ
* }</pre>
* {@snippet lang = "java" :
* Redirect.from(file).file() == file &&
* Redirect.from(file).type() == Redirect.Type.READ
* }
*
* @param file The {@code File} for the {@code Redirect}.
* @return a redirect to read from the specified file
@@ -598,10 +600,10 @@ public final class ProcessBuilder
* its previous contents will be discarded.
*
* <p>It will always be true that
* <pre> {@code
* Redirect.to(file).file() == file &&
* Redirect.to(file).type() == Redirect.Type.WRITE
* }</pre>
* {@snippet lang = "java" :
* Redirect.to(file).file() == file &&
* Redirect.to(file).type() == Redirect.Type.WRITE
* }
*
* @param file The {@code File} for the {@code Redirect}.
* @return a redirect to write to the specified file
@@ -628,10 +630,10 @@ public final class ProcessBuilder
* system-dependent and therefore unspecified.
*
* <p>It will always be true that
* <pre> {@code
* Redirect.appendTo(file).file() == file &&
* Redirect.appendTo(file).type() == Redirect.Type.APPEND
* }</pre>
* {@snippet lang = "java" :
* Redirect.appendTo(file).file() == file &&
* Redirect.appendTo(file).type() == Redirect.Type.APPEND
* }
*
* @param file The {@code File} for the {@code Redirect}.
* @return a redirect to append to the specified file
@@ -914,15 +916,15 @@ public final class ProcessBuilder
* to be the same as those of the current Java process.
*
* <p>This is a convenience method. An invocation of the form
* <pre> {@code
* pb.inheritIO()
* }</pre>
* {@snippet lang = "java" :
* pb.inheritIO()
* }
* behaves in exactly the same way as the invocation
* <pre> {@code
* pb.redirectInput(Redirect.INHERIT)
* .redirectOutput(Redirect.INHERIT)
* .redirectError(Redirect.INHERIT)
* }</pre>
* {@snippet lang = "java" :
* pb.redirectInput(Redirect.INHERIT)
* .redirectOutput(Redirect.INHERIT)
* .redirectError(Redirect.INHERIT)
* }
*
* This gives behavior equivalent to most operating system
* command interpreters, or the standard C library function
@@ -1176,22 +1178,21 @@ public final class ProcessBuilder
* @apiNote
* For example to count the unique imports for all the files in a file hierarchy
* on a Unix compatible platform:
* <pre>{@code
* String directory = "/home/duke/src";
* ProcessBuilder[] builders = {
* {@snippet lang = "java" :
* String directory = "/home/duke/src";
* ProcessBuilder[] builders = {
* new ProcessBuilder("find", directory, "-type", "f"),
* new ProcessBuilder("xargs", "grep", "-h", "^import "),
* new ProcessBuilder("awk", "{print $2;}"),
* new ProcessBuilder("sort", "-u")};
* List<Process> processes = ProcessBuilder.startPipeline(
* Arrays.asList(builders));
* Process last = processes.get(processes.size()-1);
* try (InputStream is = last.getInputStream();
* List<Process> processes = ProcessBuilder.startPipeline( Arrays.asList(builders));
* Process last = processes.get(processes.size() - 1);
* try (InputStream is = last.getInputStream();
* Reader isr = new InputStreamReader(is);
* BufferedReader r = new BufferedReader(isr)) {
* long count = r.lines().count();
* long count = r.lines().count();
* }
* }
* }</pre>
*
* @param builders a List of ProcessBuilders
* @return a {@code List<Process>}es started from the corresponding

View File

@@ -1589,6 +1589,11 @@ public final class String
* @return {@code true} if {@link #length()} is {@code 0}, otherwise
* {@code false}
*
* @apiNote
* To determine whether a string contains only
* {@linkplain Character#isWhitespace(int) white space}, use
* {@link #isBlank() isBlank}.
*
* @since 1.6
*/
@Override
@@ -3827,9 +3832,13 @@ public final class String
* begins with the character at index <i>k</i> and ends with the
* character at index <i>m</i>-that is, the result of
* {@code this.substring(k, m + 1)}.
* <p>
* This method may be used to trim space (as defined above) from
* the beginning and end of a string.
*
* @apiNote
* This method removes leading and trailing space characters and ASCII control
* characters from the string. To remove characters using a Unicode-based definition of
* {@linkplain Character#isWhitespace(int) white space}, use {@link #strip() strip},
* {@link #stripIndent() stripIndent}, {@link #stripLeading() stripLeading}, or
* {@link #stripTrailing() stripTrailing}.
*
* @return a string whose value is this string, with all leading
* and trailing space removed, or this string if it
@@ -3934,13 +3943,9 @@ public final class String
}
/**
* Returns {@code true} if the string is empty or contains only
* {@linkplain Character#isWhitespace(int) white space} codepoints,
* otherwise {@code false}.
*
* @return {@code true} if the string is empty or contains only
* {@linkplain Character#isWhitespace(int) white space} codepoints,
* otherwise {@code false}
* {@return {@code true} if the string is {@linkplain #isEmpty empty} or contains
* only {@linkplain Character#isWhitespace(int) white space} codepoints,
* otherwise {@code false}}
*
* @see Character#isWhitespace(int)
*

View File

@@ -81,24 +81,24 @@ import java.util.Objects;
* {@link PEMRecord}.
*
* <p> The {@linkplain #decode(String, Class)} and
* {@linkplain #decode(InputStream, Class)} methods take a Class parameter
* {@linkplain #decode(InputStream, Class)} methods take a class parameter
* which determines the type of {@code DEREncodable} that is returned. These
* methods are useful when extracting or changing the return class.
* For example, if the PEM contains both public and private keys, the
* Class parameter can specify which to return. Use
* class parameter can specify which to return. Use
* {@code PrivateKey.class} to return only the private key.
* If the Class parameter is set to {@code X509EncodedKeySpec.class}, the
* If the class parameter is set to {@code X509EncodedKeySpec.class}, the
* public key will be returned in that format. Any type of PEM data can be
* decoded into a {@code PEMRecord} by specifying {@code PEMRecord.class}.
* If the Class parameter doesn't match the PEM content, an
* {@code IllegalArgumentException} will be thrown.
* If the class parameter doesn't match the PEM content, a
* {@linkplain ClassCastException} will be thrown.
*
* <p> A new {@code PEMDecoder} instance is created when configured
* with {@linkplain #withFactory(Provider)} and/or
* {@linkplain #withDecryption(char[])}. {@linkplain #withFactory(Provider)}
* configures the decoder to use only {@linkplain KeyFactory} and
* {@linkplain CertificateFactory} instances from the given {@code Provider}.
* {@link#withDecryption(char[])} configures the decoder to decrypt all
* {@linkplain #withDecryption(char[])} configures the decoder to decrypt all
* encrypted private key PEM data using the given password.
* Configuring an instance for decryption does not prevent decoding with
* unencrypted PEM. Any encrypted PEM that fails decryption
@@ -117,15 +117,15 @@ import java.util.Objects;
* <p> Here is an example of a {@code PEMDecoder} configured with decryption
* and a factory provider:
* {@snippet lang = java:
* PEMDecoder pe = PEMDecoder.of().withDecryption(password).
* PEMDecoder pd = PEMDecoder.of().withDecryption(password).
* withFactory(provider);
* byte[] pemData = pe.decode(privKey);
* byte[] pemData = pd.decode(privKey);
* }
*
* @implNote An implementation may support other PEM types and
* {@code DEREncodables}. This implementation additionally supports PEM types:
* {@code X509 CERTIFICATE}, {@code X.509 CERTIFICATE}, {@code CRL},
* and {@code RSA PRIVATE KEY}.
* {@code DEREncodable} objects. This implementation additionally supports
* the following PEM types: {@code X509 CERTIFICATE},
* {@code X.509 CERTIFICATE}, {@code CRL}, and {@code RSA PRIVATE KEY}.
*
* @see PEMEncoder
* @see PEMRecord
@@ -179,13 +179,13 @@ public final class PEMDecoder {
return switch (pem.type()) {
case Pem.PUBLIC_KEY -> {
X509EncodedKeySpec spec =
new X509EncodedKeySpec(decoder.decode(pem.pem()));
new X509EncodedKeySpec(decoder.decode(pem.content()));
yield getKeyFactory(
KeyUtil.getAlgorithm(spec.getEncoded())).
generatePublic(spec);
}
case Pem.PRIVATE_KEY -> {
PKCS8Key p8key = new PKCS8Key(decoder.decode(pem.pem()));
PKCS8Key p8key = new PKCS8Key(decoder.decode(pem.content()));
String algo = p8key.getAlgorithm();
KeyFactory kf = getKeyFactory(algo);
DEREncodable d = kf.generatePrivate(
@@ -216,27 +216,27 @@ public final class PEMDecoder {
case Pem.ENCRYPTED_PRIVATE_KEY -> {
if (password == null) {
yield new EncryptedPrivateKeyInfo(decoder.decode(
pem.pem()));
pem.content()));
}
yield new EncryptedPrivateKeyInfo(decoder.decode(pem.pem())).
yield new EncryptedPrivateKeyInfo(decoder.decode(pem.content())).
getKey(password.getPassword());
}
case Pem.CERTIFICATE, Pem.X509_CERTIFICATE,
Pem.X_509_CERTIFICATE -> {
CertificateFactory cf = getCertFactory("X509");
yield (X509Certificate) cf.generateCertificate(
new ByteArrayInputStream(decoder.decode(pem.pem())));
new ByteArrayInputStream(decoder.decode(pem.content())));
}
case Pem.X509_CRL, Pem.CRL -> {
CertificateFactory cf = getCertFactory("X509");
yield (X509CRL) cf.generateCRL(
new ByteArrayInputStream(decoder.decode(pem.pem())));
new ByteArrayInputStream(decoder.decode(pem.content())));
}
case Pem.RSA_PRIVATE_KEY -> {
KeyFactory kf = getKeyFactory("RSA");
yield kf.generatePrivate(
RSAPrivateCrtKeyImpl.getKeySpec(decoder.decode(
pem.pem())));
pem.content())));
}
default -> pem;
};
@@ -271,7 +271,6 @@ public final class PEMDecoder {
*/
public DEREncodable decode(String str) {
Objects.requireNonNull(str);
DEREncodable de;
try {
return decode(new ByteArrayInputStream(
str.getBytes(StandardCharsets.UTF_8)));
@@ -483,9 +482,6 @@ public final class PEMDecoder {
* from the specified {@link Provider} to produce cryptographic objects.
* Any errors using the {@code Provider} will occur during decoding.
*
* <p>If {@code provider} is {@code null}, a new instance is returned with
* the default provider configuration.
*
* @param provider the factory provider
* @return a new PEMEncoder instance configured to the {@code Provider}.
* @throws NullPointerException if {@code provider} is null

View File

@@ -71,7 +71,7 @@ import java.util.concurrent.locks.ReentrantLock;
* OneAsymmetricKey structure using the "PRIVATE KEY" type.
*
* <p> When encoding a {@link PEMRecord}, the API surrounds the
* {@linkplain PEMRecord#pem()} with the PEM header and footer
* {@linkplain PEMRecord#content()} with the PEM header and footer
* from {@linkplain PEMRecord#type()}. {@linkplain PEMRecord#leadingData()} is
* not included in the encoding. {@code PEMRecord} will not perform
* validity checks on the data.
@@ -108,7 +108,8 @@ import java.util.concurrent.locks.ReentrantLock;
* byte[] pemData = pe.encode(privKey);
* }
*
* @implNote An implementation may support other PEM types and DEREncodables.
* @implNote An implementation may support other PEM types and
* {@code DEREncodable} objects.
*
*
* @see PEMDecoder
@@ -287,7 +288,7 @@ public final class PEMEncoder {
}
// If `keySpec` is non-null, then `key` hasn't been established.
// Setting a `key' prevents repeated key generations operations.
// Setting a `key` prevents repeated key generation operations.
// withEncryption() is a configuration method and cannot throw an
// exception; therefore generation is delayed.
if (keySpec != null) {

View File

@@ -29,7 +29,6 @@ import jdk.internal.javac.PreviewFeature;
import sun.security.util.Pem;
import java.util.Base64;
import java.util.Objects;
/**
@@ -39,20 +38,20 @@ import java.util.Objects;
* cryptographic object is not desired or the type has no
* {@code DEREncodable}.
*
* <p> {@code type} and {@code pem} may not be {@code null}.
* <p> {@code type} and {@code content} may not be {@code null}.
* {@code leadingData} may be null if no non-PEM data preceded PEM header
* during decoding. {@code leadingData} may be useful for reading metadata
* that accompanies PEM data.
*
* <p> No validation is performed during instantiation to ensure that
* {@code type} conforms to {@code RFC 7468}, that {@code pem} is valid Base64,
* or that {@code pem} matches the {@code type}. {@code leadingData} is not
* defensively copied and does not return a clone when
* {@linkplain #leadingData()} is called.
* {@code type} conforms to {@code RFC 7468}, that {@code content} is valid
* Base64, or that {@code content} matches the {@code type}.
* {@code leadingData} is not defensively copied and does not return a
* clone when {@linkplain #leadingData()} is called.
*
* @param type the type identifier in the PEM header without PEM syntax labels.
* For a public key, {@code type} would be "PUBLIC KEY".
* @param pem any data between the PEM header and footer.
* @param content the Base64-encoded data, excluding the PEM header and footer
* @param leadingData any non-PEM data preceding the PEM header when decoding.
*
* @spec https://www.rfc-editor.org/info/rfc7468
@@ -64,25 +63,25 @@ import java.util.Objects;
* @since 25
*/
@PreviewFeature(feature = PreviewFeature.Feature.PEM_API)
public record PEMRecord(String type, String pem, byte[] leadingData)
public record PEMRecord(String type, String content, byte[] leadingData)
implements DEREncodable {
/**
* Creates a {@code PEMRecord} instance with the given parameters.
*
* @param type the type identifier
* @param pem the Base64-encoded data encapsulated by the PEM header and
* footer.
* @param content the Base64-encoded data, excluding the PEM header and
* footer
* @param leadingData any non-PEM data read during the decoding process
* before the PEM header. This value maybe {@code null}.
* @throws IllegalArgumentException if the {@code type} is incorrectly
* @throws IllegalArgumentException if {@code type} is incorrectly
* formatted.
* @throws NullPointerException if {@code type} and/or {@code pem} are
* @throws NullPointerException if {@code type} and/or {@code content} are
* {@code null}.
*/
public PEMRecord(String type, String pem, byte[] leadingData) {
public PEMRecord {
Objects.requireNonNull(type, "\"type\" cannot be null.");
Objects.requireNonNull(pem, "\"pem\" cannot be null.");
Objects.requireNonNull(content, "\"content\" cannot be null.");
// With no validity checking on `type`, the constructor accept anything
// including lowercase. The onus is on the caller.
@@ -92,37 +91,22 @@ public record PEMRecord(String type, String pem, byte[] leadingData)
"Only the PEM type identifier is allowed");
}
this.type = type;
this.pem = pem;
this.leadingData = leadingData;
}
/**
* Creates a {@code PEMRecord} instance with a given {@code type} and
* {@code pem} data in String form. {@code leadingData} is set to null.
* {@code content} data in String form. {@code leadingData} is set to null.
*
* @param type the PEM type identifier
* @param pem the Base64-encoded data encapsulated by the PEM header and
* footer.
* @throws IllegalArgumentException if the {@code type} is incorrectly
* @param content the Base64-encoded data, excluding the PEM header and
* footer
* @throws IllegalArgumentException if {@code type} is incorrectly
* formatted.
* @throws NullPointerException if {@code type} and/or {@code pem} are
* @throws NullPointerException if {@code type} and/or {@code content} are
* {@code null}.
*/
public PEMRecord(String type, String pem) {
this(type, pem, null);
}
/**
* Returns the binary encoding from the Base64 data contained in
* {@code pem}.
*
* @throws IllegalArgumentException if {@code pem} cannot be decoded.
* @return a new array of the binary encoding each time this
* method is called.
*/
public byte[] getEncoded() {
return Base64.getMimeDecoder().decode(pem);
public PEMRecord(String type, String content) {
this(type, content, null);
}
/**

View File

@@ -177,8 +177,11 @@ public class ThreadDumper {
container.children().forEach(c -> dumpThreads(c, writer));
}
private static void dumpThread(Thread thread, TextWriter writer) {
private static boolean dumpThread(Thread thread, TextWriter writer) {
ThreadSnapshot snapshot = ThreadSnapshot.of(thread);
if (snapshot == null) {
return false; // thread terminated
}
Instant now = Instant.now();
Thread.State state = snapshot.threadState();
writer.println("#" + thread.threadId() + " \"" + snapshot.threadName()
@@ -217,6 +220,7 @@ public class ThreadDumper {
depth++;
}
writer.println();
return true;
}
/**
@@ -284,8 +288,9 @@ public class ThreadDumper {
Iterator<Thread> threads = container.threads().iterator();
while (threads.hasNext()) {
Thread thread = threads.next();
dumpThread(thread, jsonWriter);
threadCount++;
if (dumpThread(thread, jsonWriter)) {
threadCount++;
}
}
jsonWriter.endArray(); // threads
@@ -303,11 +308,15 @@ public class ThreadDumper {
/**
* Write a thread to the given JSON writer.
* @return true if the thread dump was written, false otherwise
* @throws UncheckedIOException if an I/O error occurs
*/
private static void dumpThread(Thread thread, JsonWriter jsonWriter) {
private static boolean dumpThread(Thread thread, JsonWriter jsonWriter) {
Instant now = Instant.now();
ThreadSnapshot snapshot = ThreadSnapshot.of(thread);
if (snapshot == null) {
return false; // thread terminated
}
Thread.State state = snapshot.threadState();
StackTraceElement[] stackTrace = snapshot.stackTrace();
@@ -369,6 +378,7 @@ public class ThreadDumper {
}
jsonWriter.endObject();
return true;
}
/**

View File

@@ -52,12 +52,14 @@ class ThreadSnapshot {
/**
* Take a snapshot of a Thread to get all information about the thread.
* Return null if a ThreadSnapshot is not created, for example if the
* thread has terminated.
* @throws UnsupportedOperationException if not supported by VM
*/
static ThreadSnapshot of(Thread thread) {
ThreadSnapshot snapshot = create(thread);
if (snapshot == null) {
throw new UnsupportedOperationException();
return null; // thread terminated
}
if (snapshot.stackTrace == null) {
snapshot.stackTrace = EMPTY_STACK;

View File

@@ -1,5 +1,5 @@
#
# Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2007, 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
@@ -34,8 +34,8 @@ java.launcher.opt.footer = \ -cp <Klassensuchpfad mit Verzeichnissen und ZIP-
Granularität\n -da[:<packagename>...|:<classname>]\n -disableassertions[:<packagename>...|:<classname>]\n Deaktiviert Assertions mit angegebener Granularität\n -esa | -enablesystemassertions\n Aktiviert System-Assertions\n -dsa | -disablesystemassertions\n Deaktiviert System-Assertions\n -agentlib:<libname>[=<options>]\n Lädt die native Agent Library <libname>. Beispiel: -agentlib:jdwp\n siehe auch -agentlib:jdwp=help\n -agentpath:<pathname>[=<options>]\n Lädt die native Agent Library mit dem vollständigen Pfadnamen\n -javaagent:<jarpath>[=<options>]\n Lädt den Java-Programmiersprachen-Agent, siehe java.lang.instrument\n -splash:<imagepath>\n Zeigt den Startbildschirm mit einem angegebenen Bild an\n Skalierte HiDPI-Bilder werden automatisch unterstützt und verwendet,\n falls verfügbar. Der nicht skalierte Bilddateiname (Beispiel: image.ext)\n muss immer als Argument an die Option "-splash" übergeben werden.\n Das am besten geeignete angegebene skalierte Bild wird\n automatisch ausgewählt.\n Weitere Informationen finden Sie in der Dokumentation zur SplashScreen-API\n @argument files\n Eine oder mehrere Argumentdateien mit Optionen\n --disable-@files\n Verhindert die weitere Erweiterung von Argumentdateien\n --enable-preview\n Lässt zu, das Klassen von Vorschaufeatures dieses Release abhängig sind\nUm ein Argument für eine lange Option anzugeben, können Sie --<Name>=<Wert> oder\n--<Name> <Wert> verwenden.\n
# Translators please note do not translate the options themselves
java.launcher.X.usage=\n -Xbatch Deaktiviert die Hintergrundkompilierung\n -Xbootclasspath/a:<durch {0} getrennte Verzeichnisse und ZIP-/JAR-Dateien>\n An das Ende des Bootstrap Classpaths anhängen\n -Xcheck:jni Führt zusätzliche Prüfungen für JNI-Funktionen aus\n -Xcomp Erzwingt die Kompilierung von Methoden beim ersten Aufruf\n -Xdebug Führt keine Aktion aus. Ist veraltet und wird in einem zukünftigen Release entfernt.\n -Xdiag Zeigt zusätzliche Diagnosemeldungen an\n -Xint Nur Ausführung im interpretierten Modus\n -Xinternalversion\n Zeigt detailliertere JVM-Versionsinformationen an als die\n Option -version\n -Xlog:<Optionen> Konfiguriert oder aktiviert Logging mit dem einheitlichen Java Virtual\n Machine-(JVM-)Logging-Framework. Verwenden Sie -Xlog:help\n für weitere Einzelheiten.\n -Xloggc:<Datei> Protokolliert den GC-Status in einer Datei mit Zeitstempeln.\n Diese Option ist veraltet und kann in einem\n zukünftigen Release entfernt werden. Wird durch -Xlog:gc:<Datei> ersetzt.\n -Xmixed Ausführung im gemischten Modus (Standard)\n -Xmn<Größe> Legt die anfängliche und maximale Größe (in Byte) des Heaps\n für die Young Generation (Nursery) fest\n -Xms<Größe> Legt die anfängliche Java-Heap-Größe fest\n -Xmx<Größe> Legt die maximale Java-Heap-Größe fest\n -Xnoclassgc Deaktiviert die Klassen-Garbage Collection\n -Xrs Reduziert die Verwendung von BS-Signalen durch Java/VM (siehe Dokumentation)\n -Xshare:auto Verwendet freigegebene Klassendaten, wenn möglich (Standard)\n -Xshare:off Versucht nicht, freigegebene Klassendaten zu verwenden\n -Xshare:on Erfordert die Verwendung freigegebener Klassendaten, verläuft sonst nicht erfolgreich.\n Diese Testoption kann zeitweise zu\n Fehlern führen. Sie darf nicht in Produktionsumgebungen verwendet werden.\n -XshowSettings Zeigt alle Einstellungen an und fährt fort\n -XshowSettings:all\n Zeigt alle Einstellungen als Verbose-Ausgabe an und fährt fort\n -XshowSettings:locale\n Zeigt alle gebietsschemabezogenen Einstellungen an und fährt fort\n -XshowSettings:properties\n Zeigt alle Eigenschaftseinstellungen an und fährt fort\n -XshowSettings:vm\n Zeigt alle VM-bezogenen Einstellungen an und fährt fort\n -XshowSettings:security\n Zeigt alle Sicherheitseinstellungen an und fährt fort\n -XshowSettings:security:all\n Zeigt alle Sicherheitseinstellungen an und fährt fort\n -XshowSettings:security:properties\n Zeigt Sicherheitseigenschaften an und fährt fort\n -XshowSettings:security:providers\n Zeigt statische Sicherheitsprovidereinstellungen an und fährt fort\n -XshowSettings:security:tls\n Zeigt TLS-bezogene Sicherheitseinstellungen an und fährt fort\n -XshowSettings:system\n (Nur Linux) Zeigt die Konfiguration des Hostsystems oder Containers an\n und fährt fort\n -Xss<Größe> Legt die Stackgröße des Java-Threads fest\n Die tatsächliche Größe kann auf ein Vielfaches der\n Systemseitengröße aufgerundet werden, wenn für das Betriebssystem erforderlich.\n -Xverify Legt den Modus der Bytecodeverifizierung fest\n \
Beachten Sie, dass die Option -Xverify:none veraltet ist und\n in einem zukünftigen Release entfernt werden kann.\n --add-reads <Modul>=<Zielmodul>(,<Zielmodul>)*\n Aktualisiert <Modul>, damit <Zielmodul> gelesen wird, ungeachtet\n der Moduldeklaration. \n <Zielmodul> kann ALL-UNNAMED sein, um alle unbenannten\n Module zu lesen.\n --add-exports <Modul>/<Package>=<Zielmodul>(,<Zielmodul>)*\n Aktualisiert <Modul>, um <Package> in <Zielmodul> zu exportieren,\n ungeachtet der Moduldeklaration.\n <Zielmodul> kann ALL-UNNAMED sein, um in alle\n unbenannten Module zu exportieren.\n --add-opens <Modul>/<Package>=<Zielmodul>(,<Zielmodul>)*\n Aktualisiert <Modul>, um <Package> in\n <Zielmodul> zu öffnen, ungeachtet der Moduldeklaration.\n --limit-modules <Modulname>[,<Modulname>...]\n Grenzt die Gesamtmenge der beobachtbaren Module ein\n --patch-module <Modul>=<Datei>({0}<Datei>)*\n Überschreibt oder erweitert ein Modul mit Klassen und Ressourcen\n in JAR-Dateien oder Verzeichnissen.\n --source <Version>\n Legt die Version der Quelle im Quelldateimodus fest.\n --finalization=<Wert>\n Steuert, ob die JVM Objekte finalisiert.\n Dabei ist <Wert> entweder "enabled" oder "disabled".\n Die Finalisierung ist standardmäßig aktiviert.\n --sun-misc-unsafe-memory-access=<value>\n Verwendung der nicht unterstützten API sun.misc.Unsafe zulassen oder verweigern\n <value> ist "allow", "warn", "debug" oder "deny".\n Der Standardwert ist "warn".\n\nDiese zusätzlichen Optionen können jederzeit ohne vorherige Ankündigung geändert werden.\n
java.launcher.X.usage=\n -Xbatch Deaktiviert die Hintergrundkompilierung\n -Xbootclasspath/a:<durch {0} getrennte Verzeichnisse und ZIP-/JAR-Dateien>\n An das Ende des Bootstrap Classpaths anhängen\n -Xcheck:jni Führt zusätzliche Prüfungen für JNI-Funktionen aus\n -Xcomp Erzwingt die Kompilierung von Methoden beim ersten Aufruf\n -Xdebug Führt keine Aktion aus. Ist veraltet und wird in einem zukünftigen Release entfernt.\n -Xdiag Zeigt zusätzliche Diagnosemeldungen an\n -Xint Nur Ausführung im interpretierten Modus\n -Xinternalversion\n Zeigt detailliertere JVM-Versionsinformationen an als die\n Option -version\n -Xlog:<Optionen> Konfiguriert oder aktiviert Logging mit dem einheitlichen Java Virtual\n Machine-(JVM-)Logging-Framework. Verwenden Sie -Xlog:help\n für weitere Einzelheiten.\n -Xloggc:<Datei> Protokolliert den GC-Status in einer Datei mit Zeitstempeln.\n Diese Option ist veraltet und kann in einem\n zukünftigen Release entfernt werden. Wird durch -Xlog:gc:<Datei> ersetzt.\n -Xmixed Ausführung im gemischten Modus (Standard)\n -Xmn<Größe> Legt die anfängliche und maximale Größe (in Byte) des Heaps\n für die Young Generation (Nursery) fest\n -Xms<size> Legt die minimale und die anfängliche Java-Heap-Größe fest\n -Xmx<Größe> Legt die maximale Java-Heap-Größe fest\n -Xnoclassgc Deaktiviert die Klassen-Garbage Collection\n -Xrs Reduziert die Verwendung von BS-Signalen durch Java/VM (siehe Dokumentation)\n -Xshare:auto Verwendet freigegebene Klassendaten, wenn möglich (Standard)\n -Xshare:off Versucht nicht, freigegebene Klassendaten zu verwenden\n -Xshare:on Erfordert die Verwendung freigegebener Klassendaten, verläuft sonst nicht erfolgreich.\n Diese Testoption kann zeitweise zu\n Fehlern führen. Sie darf nicht in Produktionsumgebungen verwendet werden.\n -XshowSettings Zeigt alle Einstellungen an und fährt fort\n -XshowSettings:all\n Zeigt alle Einstellungen als Verbose-Ausgabe an und fährt fort\n -XshowSettings:locale\n Zeigt alle gebietsschemabezogenen Einstellungen an und fährt fort\n -XshowSettings:properties\n Zeigt alle Eigenschaftseinstellungen an und fährt fort\n -XshowSettings:vm\n Zeigt alle VM-bezogenen Einstellungen an und fährt fort\n -XshowSettings:security\n Zeigt alle Sicherheitseinstellungen an und fährt fort\n -XshowSettings:security:all\n Zeigt alle Sicherheitseinstellungen an und fährt fort\n -XshowSettings:security:properties\n Zeigt Sicherheitseigenschaften an und fährt fort\n -XshowSettings:security:providers\n Zeigt statische Sicherheitsprovidereinstellungen an und fährt fort\n -XshowSettings:security:tls\n Zeigt TLS-bezogene Sicherheitseinstellungen an und fährt fort\n -XshowSettings:system\n (Nur Linux) Zeigt die Konfiguration des Hostsystems oder Containers an\n und fährt fort\n -Xss<Größe> Legt die Stackgröße des Java-Threads fest\n Die tatsächliche Größe kann auf ein Vielfaches der\n Systemseitengröße aufgerundet werden, wenn für das Betriebssystem erforderlich.\n -Xverify Legt den Modus der Bytecodeverifizierung fest\n \
Beachten Sie, dass die Option -Xverify:none veraltet ist und\n in einem zukünftigen Release entfernt werden kann.\n --add-reads <Modul>=<Zielmodul>(,<Zielmodul>)*\n Aktualisiert <Modul>, damit <Zielmodul> gelesen wird, ungeachtet\n der Moduldeklaration. \n <Zielmodul> kann ALL-UNNAMED sein, um alle unbenannten\n Module zu lesen.\n --add-exports <Modul>/<Package>=<Zielmodul>(,<Zielmodul>)*\n Aktualisiert <Modul>, um <Package> in <Zielmodul> zu exportieren,\n ungeachtet der Moduldeklaration.\n <Zielmodul> kann ALL-UNNAMED sein, um in alle\n unbenannten Module zu exportieren.\n --add-opens <Modul>/<Package>=<Zielmodul>(,<Zielmodul>)*\n Aktualisiert <Modul>, um <Package> in\n <Zielmodul> zu öffnen, ungeachtet der Moduldeklaration.\n --limit-modules <Modulname>[,<Modulname>...]\n Grenzt die Gesamtmenge der beobachtbaren Module ein\n --patch-module <Modul>=<Datei>({0}<Datei>)*\n Überschreibt oder erweitert ein Modul mit Klassen und Ressourcen\n in JAR-Dateien oder Verzeichnissen.\n --source <Version>\n Legt die Version der Quelle im Quelldateimodus fest.\n --finalization=<Wert>\n Steuert, ob die JVM Objekte finalisiert.\n Dabei ist <Wert> entweder "enabled" oder "disabled".\n Die Finalisierung ist standardmäßig aktiviert.\n --sun-misc-unsafe-memory-access=<value>\n Verwendung der nicht unterstützten API sun.misc.Unsafe zulassen oder verweigern\n <value> ist "allow", "warn", "debug" oder "deny".\n Der Standardwert ist "warn".\n\nDiese zusätzlichen Optionen können jederzeit ohne vorherige Ankündigung geändert werden.\n
# Translators please note do not translate the options themselves
java.launcher.X.macosx.usage=\nDie folgenden Optionen sind für macOS spezifisch:\n -XstartOnFirstThread\n Führt die main()-Methode für den ersten (AppKit-)Thread aus\n -Xdock:name=<Anwendungsname>\n Setzt den im Dock angezeigten Standardanwendungsnamen außer Kraft\n -Xdock:icon=<Pfad zu Symboldatei>\n Setzt das im Dock angezeigte Standardsymbol außer Kraft\n\n
@@ -51,6 +51,7 @@ java.launcher.cls.error4=Fehler: Beim Laden der Klasse {0} ist ein LinkageError
java.launcher.cls.error5=Fehler: Hauptklasse {0} kann nicht initialisiert werden\nUrsache: {1}: {2}
java.launcher.cls.error6=Fehler: Kein nicht privater Null-Argument-Konstruktor in Klasse {0} gefunden\nEntfernen Sie die Eigenschaft "private" aus dem vorhandenen Konstruktor, oder definieren Sie ihn als:\n public {0}()
java.launcher.cls.error7=Fehler: Konstruktor mit nicht statischer innerer Klasse {0} kann nicht aufgerufen werden \nLegen Sie die innere Klasse als statisch fest, oder verschieben Sie sie in eine separate Quelldatei
java.launcher.cls.error8=Fehler: Abstrakte Klasse {0} kann nicht instanziiert werden.\nVerwenden Sie eine konkrete Klasse
java.launcher.jar.error1=Fehler: Beim Versuch, Datei {0} zu öffnen, ist ein unerwarteter Fehler aufgetreten
java.launcher.jar.error2=Manifest in {0} nicht gefunden
java.launcher.jar.error3=kein Hauptmanifestattribut, in {0}

View File

@@ -1,5 +1,5 @@
#
# Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2007, 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
@@ -35,7 +35,7 @@ java.launcher.opt.footer = \ -cp <ディレクトリおよびzip/jarファイ
-disableassertions[:<packagename>...|:<classname>]\n 指定した粒度でアサーションを無効にします\n -esa | -enablesystemassertions\n システム・アサーションを有効にします\n -dsa | -disablesystemassertions\n システム・アサーションを無効にします\n -agentlib:<libname>[=<options>]\n ネイティブ・エージェント・ライブラリ<libname>をロードします。例: -agentlib:jdwp\n -agentlib:jdwp=helpも参照してください\n -agentpath:<pathname>[=<options>]\n フルパス名を使用して、ネイティブ・エージェント・ライブラリをロードします\n -javaagent:<jarpath>[=<options>]\n Javaプログラミング言語エージェントをロードします。java.lang.instrumentを参照してください\n -splash:<imagepath>\n 指定されたイメージを含むスプラッシュ画面を表示します\n HiDPIスケールのイメージが自動的にサポートされて使用されます\n (可能な場合)。スケーリングされないイメージのファイル名(image.extなど)を\n 引数として-splashオプションに必ず渡す必要があります。\n 指定された最も適切なスケーリング済イメージが選択されます\n (自動的)。\n 詳細は、SplashScreen APIのドキュメントを参照してください\n @argumentファイル\n オプションを含む1つ以上の引数ファイル\n --disable-@files\n さらなる引数ファイル拡張を無効にします\n --enable-preview\n クラスをこのリリースのプレビュー機能に依存させることができます\n長いオプションの引数を指定する場合、--<name>=<value>または\n--<name> <value>を使用できます。\n
# Translators please note do not translate the options themselves
java.launcher.X.usage=\n -Xbatch バックグラウンド・コンパイルを無効にします\n -Xbootclasspath/a:<directories and zip/jar files separated by {0}>\n ブートストラップ・クラス・パスの最後に追加します\n -Xcheck:jni JNI関数に対する追加のチェックを実行します\n -Xcomp 初回呼出し時にメソッドのコンパイルを強制します\n -Xdebug 何も実行されません。将来のリリースで削除されるため、非推奨になりました。\n -Xdiag 追加の診断メッセージを表示します\n -Xint インタプリタ・モードの実行のみ\n -Xinternalversion\n -versionオプションより詳細なJVMバージョン情報を\n 表示します\n -Xlog:<opts> Java Virtual Machine (JVM)統合ロギング・フレームワークでの\n ロギングを構成または有効化します。詳細は、-Xlog:helpを\n 使用してください。\n -Xloggc:<file> タイムスタンプが付いたファイルにGCステータスのログを記録します\n このオプションは非推奨であり、将来のリリースで削除される\n 可能性があります。-Xlog:gc:<file>で置換されています。\n -Xmixed 混合モードの実行(デフォルト)\n -Xmn<size> 若い世代(ナーサリ)のヒープの初期サイズおよび最大サイズ\n (バイト単位)を設定します\n -Xms<size> Javaの初期ヒープ・サイズを設定します\n -Xmx<size> Javaの最大ヒープ・サイズを設定します\n -Xnoclassgc クラスのガベージ・コレクションを無効にします\n -Xrs Java/VMによるOSシグナルの使用を削減します(ドキュメントを参照)\n -Xshare:auto 可能であれば共有クラス・データを使用します(デフォルト)\n -Xshare:off 共有クラス・データの使用を試みません\n -Xshare:on 共有クラス・データの使用を必須にし、できなければ失敗します。\n \
java.launcher.X.usage=\n -Xbatch バックグラウンド・コンパイルを無効にします\n -Xbootclasspath/a:<directories and zip/jar files separated by {0}>\n ブートストラップ・クラス・パスの最後に追加します\n -Xcheck:jni JNI関数に対する追加のチェックを実行します\n -Xcomp 初回呼出し時にメソッドのコンパイルを強制します\n -Xdebug 何も実行されません。将来のリリースで削除されるため、非推奨になりました。\n -Xdiag 追加の診断メッセージを表示します\n -Xint インタプリタ・モードの実行のみ\n -Xinternalversion\n -versionオプションより詳細なJVMバージョン情報を\n 表示します\n -Xlog:<opts> Java Virtual Machine (JVM)統合ロギング・フレームワークでの\n ロギングを構成または有効化します。詳細は、-Xlog:helpを\n 使用してください。\n -Xloggc:<file> タイムスタンプが付いたファイルにGCステータスのログを記録します\n このオプションは非推奨であり、将来のリリースで削除される\n 可能性があります。-Xlog:gc:<file>で置換されています。\n -Xmixed 混合モードの実行(デフォルト)\n -Xmn<size> 若い世代(ナーサリ)のヒープの初期サイズおよび最大サイズ\n (バイト単位)を設定します\n -Xms<size> Javaの最小および初期ヒープ・サイズを設定します\n -Xmx<size> Javaの最大ヒープ・サイズを設定します\n -Xnoclassgc クラスのガベージ・コレクションを無効にします\n -Xrs Java/VMによるOSシグナルの使用を削減します(ドキュメントを参照)\n -Xshare:auto 可能であれば共有クラス・データを使用します(デフォルト)\n -Xshare:off 共有クラス・データの使用を試みません\n -Xshare:on 共有クラス・データの使用を必須にし、できなければ失敗します。\n \
これはテスト・オプションであり、断続的な失敗につながる\n 可能性があります。本番環境では使用しないでください。\n -XshowSettings すべての設定を表示して続行します\n -XshowSettings:all\n すべての設定を詳細に表示して続行します\n -XshowSettings:locale\n すべてのロケール関連の設定を表示して続行します\n -XshowSettings:properties\n すべてのプロパティ設定を表示して続行します\n -XshowSettings:vm\n すべてのVM関連の設定を表示して続行します\n -XshowSettings:security\n すべてのセキュリティ設定を表示して続行します\n -XshowSettings:security:all\n すべてのセキュリティ設定を表示して続行します\n -XshowSettings:security:properties\n セキュリティ・プロパティを表示して続行します\n -XshowSettings:security:providers\n 静的セキュリティ・プロバイダ設定を表示して続行します\n -XshowSettings:security:tls\n TLS関連のセキュリティ設定を表示して続行します\n -XshowSettings:system\n (Linuxのみ)ホスト・システムまたはコンテナを表示します\n 構成して続行します\n -Xss<size> javaスレッドのスタック・サイズを設定します\n 実際のサイズは、次の倍数に切り上げられる場合があります: \n オペレーティング・システムの要件に応じたシステム・ページ・サイズ。\n -Xverify バイトコード・ベリファイアのモードを設定します\n オプション-Xverify:noneは非推奨になり、\n 将来のリリースで削除される可能性があります。\n --add-reads <module>=<target-module>(,<target-module>)*\n モジュール宣言に関係なく、<module>を更新して<target-module>を\n 読み取ります。 \n <target-module>をALL-UNNAMEDに設定すると、すべての名前のないモジュールを\n 読み取ることができます。\n --add-exports \
<module>/<package>=<target-module>(,<target-module>)*\n モジュール宣言に関係なく、<module>を更新して<package>を<target-module>に\n エクスポートします。\n <target-module>をALL-UNNAMEDに設定すると、すべての名前のないモジュールに\n エクスポートできます。\n --add-opens <module>/<package>=<target-module>(,<target-module>)*\n モジュール宣言に関係なく、<module>を更新して<package>を\n <target-module>に開きます。\n --limit-modules <module name>[,<module name>...]\n 参照可能なモジュールの領域を制限します\n --patch-module <module>=<file>({0}<file>)*\n JARファイルまたはディレクトリのクラスおよびリソースで\n モジュールをオーバーライドまたは拡張します。\n --source <version>\n ソースファイル・モードでソースのバージョンを設定します。\n --finalization=<value>\n JVMがオブジェクトのファイナライズを実行するかどうかを制御します\n <value>は"enabled"または"disabled"のいずれかです。\n ファイナライズはデフォルトで有効になっています。\n --sun-misc-unsafe-memory-access=<value>\n サポートされていないAPI sun.misc.Unsafeの使用を許可または拒否します\n <value>は"allow"、"warn"、"debug"または"deny"のいずれかです。\n デフォルト値は"warn"です。\n\nこの追加オプションは予告なしに変更されることがあります。\n
@@ -53,6 +53,7 @@ java.launcher.cls.error4=エラー: メイン・クラス{0}のロード中にLi
java.launcher.cls.error5=エラー: メイン・クラス{0}を初期化できません\n原因: {1}: {2}
java.launcher.cls.error6=エラー: 非privateのゼロ引数コンストラクタがクラス{0}に見つかりません\n既存のコンストラクタからprivateを削除するか、次のように定義してください:\n public {0}()
java.launcher.cls.error7=エラー: staticでない内部クラス{0}コンストラクタを起動できません \n内部クラスをstaticにするか、内部クラスを外部に出してソース・ファイルを区別してください
java.launcher.cls.error8=エラー: 抽象クラス{0}はインスタンス化できません\n具象クラスを使用してください
java.launcher.jar.error1=エラー: ファイル{0}を開こうとしているときに、予期しないエラーが発生しました
java.launcher.jar.error2={0}にマニフェストが見つかりません
java.launcher.jar.error3={0}にメイン・マニフェスト属性がありません

View File

@@ -1,5 +1,5 @@
#
# Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2007, 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
@@ -34,7 +34,7 @@ java.launcher.opt.footer = \ -cp <目录和 zip/jar 文件的类搜索路径>
将产品版本输出到输出流并退出\n -showversion 将产品版本输出到错误流并继续\n --show-version\n 将产品版本输出到输出流并继续\n --show-module-resolution\n 在启动过程中显示模块解析输出\n -? -h -help\n 将此帮助消息输出到错误流\n --help 将此帮助消息输出到输出流\n -X 将额外选项的帮助输出到错误流\n --help-extra 将额外选项的帮助输出到输出流\n -ea[:<程序包名称>...|:<类名>]\n -enableassertions[:<程序包名称>...|:<类名>]\n 按指定的粒度启用断言\n -da[:<程序包名称>...|:<类名>]\n -disableassertions[:<程序包名称>...|:<类名>]\n 按指定的粒度禁用断言\n -esa | -enablesystemassertions\n 启用系统断言\n -dsa | -disablesystemassertions\n 禁用系统断言\n -agentlib:<库名>[=<选项>]\n 加载本机代理库 <库名>, 例如 -agentlib:jdwp\n 另请参阅 -agentlib:jdwp=help\n -agentpath:<路径名>[=<选项>]\n 按完整路径名加载本机代理库\n -javaagent:<jar 路径>[=<选项>]\n 加载 Java 编程语言代理, 请参阅 java.lang.instrument\n -splash:<图像路径>\n 使用指定的图像显示启动屏幕\n 自动支持和使用 HiDPI 缩放图像\n (如果可用)。应始终将未缩放的图像文件名 (例如, image.ext)\n 作为参数传递给 -splash 选项。\n 将自动选取提供的最合适的缩放\n 图像。\n 有关详细信息, 请参阅 SplashScreen API 文档\n @argument 文件\n 一个或多个包含选项的参数文件\n --disable-@files\n 阻止进一步扩展参数文件\n --enable-preview\n 允许类依赖于此发行版的预览功能\n要为长选项指定参数, 可以使用 --<名称>=<值> 或\n--<名称> <值>。\n
# Translators please note do not translate the options themselves
java.launcher.X.usage=\n -Xbatch 禁用后台编译\n -Xbootclasspath/a:<以 {0} 分隔的目录和 zip/jar 文件>\n 附加在引导类路径末尾\n -Xcheck:jni 对 JNI 函数执行其他检查\n -Xcomp 强制在首次调用时编译方法\n -Xdebug 不执行任何操作;已过时,将在未来发行版中删除。\n -Xdiag 显示附加诊断消息\n -Xint 仅解释模式执行\n -Xinternalversion\n 显示比 -version 选项更详细的\n JVM 版本信息\n -Xlog:<opts> 配置或启用采用 Java 虚拟\n 机 (Java Virtual Machine, JVM) 统一记录框架进行事件记录。使用 -Xlog:help\n 可了解详细信息。\n -Xloggc:<file> 将 GC 状态记录在文件中(带时间戳)。\n 此选项已过时,可能会在\n 将来的发行版中删除。它将替换为 -Xlog:gc:<file>。\n -Xmixed 混合模式执行(默认值)\n -Xmn<size> 为年轻代(新生代)设置初始和最大堆大小\n (以字节为单位)\n -Xms<size> 设置初始 Java 堆大小\n -Xmx<size> 设置最大 Java 堆大小\n -Xnoclassgc 禁用类垃圾收集\n -Xrs 减少 Java/VM 对操作系统信号的使用(请参见文档)\n -Xshare:auto 在可能的情况下使用共享类数据(默认值)\n -Xshare:off 不尝试使用共享类数据\n -Xshare:on 要求使用共享类数据,否则将失败。\n 这是一个测试选项,可能导致间歇性\n 故障。不应在生产环境中使用它。\n -XshowSettings 显示所有设置并继续\n -XshowSettings:all\n 详细显示所有设置并继续\n -XshowSettings:locale\n 显示所有与区域设置相关的设置并继续\n -XshowSettings:properties\n 显示所有属性设置并继续\n -XshowSettings:vm\n 显示所有与 vm 相关的设置并继续\n -XshowSettings:security\n 显示所有安全设置并继续\n -XshowSettings:security:all\n 显示所有安全设置并继续\n -XshowSettings:security:properties\n 显示安全属性并继续\n -XshowSettings:security:providers\n 显示静态安全提供方设置并继续\n -XshowSettings:security:tls\n 显示与 TLS \
java.launcher.X.usage=\n -Xbatch 禁用后台编译\n -Xbootclasspath/a:<以 {0} 分隔的目录和 zip/jar 文件>\n 附加在引导类路径末尾\n -Xcheck:jni 对 JNI 函数执行其他检查\n -Xcomp 强制在首次调用时编译方法\n -Xdebug 不执行任何操作;已过时,将在未来发行版中删除。\n -Xdiag 显示附加诊断消息\n -Xint 仅解释模式执行\n -Xinternalversion\n 显示比 -version 选项更详细的\n JVM 版本信息\n -Xlog:<opts> 配置或启用采用 Java 虚拟\n 机 (Java Virtual Machine, JVM) 统一记录框架进行事件记录。使用 -Xlog:help\n 可了解详细信息。\n -Xloggc:<file> 将 GC 状态记录在文件中(带时间戳)。\n 此选项已过时,可能会在\n 将来的发行版中删除。它将替换为 -Xlog:gc:<file>。\n -Xmixed 混合模式执行(默认值)\n -Xmn<size> 为年轻代(新生代)设置初始和最大堆大小\n (以字节为单位)\n -Xms<size> 设置最小和初始 Java 堆大小\n -Xmx<size> 设置最大 Java 堆大小\n -Xnoclassgc 禁用类垃圾收集\n -Xrs 减少 Java/VM 对操作系统信号的使用(请参见文档)\n -Xshare:auto 在可能的情况下使用共享类数据(默认值)\n -Xshare:off 不尝试使用共享类数据\n -Xshare:on 要求使用共享类数据,否则将失败。\n 这是一个测试选项,可能导致间歇性\n 故障。不应在生产环境中使用它。\n -XshowSettings 显示所有设置并继续\n -XshowSettings:all\n 详细显示所有设置并继续\n -XshowSettings:locale\n 显示所有与区域设置相关的设置并继续\n -XshowSettings:properties\n 显示所有属性设置并继续\n -XshowSettings:vm\n 显示所有与 vm 相关的设置并继续\n -XshowSettings:security\n 显示所有安全设置并继续\n -XshowSettings:security:all\n 显示所有安全设置并继续\n -XshowSettings:security:properties\n 显示安全属性并继续\n -XshowSettings:security:providers\n 显示静态安全提供方设置并继续\n -XshowSettings:security:tls\n 显示与 TLS \
相关的安全设置并继续\n -XshowSettings:system\n (仅 Linux显示主机系统或容器\n 配置并继续\n -Xss<size> 设置 Java 线程堆栈大小\n 实际大小可以舍入到\n 操作系统要求的系统页面大小的倍数。\n -Xverify 设置字节码验证器的模式\n 请注意,选项 -Xverify:none 已过时,\n 可能会在未来发行版中删除。\n --add-reads <module>=<target-module>(,<target-module>)*\n 更新 <module> 以读取 <target-module>,而无论\n 模块如何声明。 \n <target-module> 可以是 ALL-UNNAMED将读取所有未命名\n 模块。\n --add-exports <module>/<package>=<target-module>(,<target-module>)*\n 更新 <module> 以将 <package> 导出到 <target-module>\n 而无论模块如何声明。\n <target-module> 可以是 ALL-UNNAMED将导出到所有\n 未命名模块。\n --add-opens <module>/<package>=<target-module>(,<target-module>)*\n 更新 <module> 以在 <target-module> 中打开\n <package>,而无论模块如何声明。\n --limit-modules <module name>[,<module name>...]\n 限制可观察模块的领域\n --patch-module <module>=<file>({0}<file>)*\n 使用 JAR 文件或目录中的类和资源\n 覆盖或增强模块。\n --source <version>\n 设置源文件模式中源的版本。\n --finalization=<value>\n 控制 JVM 是否执行对象最终处理,\n 其中 <value> 为 "enabled" 或 "disabled" 之一。\n 默认情况下,最终处理处于启用状态。\n --sun-misc-unsafe-memory-access=<value>\n 允许或拒绝使用不受支持的 API sun.misc.Unsafe\n <value> 为 "allow"、"warn"、"debug" 或 "deny" 之一。\n 默认值为 "warn"。\n\n这些额外选项如有更改, 恕不另行通知。\n
# Translators please note do not translate the options themselves
@@ -51,6 +51,7 @@ java.launcher.cls.error4=错误: 加载主类 {0} 时出现 LinkageError\n\t{1}
java.launcher.cls.error5=错误: 无法初始化主类 {0}\n原因: {1}: {2}
java.launcher.cls.error6=错误:在类 {0} 中未找到非专用零参数构造器\n请从现有构造器中删除专用或者定义为\n public {0}()
java.launcher.cls.error7=错误:无法调用非静态内部类 {0} 构造器\n请将内部类设为静态或将内部类移出到单独的源文件
java.launcher.cls.error8=错误:无法实例化抽象类 {0}\n请使用具体类
java.launcher.jar.error1=错误: 尝试打开文件{0}时出现意外错误
java.launcher.jar.error2=在{0}中找不到清单
java.launcher.jar.error3={0}中没有主清单属性

View File

@@ -621,10 +621,10 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
if (port != -1 && port != url.getDefaultPort()) {
host += ":" + String.valueOf(port);
}
String reqHost = requests.findValue("Host");
if (reqHost == null || !reqHost.equalsIgnoreCase(host)) {
requests.set("Host", host);
}
// if the "Host" header hasn't been explicitly set, then set its
// value to the one determined through the request URL
requests.setIfNotSet("Host", host);
requests.setIfNotSet("Accept", acceptString);
/*

View File

@@ -94,6 +94,15 @@ public class Net {
return EXCLUSIVE_BIND;
}
private static final StableValue<Boolean> SHUTDOWN_WRITE_BEFORE_CLOSE = StableValue.of();
/**
* Tells whether a TCP connection should be shutdown for writing before closing.
*/
static boolean shouldShutdownWriteBeforeClose() {
return SHUTDOWN_WRITE_BEFORE_CLOSE.orElseSet(Net::shouldShutdownWriteBeforeClose0);
}
/**
* Tells whether both IPV6_XXX and IP_XXX socket options should be set on
* IPv6 sockets. On some kernels, both IPV6_XXX and IP_XXX socket options
@@ -462,6 +471,8 @@ public class Net {
*/
private static native int isExclusiveBindAvailable();
private static native boolean shouldShutdownWriteBeforeClose0();
private static native boolean shouldSetBothIPv4AndIPv6Options0();
private static native boolean canIPv6SocketJoinIPv4Group0();

View File

@@ -846,7 +846,7 @@ class SocketChannelImpl
/**
* Marks the beginning of a connect operation that might block.
* @param blocking true if configured blocking
* @param isa the remote address
* @param sa the remote socket address
* @throws ClosedChannelException if the channel is closed
* @throws AlreadyConnectedException if already connected
* @throws ConnectionPendingException is a connection is pending
@@ -1070,8 +1070,8 @@ class SocketChannelImpl
}
/**
* Closes the socket if there are no I/O operations in progress and the
* channel is not registered with a Selector.
* Closes the socket if there are no I/O operations in progress (or no I/O
* operations tracked), and the channel is not registered with a Selector.
*/
private boolean tryClose() throws IOException {
assert Thread.holdsLock(stateLock) && state == ST_CLOSING;
@@ -1096,11 +1096,21 @@ class SocketChannelImpl
}
/**
* Closes this channel when configured in blocking mode.
* Closes this channel when configured in blocking mode. If there are no I/O
* operations in progress (or tracked), then the channel's socket is closed. If
* there are I/O operations in progress then the behavior is platform specific.
*
* If there is an I/O operation in progress then the socket is pre-closed
* and the I/O threads signalled, in which case the final close is deferred
* until all I/O operations complete.
* On Unix systems, the channel's socket is pre-closed. This unparks any virtual
* threads that are blocked in I/O operations on this channel. If there are
* platform threads blocked on the channel's socket then the socket is dup'ed
* and the platform threads signalled. The final close is deferred until all I/O
* operations complete.
*
* On Windows, the channel's socket is pre-closed. This unparks any virtual
* threads that are blocked in I/O operations on this channel. If there are no
* virtual threads blocked in I/O operations on this channel then the channel's
* socket is closed. If there are virtual threads in I/O then the final close is
* deferred until all I/O operations on virtual threads complete.
*
* Note that a channel configured blocking may be registered with a Selector
* This arises when a key is canceled and the channel configured to blocking
@@ -1112,17 +1122,17 @@ class SocketChannelImpl
boolean connected = (state == ST_CONNECTED);
state = ST_CLOSING;
if (!tryClose()) {
if (connected && Net.shouldShutdownWriteBeforeClose()) {
// shutdown output when linger interval not set to 0
if (connected) {
try {
var SO_LINGER = StandardSocketOptions.SO_LINGER;
if ((int) Net.getSocketOption(fd, SO_LINGER) != 0) {
Net.shutdown(fd, Net.SHUT_WR);
}
} catch (IOException ignore) { }
}
try {
var SO_LINGER = StandardSocketOptions.SO_LINGER;
if ((int) Net.getSocketOption(fd, SO_LINGER) != 0) {
Net.shutdown(fd, Net.SHUT_WR);
}
} catch (IOException ignore) { }
}
if (!tryClose()) {
// prepare file descriptor for closing
nd.preClose(fd, readerThread, writerThread);
}

View File

@@ -565,7 +565,7 @@ public class X509Factory extends CertificateFactorySpi {
} catch (EOFException e) {
return null;
}
return Base64.getDecoder().decode(rec.pem());
return Base64.getDecoder().decode(rec.content());
} catch (IllegalArgumentException e) {
throw new IOException(e);
}

View File

@@ -27,7 +27,7 @@ NEWLINE=\n
STAR=*******************************************
STARNN=*******************************************\n\n
# keytool: Help part
.OPTION.=\u0020[OPTION]...
.OPTION.=\ [OPTION]...
Options.=Optionen:
option.1.set.twice=Die Option %s wurde mehrmals angegeben. Alle Angaben bis auf die letzte werden ignoriert.
multiple.commands.1.2=Nur ein Befehl ist zulässig: Sowohl %1$s als auch %2$s wurden angegeben.
@@ -170,7 +170,7 @@ Certificate.reply.was.installed.in.keystore=Zertifikatsantwort wurde in Keystore
Certificate.reply.was.not.installed.in.keystore=Zertifikatsantwort wurde nicht in Keystore installiert
Certificate.was.added.to.keystore=Zertifikat wurde Keystore hinzugefügt
Certificate.was.not.added.to.keystore=Zertifikat wurde nicht zu Keystore hinzugefügt
.Storing.ksfname.=[{0} wird gesichert]
.Storing.ksfname.=[{0} wird gespeichert]
alias.has.no.public.key.certificate.={0} hat keinen Public Key (Zertifikat)
Cannot.derive.signature.algorithm=Signaturalgorithmus kann nicht abgeleitet werden
Alias.alias.does.not.exist=Alias <{0}> ist nicht vorhanden
@@ -178,9 +178,9 @@ Alias.alias.has.no.certificate=Alias <{0}> hat kein Zertifikat
groupname.keysize.coexist=Es können nicht sowohl -groupname als auch -keysize angegeben werden
deprecate.keysize.for.ec=Das Angeben von -keysize zum Generieren von EC-Schlüsseln ist veraltet. Verwenden Sie stattdessen "-groupname %s".
Key.pair.not.generated.alias.alias.already.exists=Schlüsselpaar wurde nicht generiert. Alias <{0}> ist bereits vorhanden
size.bit.alg=%1$d-Bit %2$s
Generating.full.keyAlgName.key.pair.and.self.signed.certificate.sigAlgName.with.a.validity.of.days.for=Schlüsselpaar {0} und selbstsigniertes Zertifikat ({1}) werden mit einer Gültigkeit von {2} Tagen generiert\n\tfür: {3}
Generating.full.keyAlgName.key.pair.and.a.certificate.sigAlgName.issued.by.signerAlias.with.a.validity.of.days.for=Schlüsselpaar {0} und Zertifikat ({1}) werden generiert, das von <{2}> mit einer Gültigkeit von {3} Tagen ausgestellt wurde\n\tfür: {4}
size.bit.alg=%1$d-Bit-%2$s
Generating.full.keyAlgName.key.pair.and.self.signed.certificate.sigAlgName.with.a.validity.of.days.for=Generieren von {0}-Schlüsselpaar und selbstsigniertem Zertifikat ({1}) mit einer Gültigkeit von {2} Tagen\n\tfür: {3}
Generating.full.keyAlgName.key.pair.and.a.certificate.sigAlgName.issued.by.signerAlias.with.a.validity.of.days.for=Generieren von {0}-Schlüsselpaar und einem von <{2}> ausgestellten Zertifikat ({1}) mit einer Gültigkeit von {3} Tagen\n\tfür: {4}
Enter.key.password.for.alias.=Schlüsselkennwort für <{0}> eingeben
.RETURN.if.same.as.keystore.password.=\t(RETURN, wenn identisch mit Keystore-Kennwort): \u0020
Key.password.is.too.short.must.be.at.least.6.characters=Schlüsselkennwort ist zu kurz. Es muss mindestens sechs Zeichen lang sein
@@ -216,7 +216,7 @@ Do.you.still.want.to.add.it.no.=Möchten Sie es trotzdem hinzufügen? [Nein]: \u
Certificate.already.exists.in.system.wide.CA.keystore.under.alias.trustalias.=Zertifikat ist bereits unter Alias <{0}> im systemweiten CA-Keystore vorhanden
Do.you.still.want.to.add.it.to.your.own.keystore.no.=Möchten Sie es trotzdem zu Ihrem eigenen Keystore hinzufügen? [Nein]: \u0020
Trust.this.certificate.no.=Diesem Zertifikat vertrauen? [Nein]: \u0020
New.prompt.=Neues {0}:\u0020
New.prompt.={0} (neu):\u0020
Passwords.must.differ=Kennwörter müssen sich unterscheiden
Re.enter.new.prompt.=Neues {0} erneut eingeben:\u0020
Re.enter.password.=Geben Sie das Kennwort erneut ein:\u0020
@@ -238,7 +238,7 @@ Is.name.correct.=Ist {0} richtig?
no=Nein
yes=Ja
y=J
.defaultValue.=\u0020 [{0}]: \u0020
.defaultValue.=\ [{0}]: \u0020
Alias.alias.has.no.key=Alias <{0}> verfügt über keinen Schlüssel
Alias.alias.references.an.entry.type.that.is.not.a.private.key.entry.The.keyclone.command.only.supports.cloning.of.private.key=Alias <{0}> verweist auf einen Eintragstyp, der kein Private-Key-Eintrag ist. Der Befehl -keyclone unterstützt nur das Klonen von Private-Key-Einträgen
@@ -302,8 +302,8 @@ alias.in.keystore=Aussteller <%s>
with.weak=%s (schwach)
with.disabled=%s (deaktiviert)
key.bit=%s-Schlüssel
key.bit.weak=%s Schlüssel (schwach)
key.bit.disabled=%s Schlüssel (deaktiviert)
key.bit.weak=%s-Schlüssel (schwach)
key.bit.disabled=%s-Schlüssel (deaktiviert)
.PATTERN.printX509Cert.with.weak=Eigentümer: {0}\nAussteller: {1}\nSeriennummer: {2}\nGültig von: {3} bis: {4}\nZertifikatsfingerprints:\n\t SHA1: {5}\n\t SHA256: {6}\nSignaturalgorithmusname: {7}\nPublic-Key-Algorithmus von Subject: {8}\nVersion: {9}
PKCS.10.with.weak=PKCS #10-Zertifikatsanforderung (Version 1.0)\nSubject: %1$s\nFormat: %2$s\nPublic Key: %3$s\nSignaturalgorithmus: %4$s\n
verified.by.s.in.s.weak=Von %1$s in %2$s mit %3$s verifiziert
@@ -312,7 +312,7 @@ whose.sigalg.usagesignedjar=%1$s verwendet den Signaturalgorithmus %2$s. Das gil
Unable.to.parse.denyAfter.string.in.exception.message=denyAfter-Datumszeichenfolge in Ausnahmemeldung kann nicht geparst werden
whose.sigalg.weak=%1$s verwendet den Signaturalgorithmus %2$s. Dies gilt als Sicherheitsrisiko.
whose.key.disabled=%1$s verwendet %2$s. Dies gilt als Sicherheitsrisiko und ist deaktiviert.
whose.key.weak=%1$s verwendet %2$s. Dies gilt als Sicherheitsrisiko. Wird in einem zukünftigen Update deaktiviert.
whose.key.weak=%1$s verwendet %2$s. Das gilt als Sicherheitsrisiko. Dieser Schlüssel wird in einem zukünftigen Update deaktiviert.
jks.storetype.warning=Der %1$s-Keystore verwendet ein proprietäres Format. Es wird empfohlen, auf PKCS12 zu migrieren, das ein Industriestandardformat mit "keytool -importkeystore -srckeystore %2$s -destkeystore %2$s -deststoretype pkcs12" ist.
migrate.keystore.warning="%1$s" zu %4$s migriert. Der %2$s-Keystore wurde als "%3$s" gesichert.
backup.keystore.warning=Der ursprüngliche Keystore "%1$s" wird als "%3$s" gesichert...

View File

@@ -27,7 +27,7 @@ NEWLINE=\n
STAR=*******************************************
STARNN=*******************************************\n\n
# keytool: Help part
.OPTION.=\u0020[OPTION]...
.OPTION.=\ [OPTION]...
Options.=オプション:
option.1.set.twice=%sオプションが複数回指定されています。最後のもの以外はすべて無視されます。
multiple.commands.1.2=1つのコマンドのみ許可されます: %1$sと%2$sの両方が指定されました。
@@ -178,9 +178,9 @@ Alias.alias.has.no.certificate=別名<{0}>には証明書がありません
groupname.keysize.coexist=-groupnameと-keysizeの両方を指定できません
deprecate.keysize.for.ec=-keysizeの指定によるECキーの生成は非推奨です。かわりに"-groupname %s"を使用してください。
Key.pair.not.generated.alias.alias.already.exists=キー・ペアは生成されませんでした。別名<{0}>はすでに存在します
size.bit.alg=%1$dビット%2$s
Generating.full.keyAlgName.key.pair.and.self.signed.certificate.sigAlgName.with.a.validity.of.days.for={0}キー・ペアおよび自己署名証明書({1})を{2}日の有効性で生成しています\n\t対象: {3}
Generating.full.keyAlgName.key.pair.and.a.certificate.sigAlgName.issued.by.signerAlias.with.a.validity.of.days.for={0}キー・ペアと<{2}>によって発行され証明書({1})を{3}日間の有効性で生成しています\n\t対象: {4}
size.bit.alg=%1$d-ビット %2$s
Generating.full.keyAlgName.key.pair.and.self.signed.certificate.sigAlgName.with.a.validity.of.days.for={2}日間有効な{0}キー・ペア自己署名証明書({1})を生成しています\n\tディレクトリ名: {3}
Generating.full.keyAlgName.key.pair.and.a.certificate.sigAlgName.issued.by.signerAlias.with.a.validity.of.days.for={3}日間有効な{0}キー・ペアと<{2}>によって発行され証明書({1})を生成しています\n\tディレクトリ名: {4}
Enter.key.password.for.alias.=<{0}>のキー・パスワードを入力してください
.RETURN.if.same.as.keystore.password.=\t(キーストアのパスワードと同じ場合はRETURNを押してください): \u0020
Key.password.is.too.short.must.be.at.least.6.characters=キーのパスワードが短すぎます - 6文字以上を指定してください
@@ -227,18 +227,18 @@ Enter.new.alias.name.RETURN.to.cancel.import.for.this.entry.=新しい別名を
Enter.alias.name.=別名を入力してください: \u0020
.RETURN.if.same.as.for.otherAlias.=\t(<{0}>と同じ場合はRETURNを押してください)
enter.dname.components=識別名を入力します。サブコンポーネントを空のままにする場合はドット(.)を1つ入力し、中カッコ内のデフォルト値を使用する場合は[ENTER]を押します。
What.is.your.first.and.last.name.=姓名は何ですか
What.is.the.name.of.your.organizational.unit.=組織単位名は何ですか
What.is.the.name.of.your.organization.=組織名は何ですか
What.is.the.name.of.your.City.or.Locality.=都市名または地域名は何ですか
What.is.the.name.of.your.State.or.Province.=都道府県名または州名は何ですか
What.is.the.two.letter.country.code.for.this.unit.=この単位に該当する2文字の国コードは何ですか
What.is.your.first.and.last.name.=姓名を入力してください
What.is.the.name.of.your.organizational.unit.=組織単位名を入力してください
What.is.the.name.of.your.organization.=組織名を入力してください
What.is.the.name.of.your.City.or.Locality.=都市名または地域名を入力してください
What.is.the.name.of.your.State.or.Province.=都道府県名を入力してください
What.is.the.two.letter.country.code.for.this.unit.=この単位に該当する2文字の国コードを入力してください
no.field.in.dname=少なくとも1つのフィールドを指定する必要があります。再度入力してください。
Is.name.correct.={0}でよろしいですか。
no=いいえ
yes=はい
y=y
.defaultValue.=\u0020 [{0}]: \u0020
.defaultValue.=\ [{0}]: \u0020
Alias.alias.has.no.key=別名<{0}>にはキーがありません
Alias.alias.references.an.entry.type.that.is.not.a.private.key.entry.The.keyclone.command.only.supports.cloning.of.private.key=別名<{0}>が参照しているエントリ・タイプは秘密キー・エントリではありません。-keycloneコマンドは秘密キー・エントリのクローン作成のみをサポートします
@@ -292,7 +292,7 @@ the.certificate=証明書
the.crl=CRL
the.tsa.certificate=TSA証明書
the.input=入力
reply=応答
reply=返信
one.in.many=%1$s #%2$d / %3$d
one.in.many1=%1$s #%2$d
one.in.many2=署名者の%1$s #%2$d
@@ -302,7 +302,7 @@ alias.in.keystore=発行者<%s>
with.weak=%s (弱)
with.disabled=%s (無効)
key.bit=%sキー
key.bit.weak=%sキー(弱)
key.bit.weak=%sキー(弱)
key.bit.disabled=%sキー(無効)
.PATTERN.printX509Cert.with.weak=所有者: {0}\n発行者: {1}\nシリアル番号: {2}\n有効期間の開始日: {3}終了日: {4}\n証明書のフィンガプリント:\n\t SHA1: {5}\n\t SHA256: {6}\n署名アルゴリズム名: {7}\nサブジェクト公開キー・アルゴリズム: {8}\nバージョン: {9}
PKCS.10.with.weak=PKCS #10証明書リクエスト(バージョン1.0)\nサブジェクト: %1$s\nフォーマット: %2$s\n公開キー: %3$s\n署名アルゴリズム: %4$s\n
@@ -312,7 +312,7 @@ whose.sigalg.usagesignedjar=%1$sは%2$s署名アルゴリズムを使用して
Unable.to.parse.denyAfter.string.in.exception.message=例外メッセージのdenyAfter日付文字列を解析できません
whose.sigalg.weak=%1$sは%2$s署名アルゴリズムを使用しており、これはセキュリティ・リスクとみなされます。
whose.key.disabled=%1$sは%2$sを使用しており、これはセキュリティ・リスクとみなされ、無効化されています。
whose.key.weak=%1$sは%2$sを使用しており、これはセキュリティ・リスクとみなされます。今後の更新で無効になります。
whose.key.weak=%1$sは%2$sを使用しており、これはセキュリティ・リスクとみなされます。これは将来の更新で無効化されます。
jks.storetype.warning=%1$sキーストアは独自の形式を使用しています。"keytool -importkeystore -srckeystore %2$s -destkeystore %2$s -deststoretype pkcs12"を使用する業界標準の形式であるPKCS12に移行することをお薦めします。
migrate.keystore.warning="%1$s"が%4$sに移行されました。%2$sキーストアは"%3$s"としてバックアップされます。
backup.keystore.warning=元のキーストア"%1$s"は"%3$s"としてバックアップされます...

View File

@@ -27,13 +27,13 @@ NEWLINE=\n
STAR=*******************************************
STARNN=*******************************************\n\n
# keytool: Help part
.OPTION.=\u0020[OPTION]...
Options.=选项:
.OPTION.=\ [OPTION]...
Options.=选项
option.1.set.twice=多次指定了 %s 选项。除最后一个之外, 其余的将全部忽略。
multiple.commands.1.2=只允许一个命令: 同时指定了 %1$s 和 %2$s。
Use.keytool.help.for.all.available.commands=使用 "keytool -?, -h, or --help" 可输出此帮助消息
Key.and.Certificate.Management.Tool=密钥和证书管理工具
Commands.=命令:
Commands.=命令
Use.keytool.command.name.help.for.usage.of.command.name=使用 "keytool -command_name --help" 可获取 command_name 的用法。\n使用 -conf <url> 选项可指定预配置的选项文件。
# keytool: help: commands
Generates.a.certificate.request=生成证书请求
@@ -114,7 +114,7 @@ verbose.output=详细输出
validity.number.of.days=有效天数
Serial.ID.of.cert.to.revoke=要撤销的证书的序列 ID
# keytool: Running part
keytool.error.=keytool 错误:\u0020
keytool.error.=keytool 错误\u0020
Illegal.option.=非法选项: \u0020
Illegal.value.=非法值:\u0020
Unknown.password.type.=未知口令类型:\u0020
@@ -170,7 +170,7 @@ Certificate.reply.was.installed.in.keystore=证书回复已安装在密钥库中
Certificate.reply.was.not.installed.in.keystore=证书回复未安装在密钥库中
Certificate.was.added.to.keystore=证书已添加到密钥库中
Certificate.was.not.added.to.keystore=证书未添加到密钥库中
.Storing.ksfname.=[正在存储{0}]
.Storing.ksfname.=[正在存储 {0}]
alias.has.no.public.key.certificate.={0}没有公共密钥 (证书)
Cannot.derive.signature.algorithm=无法派生签名算法
Alias.alias.does.not.exist=别名 <{0}> 不存在
@@ -179,8 +179,8 @@ groupname.keysize.coexist=无法同时指定 -groupname 和 -keysize
deprecate.keysize.for.ec=为生成 EC 密钥指定 -keysize 已过时,请改为使用 "-groupname %s"。
Key.pair.not.generated.alias.alias.already.exists=未生成密钥对, 别名 <{0}> 已经存在
size.bit.alg=%1$d 位 %2$s
Generating.full.keyAlgName.key.pair.and.self.signed.certificate.sigAlgName.with.a.validity.of.days.for=正在为 {3} 生成有效期为 {2} 天的 {0} 密钥对和自签名证书 ({1})\n
Generating.full.keyAlgName.key.pair.and.a.certificate.sigAlgName.issued.by.signerAlias.with.a.validity.of.days.for=生成 {0} 密钥对和 <{2}> 颁发的证书 ({1})有效期为 {3} 天 \n\t 对于:{4}
Generating.full.keyAlgName.key.pair.and.self.signed.certificate.sigAlgName.with.a.validity.of.days.for=正在为以下对象生成 {0} 密钥对和自签名证书 ({1})(有效期为 {2} 天):\n\t{3}
Generating.full.keyAlgName.key.pair.and.a.certificate.sigAlgName.issued.by.signerAlias.with.a.validity.of.days.for=正在为以下对象生成 {0} 密钥对和 <{2}> 颁发的证书 ({1})有效期为 {3} 天\n\t{4}
Enter.key.password.for.alias.=输入 <{0}> 的密钥口令
.RETURN.if.same.as.keystore.password.=\t(如果和密钥库口令相同, 按回车): \u0020
Key.password.is.too.short.must.be.at.least.6.characters=密钥口令太短 - 至少必须为 6 个字符
@@ -216,7 +216,7 @@ Do.you.still.want.to.add.it.no.=是否仍要添加? [否]: \u0020
Certificate.already.exists.in.system.wide.CA.keystore.under.alias.trustalias.=在别名 <{0}> 之下, 证书已经存在于系统范围的 CA 密钥库中
Do.you.still.want.to.add.it.to.your.own.keystore.no.=是否仍要将它添加到自己的密钥库? [否]: \u0020
Trust.this.certificate.no.=是否信任此证书? [否]: \u0020
New.prompt.=新{0}:\u0020
New.prompt.= {0}\u0020
Passwords.must.differ=口令不能相同
Re.enter.new.prompt.=重新输入新{0}:\u0020
Re.enter.password.=再次输入口令:\u0020
@@ -238,14 +238,14 @@ Is.name.correct.={0}是否正确?
no=
yes=
y=y
.defaultValue.=\u0020 [{0}]: \u0020
.defaultValue.=\ [{0}]: \u0020
Alias.alias.has.no.key=别名 <{0}> 没有密钥
Alias.alias.references.an.entry.type.that.is.not.a.private.key.entry.The.keyclone.command.only.supports.cloning.of.private.key=别名 <{0}> 引用了不属于私有密钥条目的条目类型。-keyclone 命令仅支持对私有密钥条目的克隆
.WARNING.WARNING.WARNING.=***************** WARNING WARNING WARNING *****************
Signer.d.=签名者 #%d:
Signer.d.=签名者 #%d
Certificate.d.=证书 #%d
Timestamp.=时间戳:
Timestamp.=时间戳
Certificate.owner.=证书所有者:\u0020
Not.a.signed.jar.file=不是已签名的 jar 文件
No.certificate.from.the.SSL.server=没有来自 SSL 服务器的证书
@@ -256,7 +256,7 @@ No.certificate.from.the.SSL.server=没有来自 SSL 服务器的证书
Certificate.reply.does.not.contain.public.key.for.alias.=证书回复中不包含 <{0}> 的公共密钥
Incomplete.certificate.chain.in.reply=回复中的证书链不完整
Top.level.certificate.in.reply.=回复中的顶级证书:\n
.is.not.trusted.=... 是不可信的。
.is.not.trusted.=... 是不可信的。\u0020
Install.reply.anyway.no.=是否仍要安装回复? [否]: \u0020
Public.keys.in.reply.and.keystore.don.t.match=回复中的公共密钥与密钥库不匹配
Certificate.reply.and.certificate.in.keystore.are.identical=证书回复与密钥库中的证书是相同的
@@ -269,14 +269,14 @@ Please.provide.keysize.for.secret.key.generation=请提供 -keysize 以生成密
warning.not.verified.make.sure.keystore.is.correct=警告: 未验证。请确保密钥库是正确的。
warning.not.verified.make.sure.keystore.is.correct.or.specify.trustcacerts=警告:未验证。请确保密钥库是正确的,或者指定 -trustcacerts。
Extensions.=扩展:\u0020
Extensions.=扩展\u0020
.Empty.value.=(空值)
Extension.Request.=扩展请求:
Unknown.keyUsage.type.=未知 keyUsage 类型:\u0020
Unknown.extendedkeyUsage.type.=未知 extendedkeyUsage 类型:\u0020
Unknown.AccessDescription.type.=未知 AccessDescription 类型:\u0020
Unrecognized.GeneralName.type.=无法识别的 GeneralName 类型:\u0020
This.extension.cannot.be.marked.as.critical.=无法将此扩展标记为“严重”。
This.extension.cannot.be.marked.as.critical.=无法将此扩展标记为“严重”。\u0020
Odd.number.of.hex.digits.found.=找到奇数个十六进制数字:\u0020
Unknown.extension.type.=未知扩展类型:\u0020
command.{0}.is.ambiguous.=命令{0}不明确:
@@ -299,11 +299,11 @@ one.in.many2=签名者 #%2$d 的 %1$s
one.in.many3=签名者 #%3$d 的 %1$s #%2$d
alias.in.cacerts=cacerts 中的发布者 <%s>
alias.in.keystore=发布者 <%s>
with.weak=%s (弱)
with.weak=%s(弱)
with.disabled=%s禁用
key.bit=%s 密钥
key.bit.weak=%s 密钥(弱)
key.bit.disabled=%s 密钥(禁用)
key.bit.disabled=%s 密钥(禁用)
.PATTERN.printX509Cert.with.weak=所有者: {0}\n发布者: {1}\n序列号: {2}\n生效时间: {3}, 失效时间: {4}\n证书指纹:\n\t SHA1: {5}\n\t SHA256: {6}\n签名算法名称: {7}\n主体公共密钥算法: {8}\n版本: {9}
PKCS.10.with.weak=PKCS #10 证书请求 (版本 1.0)\n主体: %1$s\n格式: %2$s\n公共密钥: %3$s\n签名算法: %4$s\n
verified.by.s.in.s.weak=由 %2$s 中的 %1$s 以 %3$s 验证
@@ -312,7 +312,7 @@ whose.sigalg.usagesignedjar=%1$s 使用的 %2$s 签名算法被视为存在安
Unable.to.parse.denyAfter.string.in.exception.message=无法解析异常错误消息中的 denyAfter 日期字符串
whose.sigalg.weak=%1$s 使用的 %2$s 签名算法存在安全风险。
whose.key.disabled=%1$s 使用的 %2$s 被视为存在安全风险而且被禁用。
whose.key.weak=%1$s 使用的 %2$s 被视为存在安全风险。在将来的更新中禁用
whose.key.weak=%1$s 使用的 %2$s 被视为存在安全风险。它将在未来的更新中禁用。
jks.storetype.warning=%1$s 密钥库使用专用格式。建议使用 "keytool -importkeystore -srckeystore %2$s -destkeystore %2$s -deststoretype pkcs12" 迁移到行业标准格式 PKCS12。
migrate.keystore.warning=已将 "%1$s" 迁移到 %4$s。将 %2$s 密钥库作为 "%3$s" 进行了备份。
backup.keystore.warning=已将原始密钥库 "%1$s" 备份为 "%3$s"...

View File

@@ -343,7 +343,7 @@ public class Pem {
* @return PEM in a string
*/
public static String pemEncoded(PEMRecord pem) {
String p = pem.pem().replaceAll("(.{64})", "$1\r\n");
String p = pem.content().replaceAll("(.{64})", "$1\r\n");
return pemEncoded(pem.type(), p);
}
}

View File

@@ -24,22 +24,22 @@
#
# NT principals
invalid.null.input.value=无效的空输入: {0}
NTDomainPrincipal.name=NTDomainPrincipal: {0}
NTNumericCredential.name=NTNumericCredential: {0}
invalid.null.input.value=无效的空输入{0}
NTDomainPrincipal.name=NTDomainPrincipal{0}
NTNumericCredential.name=NTNumericCredential{0}
Invalid.NTSid.value=无效的 NTSid 值
NTSid.name=NTSid: {0}
NTSidDomainPrincipal.name=NTSidDomainPrincipal: {0}
NTSidGroupPrincipal.name=NTSidGroupPrincipal: {0}
NTSidPrimaryGroupPrincipal.name=NTSidPrimaryGroupPrincipal: {0}
NTSidUserPrincipal.name=NTSidUserPrincipal: {0}
NTUserPrincipal.name=NTUserPrincipal: {0}
NTSid.name=NTSid{0}
NTSidDomainPrincipal.name=NTSidDomainPrincipal{0}
NTSidGroupPrincipal.name=NTSidGroupPrincipal{0}
NTSidPrimaryGroupPrincipal.name=NTSidPrimaryGroupPrincipal{0}
NTSidUserPrincipal.name=NTSidUserPrincipal{0}
NTUserPrincipal.name=NTUserPrincipal{0}
# UnixPrincipals
UnixNumericGroupPrincipal.Primary.Group.name=UnixNumericGroupPrincipal [主组]: {0}
UnixNumericGroupPrincipal.Primary.Group.name=UnixNumericGroupPrincipal [主组]{0}
UnixNumericGroupPrincipal.Supplementary.Group.name=UnixNumericGroupPrincipal [补充组]: {0}
UnixNumericUserPrincipal.name=UnixNumericUserPrincipal: {0}
UnixPrincipal.name=UnixPrincipal: {0}
UnixNumericUserPrincipal.name=UnixNumericUserPrincipal{0}
UnixPrincipal.name=UnixPrincipal{0}
# com.sun.security.auth.login.ConfigFile
Unable.to.properly.expand.config=无法正确扩展{0}
@@ -53,8 +53,8 @@ Configuration.Error.Line.line.expected.expect.=配置错误: \n\t行 {0}: 应为
Configuration.Error.Line.line.system.property.value.expanded.to.empty.value=配置错误: \n\t行 {0}: 系统属性 [{1}] 扩展到空值
# com.sun.security.auth.module.JndiLoginModule
username.=用户名:\u0020
password.=口令:\u0020
username.=用户名\u0020
password.=密码:\u0020
# com.sun.security.auth.module.KeyStoreLoginModule
Please.enter.keystore.information=请输入密钥库信息
@@ -63,5 +63,5 @@ Keystore.password.=密钥库口令:\u0020
Private.key.password.optional.=私有密钥口令 (可选):\u0020
# com.sun.security.auth.module.Krb5LoginModule
Kerberos.username.defUsername.=Kerberos 用户名 [{0}]:\u0020
Kerberos.password.for.username.={0}的 Kerberos 口令:\u0020
Kerberos.username.defUsername.=Kerberos 用户名 [{0}]\u0020
Kerberos.password.for.username.={0} 的 Kerberos 密码:\u0020

View File

@@ -66,7 +66,7 @@ Login.Failure.all.modules.ignored=ログイン失敗: すべてのモジュー
# sun.security.provider.PolicyParser
duplicate.keystore.domain.name=重複するキーストア・ドメイン名: {0}
duplicate.keystore.name=重複するキーストア名: {0}
number.=数\u0020
number.=\u0020
expected.expect.read.end.of.file.=[{0}]ではなく[ファイルの終わり]が読み込まれました
expected.read.end.of.file.=[;]ではなく[ファイルの終わり]が読み込まれました
line.number.msg=行{0}: {1}

View File

@@ -43,17 +43,17 @@ provided.null.OID.map=提供的 OID 映射为空值
NEWLINE=\n
invalid.null.action.provided=提供了无效的空操作
invalid.null.Class.provided=提供了无效的空类
Subject.=主体: \n
.Principal.=\t主用户:\u0020
.Public.Credential.=\t公共身份证明:\u0020
.Private.Credential.=\t专用身份证明:\u0020
Subject.=主体\n
.Principal.=\t主用户\u0020
.Public.Credential.=\t公共身份证明\u0020
.Private.Credential.=\t专用身份证明\u0020
.Private.Credential.inaccessible.=\t无法访问专用身份证明\n
Subject.is.read.only=主体为只读
attempting.to.add.an.object.which.is.not.an.instance.of.java.security.Principal.to.a.Subject.s.Principal.Set=正在尝试将一个非 java.security.Principal 实例的对象添加到主体的主用户集中
attempting.to.add.an.object.which.is.not.an.instance.of.class=正在尝试添加一个非{0}实例的对象
# javax.security.auth.login.AppConfigurationEntry
LoginModuleControlFlag.=LoginModuleControlFlag:\u0020
LoginModuleControlFlag.=LoginModuleControlFlag\u0020
# javax.security.auth.login.LoginContext
Invalid.null.input.name=无效空输入: 名称
@@ -69,8 +69,8 @@ duplicate.keystore.name=密钥库名称重复: {0}
number.=编号\u0020
expected.expect.read.end.of.file.=应为 [{0}], 读取的是 [文件结尾]
expected.read.end.of.file.=应为 [;], 读取的是 [文件结尾]
line.number.msg={0}: {1}
line.number.msg={0} 行:{1}
line.number.expected.expect.found.actual.=行号 {0}: 应为 [{1}], 找到 [{2}]
# sun.security.pkcs11.SunPKCS11
PKCS11.Token.providerName.Password.=PKCS11 标记 [{0}] 口令:\u0020
PKCS11.Token.providerName.Password.=PKCS11 标记 [{0}] 密码:\u0020

View File

@@ -0,0 +1,21 @@
Owner: CN=Sectigo Public Code Signing Root E46, O=Sectigo Limited, C=GB
Issuer: CN=Sectigo Public Code Signing Root E46, O=Sectigo Limited, C=GB
Serial number: 50249ba2ef8ea6bf6c2c1f1a6385d4c3
Valid from: Mon Mar 22 00:00:00 GMT 2021 until: Wed Mar 21 23:59:59 GMT 2046
Signature algorithm name: SHA384withECDSA
Subject Public Key Algorithm: 384-bit EC (secp384r1) key
Version: 3
-----BEGIN CERTIFICATE-----
MIICKDCCAa+gAwIBAgIQUCSbou+Opr9sLB8aY4XUwzAKBggqhkjOPQQDAzBWMQsw
CQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMS0wKwYDVQQDEyRT
ZWN0aWdvIFB1YmxpYyBDb2RlIFNpZ25pbmcgUm9vdCBFNDYwHhcNMjEwMzIyMDAw
MDAwWhcNNDYwMzIxMjM1OTU5WjBWMQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2Vj
dGlnbyBMaW1pdGVkMS0wKwYDVQQDEyRTZWN0aWdvIFB1YmxpYyBDb2RlIFNpZ25p
bmcgUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQIMoEDH487om+BR4zl
e7m6wWmyW0nAKLkUWG8kM85Qm3PZO8FoOZx6Yc5c0iJHRKuAhanllayqrmZYhlan
uIODzLTRDqlR+EtnOX+MubY5aDSPGUq6jiHrQrisVp0J3AejQjBAMB0GA1UdDgQW
BBTPfSygkHqYHd22XoXC4NoVcdLlXjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/
BAUwAwEB/zAKBggqhkjOPQQDAwNnADBkAjACd++zAerlV83j8HflRwwwlLmgchbs
aGX/4g44dv/oG8KfzCVTRg6sZHMobtK0IqYCMGk5W6+oBFyZMtOebrSwXs8lGjll
/zHz43Zy8DMXO+iiqzSEwWGneZ6KupkGGqfVKw==
-----END CERTIFICATE-----

View File

@@ -0,0 +1,39 @@
Owner: CN=Sectigo Public Code Signing Root R46, O=Sectigo Limited, C=GB
Issuer: CN=Sectigo Public Code Signing Root R46, O=Sectigo Limited, C=GB
Serial number: 4b2c3b01018bad2abc8c7b5b3eed9057
Valid from: Mon Mar 22 00:00:00 GMT 2021 until: Wed Mar 21 23:59:59 GMT 2046
Signature algorithm name: SHA384withRSA
Subject Public Key Algorithm: 4096-bit RSA key
Version: 3
-----BEGIN CERTIFICATE-----
MIIFeDCCA2CgAwIBAgIQSyw7AQGLrSq8jHtbPu2QVzANBgkqhkiG9w0BAQwFADBW
MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMS0wKwYDVQQD
EyRTZWN0aWdvIFB1YmxpYyBDb2RlIFNpZ25pbmcgUm9vdCBSNDYwHhcNMjEwMzIy
MDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBWMQswCQYDVQQGEwJHQjEYMBYGA1UEChMP
U2VjdGlnbyBMaW1pdGVkMS0wKwYDVQQDEyRTZWN0aWdvIFB1YmxpYyBDb2RlIFNp
Z25pbmcgUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCN
55QSIgQkdC7/FiMCkoq2rjaFrEfUI5ErPtx94jGgUW+shJHjUoq14pbe0IdjJImK
/+8Skzt9u7aKvb0Ffyeba2XTpQxpsbxJOZrxbW6q5KCDJ9qaDStQ6Utbs7hkNqR+
Sj2pcaths3OzPAsM79szV+W+NDfjlxtd/R8SPYIDdub7P2bSlDFp+m2zNKzBenjc
klDyZMeqLQSrw2rq4C+np9xu1+j/2iGrQL+57g2extmeme/G3h+pDHazJyCh1rr9
gOcB0u/rgimVcI3/uxXP/tEPNqIuTzKQdEZrRzUTdwUzT2MuuC3hv2WnBGsY2HH6
zAjybYmZELGt2z4s5KoYsMYHAXVn3m3pY2MeNn9pib6qRT5uWl+PoVvLnTCGMOgD
s0DGDQ84zWeoU4j6uDBl+m/H5x2xg3RpPqzEaDux5mczmrYI4IAFSEDu9oJkRqj1
c7AGlfJsZZ+/VVscnFcax3hGfHCqlBuCF6yH6bbJDoEcQNYWFyn8XJwYK+pF9e+9
1WdPKF4F7pBMeufG9ND8+s0+MkYTIDaKBOq3qgdGnA2TOglmmVhcKaO5DKYwODzQ
RjY1fJy67sPV+Qp2+n4FG0DKkjXp1XrRtX8ArqmQqsV/AZwQsRb8zG4Y3G9i/qZQ
p7h7uJ0VP/4gDHXIIloTlRmQAOka1cKG8eOO7F/05QIDAQABo0IwQDAdBgNVHQ4E
FgQUMuuSmv81lkgvKEBCcCA2kVwXheYwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB
/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAHZlwuPXIkrXHYle/2lexhQCTXOm
zc0oyrA36r+nySGqql/av/aDbNCA0QpcAKTL88w5D55BcYjVPOiKe4wXI/fKNHSR
bAauUD8AWbImPDwXg1cDPi3RGj3UzwdUskMLUnKoiPXEF/Jv0Vil0WjkPZgIGO42
9EhImvpUcPCI1HAWMEJJ0Nk/dUtFcdiuorthDoiFUFe5uhErNikfjyBynlyeidGC
2kWNapnahHFrM6UQu3nwl/Z0gaA/V8eGjDCMDjiVrgHGHqvcqB9vL9f/dh6uF3Nt
5bl1s2EGqJUzwk5vsjfylb6FVBK5yL1iQnb3Kvz1NzEDJlf+0ebb8BYCcoOMCLOE
rKnkB/ihiMQTWlBHVEKm7dBBNCyYsT6iNKEMXb2s9395p79tDFYyhRtLl7jhrOSk
PHHxo+FOY9b0Rrr1CwjhYzztolkvCtQsayOinqFN7tESzRgzUO1Bbst/PUFgC2ML
ePV170MVtzYLEK/cXBipmNk22R3YhLMGioLjexskp0LO7g8+VlwyfexL3lYrOzu6
+XpY0FG2bNb2WKJSJHpEhqEcYD9J0/z6+YQcBcI0v+Lm8RkqmS9WVzWctfUHw0Yv
3jg9GQ37o/HfE57nqXJYMa+96trX1m13MzOO9Kz9wb9Jh9JwBWd0Bqb2eEAtFgSR
Dx/TFsS4ehcNJMmy
-----END CERTIFICATE-----

View File

@@ -0,0 +1,21 @@
Owner: CN=Sectigo Public Server Authentication Root E46, O=Sectigo Limited, C=GB
Issuer: CN=Sectigo Public Server Authentication Root E46, O=Sectigo Limited, C=GB
Serial number: 42f2ccda1b6937445f15fe752810b8f4
Valid from: Mon Mar 22 00:00:00 GMT 2021 until: Wed Mar 21 23:59:59 GMT 2046
Signature algorithm name: SHA384withECDSA
Subject Public Key Algorithm: 384-bit EC (secp384r1) key
Version: 3
-----BEGIN CERTIFICATE-----
MIICOjCCAcGgAwIBAgIQQvLM2htpN0RfFf51KBC49DAKBggqhkjOPQQDAzBfMQsw
CQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1T
ZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwHhcN
MjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBfMQswCQYDVQQGEwJHQjEYMBYG
A1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1YmxpYyBT
ZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQA
IgNiAAR2+pmpbiDt+dd34wc7qNs9Xzjoq1WmVk/WSOrsfy2qw7LFeeyZYX8QeccC
WvkEN/U0NSt3zn8gj1KjAIns1aeibVvjS5KToID1AZTc8GgHHs3u/iVStSBDHBv+
6xnOQ6OjQjBAMB0GA1UdDgQWBBTRItpMWfFLXyY4qp3W7usNw/upYTAOBgNVHQ8B
Af8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNnADBkAjAn7qRa
qCG76UeXlImldCBteU/IvZNeWBj7LRoAasm4PdCkT0RHlAFWovgzJQxC36oCMB3q
4S6ILuH5px0CMk7yn2xVdOOurvulGu7t0vzCAxHrRVxgED1cf5kDW21USAGKcw==
-----END CERTIFICATE-----

View File

@@ -0,0 +1,39 @@
Owner: CN=Sectigo Public Server Authentication Root R46, O=Sectigo Limited, C=GB
Issuer: CN=Sectigo Public Server Authentication Root R46, O=Sectigo Limited, C=GB
Serial number: 758dfd8bae7c0700faa925a7e1c7ad14
Valid from: Mon Mar 22 00:00:00 GMT 2021 until: Wed Mar 21 23:59:59 GMT 2046
Signature algorithm name: SHA384withRSA
Subject Public Key Algorithm: 4096-bit RSA key
Version: 3
-----BEGIN CERTIFICATE-----
MIIFijCCA3KgAwIBAgIQdY39i658BwD6qSWn4cetFDANBgkqhkiG9w0BAQwFADBf
MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQD
Ey1TZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYw
HhcNMjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBfMQswCQYDVQQGEwJHQjEY
MBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1Ymxp
YyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEB
AQUAA4ICDwAwggIKAoICAQCTvtU2UnXYASOgHEdCSe5jtrch/cSV1UgrJnwUUxDa
ef0rty2k1Cz66jLdScK5vQ9IPXtamFSvnl0xdE8H/FAh3aTPaE8bEmNtJZlMKpnz
SDBh+oF8HqcIStw+KxwfGExxqjWMrfhu6DtK2eWUAtaJhBOqbchPM8xQljeSM9xf
iOefVNlI8JhD1mb9nxc4Q8UBUQvX4yMPFF1bFOdLvt30yNoDN9HWOaEhUTCDsG3X
ME6WW5HwcCSrv0WBZEMNvSE6Lzzpng3LILVCJ8zab5vuZDCQOc2TZYEhMbUjUDM3
IuM47fgxMMxF/mL50V0yeUKH32rMVhlATc6qu/m1dkmU8Sf4kaWD5QazYw6A3OAS
VYCmO2a0OYctyPDQ0RTp5A1NDvZdV3LFOxxHVp3i1fuBYYzMTYCQNFu31xR13NgE
SJ/AwSiItOkcyqex8Va3e0lMWeUgFaiEAin6OJRpmkkGj80feRQXEgyDet4fsZfu
+Zd4KKTIRJLpfSYFplhym3kT2BFfrsU4YjRosoYwjviQYZ4ybPUHNs2iTG7sijbt
8uaZFURww3y8nDnAtOFr94MlI1fZEoDlSfB1D++N6xybVCi0ITz8fAr/73trdf+L
HaAZBav6+CuBQug4urv7qv094PPK306Xlynt8xhW6aWWrL3DkJiy4Pmi1KZHQ3xt
zwIDAQABo0IwQDAdBgNVHQ4EFgQUVnNYZJX5khqwEioEYnmhQBWIIUkwDgYDVR0P
AQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAC9c
mTz8Bl6MlC5w6tIyMY208FHVvArzZJ8HXtXBc2hkeqK5Duj5XYUtqDdFqij0lgVQ
YKlJfp/imTYpE0RHap1VIDzYm/EDMrraQKFz6oOht0SmDpkBm+S8f74TlH7Kph52
gDY9hAaLMyZlbcp+nv4fjFg4exqDsQ+8FxG75gbMY/qB8oFM2gsQa6H61SilzwZA
Fv97fRheORKkU55+MkIQpiGRqRxOF3yEvJ+M0ejf5lG5Nkc/kLnHvALcWxxPDkjB
JYOcCj+esQMzEhonrPcibCTRAUH4WAP+JWgiH5paPHxsnnVI84HxZmduTILA7rpX
DhjvLpr3Etiga+kFpaHpaPi8TD8SHkXoUsCjvxInebnMMTzD9joiFgOgyY9mpFui
TdaBJQbpdqQACj7LzTWb4OE4y2BThihCQRxEV+ioratF4yUQvNs+ZUH7G6aXD+u5
dHn5HrwdVw1Hr8Mvn4dGp+smWg9WY7ViYG4A++MnESLn/pmPNPW56MORcr3Ywx65
LvKRRFHQV80MNNVIIb/bE/FmJUNS0nAiNs2fxBx1IK1jcmMGDw4nztJqDby1ORrp
0XZ60Vzk50lJLVU3aPAaOpg+VBeHVOmmJ1CJeyAvP/+/oYtKR5j/K3tJPsMpRmAY
QqszKbrAKbkTidOIijlBO8n9pu0f9GBj39ItVQGL
-----END CERTIFICATE-----

View File

@@ -1449,9 +1449,10 @@ These `java` options control the runtime behavior of the Java HotSpot VM.
`report-on-exit=`*identifier*
: Specifies the name of the view to display when the Java Virtual Machine
(JVM) shuts down. This option is not available if the disk option is set
to false. For a list of available views, see `jfr help view`. By default,
no report is generated.
(JVM) shuts down. To specify more than one view, use the report-on-exit
parameter repeatedly. This option is not available if the disk option
is set to false. For a list of available views, see `jfr help view`.
By default, no report is generated.
`settings=`*path*
: Specifies the path and name of the event settings file (of type JFC).
@@ -1514,6 +1515,15 @@ These `java` options control the runtime behavior of the Java HotSpot VM.
This option is similar to `-Xss`.
`-XX:+UseCompactObjectHeaders`
: Enables compact object headers. By default, this option is disabled.
Enabling this option reduces memory footprint in the Java heap by
4 bytes per object (on average) and often improves performance.
The feature remains disabled by default while it continues to be evaluated.
In a future release it is expected to be enabled by default, and
eventually will be the only mode of operation.
`-XX:-UseCompressedOops`
: Disables the use of compressed pointers. By default, this option is
enabled, and compressed pointers are used. This will automatically limit
@@ -3806,9 +3816,10 @@ general form:
be loaded on top of those in the `<static_archive>`.
- On Windows, the above path delimiter `:` should be replaced with `;`
(The names "static" and "dynamic" are used for historical reasons.
The only significance is that the "static" archive is loaded first and
the "dynamic" archive is loaded second).
The names "static" and "dynamic" are used for historical reasons. The dynamic
archive, while still useful, supports fewer optimizations than
available for the static CDS archive. If the full set of CDS/AOT
optimizations are desired, consider using the AOT cache described below.
The JVM can use up to two archives. To use only a single `<static_archive>`,
you can omit the `<dynamic_archive>` portion:

View File

@@ -91,14 +91,7 @@ DEF_JNI_OnLoad(JavaVM *vm, void *reserved)
}
static int enhancedExceptionsInitialized = 0;
static int enhancedExceptionsAllowed = -1;
#define CHECK_NULL_THROW_ERROR(X) \
if (X == NULL) { \
JNU_ThrowByName(env, "java/lang/InternalError", \
"can't initialize enhanced exceptions"); \
return -1; \
}
static int enhancedExceptionsAllowed = 0;
int getEnhancedExceptionsAllowed(JNIEnv *env) {
jclass cls;
@@ -108,9 +101,9 @@ int getEnhancedExceptionsAllowed(JNIEnv *env) {
return enhancedExceptionsAllowed;
}
cls = (*env)->FindClass(env, "jdk/internal/util/Exceptions");
CHECK_NULL_THROW_ERROR(cls);
CHECK_NULL_RETURN(cls, ENH_INIT_ERROR);
fid = (*env)->GetStaticFieldID(env, cls, "enhancedNonSocketExceptionText", "Z");
CHECK_NULL_THROW_ERROR(fid);
CHECK_NULL_RETURN(fid, ENH_INIT_ERROR);
enhancedExceptionsAllowed = (*env)->GetStaticBooleanField(env, cls, fid);
enhancedExceptionsInitialized = 1;
return enhancedExceptionsAllowed;

View File

@@ -183,6 +183,11 @@ int lookupCharacteristicsToAddressFamily(int characteristics);
int addressesInSystemOrder(int characteristics);
/* return codes */
#define ENH_INIT_ERROR -1 /* initialization error: check exceptions */
#define ENH_DISABLED 0 /* enhanced exceptions disabled */
#define ENH_ENABLED 1 /* enhanced exceptions enabled */
int getEnhancedExceptionsAllowed(JNIEnv *env);
#endif /* NET_UTILS_H */

View File

@@ -188,8 +188,11 @@ void NET_ThrowUnknownHostExceptionWithGaiError(JNIEnv *env,
if (error_string == NULL)
error_string = "unknown error";
int enhancedExceptions = getEnhancedExceptionsAllowed(env);
if (enhancedExceptions == ENH_INIT_ERROR && (*env)->ExceptionCheck(env)) {
return;
}
if (enhancedExceptions) {
if (enhancedExceptions == ENH_ENABLED) {
size = strlen(hostname);
} else {
size = 0;
@@ -200,7 +203,7 @@ void NET_ThrowUnknownHostExceptionWithGaiError(JNIEnv *env,
if (buf) {
jstring s;
int n;
if (enhancedExceptions) {
if (enhancedExceptions == ENH_ENABLED) {
n = snprintf(buf, size, "%s: %s", hostname, error_string);
} else {
n = snprintf(buf, size, " %s", error_string);

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